> ## Documentation Index
> Fetch the complete documentation index at: https://developer.comstruct.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload delivery PDF

> **Erforderliche Berechtigungen:** `deliveries:patch`

Öffentlicher API-Einstieg für den asynchronen Lieferschein-PDF-Upload (Stapel-/Heftscan).
Erfordert das Feature-Flag `delivery-async-processing` und einen kundengebundenen API-Schlüssel
(`CUSTOMER_ONLY`) mit Scope `deliveries:patch`. Lieferanten-API-Schlüssel werden abgelehnt.

Senden Sie das rohe PDF als Request-Body (`Content-Type: application/pdf`).
Der Header `Content-Length` ist Pflicht. Metadaten werden als Query-Parameter übergeben.
Das PDF wird gestreamt in den Speicher geschrieben und in die Queue `delivery-segmentation`
eingereiht. Nach der Segmentierung wird pro erkannter Lieferschein-Seite eine Lieferung
im Status `PROCESSING` angelegt und die Extraktion über `delivery-processing` gestartet.

Die Antwort enthält sofort `fileId` und `jobId` — die Lieferzeilen erscheinen erst nach
Abschluss der Segmentierung. Abfragen Sie anschließend `GET /deliveries`.

Maximale PDF-Größe: 16 MiB.


## Overview

Uploads a delivery-note PDF and starts asynchronous segmentation and extraction (staple-scan). Suitable for single delivery notes as well as PDF bundles that contain multiple delivery notes and optional order sheets.

The PDF is streamed to storage and enqueued on the segmentation queue. After segmentation, one delivery in status `PROCESSING` is created per detected delivery note; extraction then runs asynchronously. The response returns `fileId` and `jobId` immediately — delivery rows appear only after segmentation completes.

<Info>
  This endpoint requires the `delivery-async-processing` feature flag. Without it, the API responds with `403`.
</Info>

## Permissions

| Scope              | Tenant type                     |
| ------------------ | ------------------------------- |
| `deliveries:patch` | Customer only (`CUSTOMER_ONLY`) |

The API key must be linked to a customer. Supplier API keys are rejected.

## Headers

| Header           | Required | Description                                |
| ---------------- | -------- | ------------------------------------------ |
| `x-api-key`      | Yes      | API key with scope `deliveries:patch`      |
| `Content-Type`   | Yes      | Must be `application/pdf`                  |
| `Content-Length` | Yes      | Size of the PDF body in bytes (max 16 MiB) |

## Query parameters

| Parameter    | Required    | Description                                                                                                       |
| ------------ | ----------- | ----------------------------------------------------------------------------------------------------------------- |
| `projectId`  | Conditional | Project UUID. Required unless the API key is project-scoped (then that project is used) or the caller is an admin |
| `supplierId` | No          | Supplier UUID if known at upload time                                                                             |
| `sourceType` | No          | Intake source for the delivery. Default: `COMSTRUCT_API`                                                          |

## Behavior

* The request body is the **raw PDF** (not multipart, not Base64).
* Metadata is passed only via query parameters.
* For project-scoped API keys, `projectId` may be omitted — the key's project is used.
* After a successful upload: segmentation → fan-out → extraction. Poll `GET /deliveries` for the resulting rows.
* `fileId` is the uploaded bundle document id, **not** a delivery id.

## Example

```bash theme={null}
curl -X POST "https://api.comstruct.com/v1/deliveries/pdf?projectId=PROJECT_UUID" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/pdf" \
  --data-binary @delivery-note.pdf
```

### Successful response

```json theme={null}
{
  "fileId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "jobId": "42",
  "success": true
}
```

## Response codes

| Code  | Description                                                            |
| ----- | ---------------------------------------------------------------------- |
| `200` | PDF uploaded and segmentation queued                                   |
| `400` | Invalid PDF, missing `Content-Length`, or missing `projectId`          |
| `401` | Unauthorized — missing or invalid API key                              |
| `403` | Forbidden — missing scope, wrong tenant type, or feature flag disabled |
| `413` | PDF exceeds 16 MiB                                                     |
| `500` | Internal error while storing or enqueueing                             |


## OpenAPI

````yaml POST /deliveries/pdf
openapi: 3.0.3
info:
  title: comstruct Public API
  description: >
    Die comstruct API ist eine umfassende und flexible Lösung zur Optimierung
    des Materialbeschaffungsprozesses für Unternehmen. Diese API bietet eine
    einfache Schnittstelle für Entwickler, um auf Materialbeschaffungsdaten
    zuzugreifen und diese zu verwalten, einschließlich Lieferanteninformationen,
    Lieferungen und Projekte.


    ## Erste Schritte

    Um Zugang zur comstruct API zu erhalten, wenden Sie sich bitte an Ihren
    zuständigen Customer Success Manager. Unser Expertenteam steht Ihnen mit
    erstklassigem Support zur Verfügung, um Ihnen zu helfen, das Beste aus
    unserer API herauszuholen.


    ## Authentifizierung

    Alle API-Endpunkte unter `/v1` erfordern eine Authentifizierung mittels
    API-Schlüssel im `x-api-key`-Header. Jeder API-Schlüssel hat spezifische
    Berechtigungen (Scopes), die bestimmen, welche Endpunkte und Operationen
    verfügbar sind. Die Authentifizierung wird durch Middleware durchgesetzt,
    die den API-Schlüssel und die Berechtigungen für jede Anfrage validiert.


    Kalender-Endpunkte unter `/calendars` und IDS-Endpunkte unter `/ids` liegen
    **ohne** `/v1`-Präfix (Basis-URL `https://api.comstruct.com`). Kalender
    verwenden Token-basierte Authentifizierung; IDS ist ein öffentlicher
    Callback ohne API-Schlüssel.


    ## Datenformate

    - Alle Zeitstempel sind im ISO 8601-Format (UTC)

    - Geldbeträge werden als Dezimalzahlen dargestellt

    - IDs sind UUIDs, sofern nicht anders angegeben


    ## Anfragegrößenbeschränkungen

    - PDF-Rechnungsverarbeitung, benutzerdefinierte Rechnungsverarbeitung und
    Workflow-Verarbeitung: 32MiB

    - Asynchroner Lieferschein-PDF-Upload (`POST /deliveries/pdf`): 16MiB

    - Alle anderen Endpunkte: 10MiB


    ## Fehlerbehandlung

    Die API verwendet Standard-HTTP-Statuscodes und gibt detaillierte
    Fehlermeldungen im JSON-Format zurück. Weitere Details finden Sie in den
    Fehlerschemas.


    ## Integrationsmuster

    - **SAP-Integration**: Spezialisierte Endpunkte für SAP-ERP-Systeme

    - **Projektverwaltung**: Vollständiges Projektlebenszyklusmanagement mit
    Benutzerrollen

    - **Lieferverfolgung**: Unterstützung mehrerer Lieferscheinformate
    (OpenTrans, PAHM, Q-Point, benutzerdefiniert)

    - **Rechnungsverarbeitung**: Automatisierte Rechnungsanalyse und
    -validierung mit KI/GPT-Unterstützung

    - **Auftragsverwaltung**: IDS-Auftragsverarbeitung mit XML-Parsing und
    Projektkalenderintegration

    - **Kalenderintegration**: Separate Kalender-Endpunkte für
    iCalendar-Abonnement-Feeds
  version: 1.0.10
  license:
    name: Proprietary
    url: https://comstruct.com
  contact:
    name: comstruct ICT GmbH
    url: https://comstruct.com
    email: support@comstruct.com
  termsOfService: https://comstruct.com/datenschutzerklarung/
  x-logo:
    url: https://app.comstruct.com/logo-light-text.png
    altText: comstruct logo
servers:
  - url: https://api.comstruct.com/v1
    description: Haupt-API-Endpunkte (erfordert API-Schlüssel-Authentifizierung)
    variables: {}
  - url: https://api.comstruct.com
    description: Basisserver für Kalender- und IDS-Endpunkte (andere Authentifizierung)
    variables: {}
security:
  - ApiKey: []
tags:
  - name: Projects
    description: Endpunkte für Projekte.
  - name: Projects (SAP)
    description: SAP-spezifische Projekt-Endpunkte.
  - name: Project Regions
    description: Endpunkte für die Verwaltung von Projektregionen.
  - name: Deliveries
    description: Endpunkte für Lieferungen.
  - name: Deliveries (Supplier)
    description: Lieferantenspezifische Liefer-Endpunkte.
  - name: Accounts
    description: Endpunkte für die Verwaltung von Sachkonten.
  - name: Payment Terms
    description: Endpunkte für die Verwaltung von Zahlungsbedingungen.
  - name: Tax Codes
    description: Endpunkte für die Verwaltung von Steuercodes.
  - name: Company Codes
    description: Endpunkte für die Verwaltung von Buchungskreisen (juristische Einheiten).
  - name: Suppliers
    description: Endpunkte für die Verwaltung von Lieferanten.
  - name: Purchase Orders
    description: Endpunkte für Bestellungen.
  - name: Purchase Orders (SAP)
    description: SAP-spezifische Bestellungs-Endpunkte.
  - name: Orders (Supplier)
    description: >-
      Lieferantenspezifische Bestellungs-Endpunkte (Bestätigung, Ablehnung,
      Bearbeitung).
  - name: Suppliers (SAP)
    description: SAP-spezifische Lieferanten-Endpunkte.
  - name: Invoices
    description: Endpunkte für Rechnungen.
  - name: Invoices (Supplier)
    description: Lieferantenspezifische Rechnungs-Endpunkte.
  - name: Invoices (SAP)
    description: SAP-spezifische Rechnungs-Endpunkte.
  - name: Invoice Dimensions
    description: >
      Rechnungs-Dimensionen (benutzerdefinierte Eigenschaften) und Zuweisungen
      auf Rechnung (`header`), Position (`line_item`) oder Kontierung
      (`account`).


      Dimensionen haben den Typ `option` (vordefinierte Werte) oder `text`
      (Freitext über `dimension_id` + `text_value`). Bulk-Konto-POST
      (`/assignments/account/bulk`) unterstützt nur Options-Zuweisungen über
      `option_ids`; Freitext auf Kontoebene über Einzel-POST, PATCH-Bulk oder
      Positions-Bulk.
  - name: Workflows
    description: Endpunkte für Workflow- und Prozessmanagement.
  - name: Calendar
    description: Kalender-Abonnement-Endpunkte mit separater Authentifizierung.
  - name: Orders
    description: Endpunkte für Auftragsverarbeitung und -verwaltung.
paths:
  /deliveries/pdf:
    post:
      tags:
        - Deliveries
      summary: Lieferschein-PDF hochladen (asynchrone Segmentierung)
      description: >
        **Erforderliche Berechtigungen:** `deliveries:patch`


        Öffentlicher API-Einstieg für den asynchronen Lieferschein-PDF-Upload
        (Stapel-/Heftscan).

        Erfordert das Feature-Flag `delivery-async-processing` und einen
        kundengebundenen API-Schlüssel

        (`CUSTOMER_ONLY`) mit Scope `deliveries:patch`.
        Lieferanten-API-Schlüssel werden abgelehnt.


        Senden Sie das rohe PDF als Request-Body (`Content-Type:
        application/pdf`).

        Der Header `Content-Length` ist Pflicht. Metadaten werden als
        Query-Parameter übergeben.

        Das PDF wird gestreamt in den Speicher geschrieben und in die Queue
        `delivery-segmentation`

        eingereiht. Nach der Segmentierung wird pro erkannter Lieferschein-Seite
        eine Lieferung

        im Status `PROCESSING` angelegt und die Extraktion über
        `delivery-processing` gestartet.


        Die Antwort enthält sofort `fileId` und `jobId` — die Lieferzeilen
        erscheinen erst nach

        Abschluss der Segmentierung. Abfragen Sie anschließend `GET
        /deliveries`.


        Maximale PDF-Größe: 16 MiB.
      operationId: uploadDeliveryPdf
      parameters:
        - name: projectId
          in: query
          required: false
          schema:
            type: string
            format: uuid
          description: >
            Projekt-UUID. Pflicht, sofern der API-Schlüssel nicht
            projektgebunden ist

            (dann wird das Projekt des Schlüssels verwendet) oder der Aufrufer
            kein Admin ist.
        - name: supplierId
          in: query
          required: false
          schema:
            type: string
            format: uuid
          description: Optionale Lieferanten-UUID, falls zum Upload-Zeitpunkt bekannt
        - name: sourceType
          in: query
          required: false
          schema:
            type: string
            enum:
              - WEB_APP_IMPORT
              - MAIL
              - GENERAL_MAIL
              - COMSTRUCT_API
              - EXTERNAL_API
              - PORTAL
              - APP_SCAN
            default: COMSTRUCT_API
          description: >
            Quelle der Lieferung. Standard für öffentliche API-Uploads:
            `COMSTRUCT_API`.
      requestBody:
        required: true
        description: Rohes PDF (binär)
        content:
          application/pdf:
            schema:
              type: string
              format: binary
      responses:
        '200':
          description: PDF hochgeladen und Segmentierung eingereiht
          content:
            application/json:
              schema:
                type: object
                required:
                  - fileId
                  - success
                properties:
                  fileId:
                    type: string
                    format: uuid
                    description: >-
                      ID des hochgeladenen Bundle-Dokuments (keine
                      Lieferungs-ID)
                    example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  jobId:
                    type: string
                    description: ID des Segmentierungs-Jobs in der Queue
                    example: '42'
                  success:
                    type: boolean
                    example: true
        '400':
          description: Ungültiges PDF, fehlender Content-Length oder fehlende projectId
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Nicht autorisiert — fehlender oder ungültiger API-Schlüssel
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >
            Keine Berechtigung — fehlender Scope `deliveries:patch`, falscher
            Tenant-Typ

            (nicht kundengebunden) oder Feature-Flag `delivery-async-processing`
            deaktiviert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Payload zu groß — PDF überschreitet 16 MiB
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Interner Serverfehler beim Speichern oder Einreihen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - ApiKey:
            - deliveries:patch
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Fehlermeldung, die beschreibt, was schiefgelaufen ist
        message:
          type: string
          description: Zusätzliche Fehlerdetails oder benutzerfreundliche Nachricht
        success:
          type: boolean
          description: Zeigt Fehlschlag an, wenn in Fehlerantworten vorhanden
      anyOf:
        - required:
            - error
        - required:
            - message
        - required:
            - success
      example:
        error: Validation failed
        message: The provided data did not pass validation checks
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: >
        API-Schlüssel zur Authentifizierung. Kontaktieren Sie Ihren Customer
        Success Manager, um einen API-Schlüssel zu erhalten.


        Jeder Endpunkt erfordert spezifische Berechtigungen (Scopes); die
        erforderlichen Scopes werden pro Endpunkt angezeigt.

````