# Beleg hochladen (https://developer.bimetrics.de/referenz/belege/upload-document)

`POST https://app.bimetrics.de/api/document/`

operationId: `uploadDocument` · Berechtigung (Scope): `upload` · Bereich: Belege

Lädt genau eine Datei als neuen Beleg hoch und stößt die Erkennung an. Die Antwort ist ein Array mit genau einem Beleg. Das Formularfeld bestimmt die Belegart: `invoice[]` Ausgangsrechnung, `receipt[]` Eingangsbeleg, `auto[]` Erkennung durch bimetrics. Unterstützt werden PDF, PNG, JPEG und XML-E-Rechnungen. `X-Upload-Request-Id` macht Wiederholungen sicher: Dieselbe ID mit identischer Datei, identischem Dateinamen und Feld liefert denselben Beleg, ohne weiteres Kontingent; dieselbe ID mit anderem Inhalt ergibt `409 UploadRequestConflict`. Für jeden neuen Beleg eine neue ID verwenden. Ist das Belegkontingent ausgeschöpft, wird der Beleg trotzdem gespeichert (`uploadDocument.ocrStatus` = `quota_paused`); dann keinen weiteren Upload mit neuer ID starten.

Benötigt einen Schlüssel mit der Berechtigung `upload`.

> **Achtung:** Erzeugt einen echten Beleg, verbraucht Kontingent und wird GoBD-protokolliert.
>
> KI-Agenten fragen vor diesem Aufruf beim Nutzer nach.

### Authentifizierung

`Authorization: Bearer bm_…` (alternativ `X-API-KEY: bm_…`, nie beide zugleich).

### Parameter

| Name | Ort | Pflicht | Typ | Beschreibung |
| --- | --- | --- | --- | --- |
| `X-Upload-Request-Id` | header | ja | string | Idempotenzschlüssel des Uploads: 1–128 druckbare ASCII-Zeichen ohne Leerzeichen. Für jeden neuen Beleg eine neue ID, bei Wiederholungen dieselbe. |

### Request-Body (`multipart/form-data`)

| Feld | Typ | Beschreibung |
| --- | --- | --- |
| `auto[]` | string (binary) | Belegart erkennt bimetrics. |
| `invoice[]` | string (binary) | Ausgangsrechnung. |
| `receipt[]` | string (binary) | Eingangsbeleg. |

### Beispiel

```sh
curl --fail-with-body -X POST "https://app.bimetrics.de/api/document/" \
  -H "Authorization: Bearer $BIMETRICS_API_KEY" \
  -H "X-Upload-Request-Id: rechnung-2026-0001" \
  -F "auto[]=@rechnung.pdf"
```

### Antworten

| Status | Beschreibung | Inhalt |
| --- | --- | --- |
| 200 | Der angelegte oder bei Wiederholung derselbe Beleg, als Array mit genau einem Eintrag. | `application/json`: Array<UploadResult> |
| 400 | Ungültige Anfrage, z. B. ein ungültiger Filter (unbekannte Art `kind`, unbekanntes Attribut, `sort` nach einem Attribut mit `sortable: false`, `limit` < 0, `offset` > 1.000.000), eine ID, die keine UUID ist, oder ein Upload ohne gültige `X-Upload-Request-Id`, mit mehr als einer Datei oder einer Datei über 30 MiB. Code meist `BadRequest`. Anfrage korrigieren, nicht wiederholen. | `application/json`: Error |
| 401 | Kein gültiger Schlüssel: fehlt (`Unauthorized`), ist unbekannt, abgelaufen oder widerrufen oder wurde nicht in genau einem Header gesendet (`InvalidAPIKey`). Schlüssel prüfen, nicht wiederholen. Auch eine ID, die zu einer anderen Firma gehört, ergibt `401 Unauthorized`. | `application/json`: Error |
| 402 | Das Abo der Firma erlaubt die Anfrage nicht (`SubscriptionRequired`, `PlanRequired`, `LimitReached`); `context` nennt Einzelheiten. | `application/json`: Error |
| 403 | Dem Schlüssel fehlt die Berechtigung für diese Route (`APIKeyPermissionDenied`), oder der Tarif der Firma enthält die API nicht (`APIUnavailable`). | `application/json`: Error |
| 409 | Die `X-Upload-Request-Id` gehört schon zu einem Upload mit anderer Datei, anderem Dateinamen oder anderem Feld (`UploadRequestConflict`). Kein vorübergehender Fehler: nicht mit derselben ID wiederholen. | `application/json`: Error |
| 413 | Die Anfrage ist zu groß (`APIRequestTooLarge`), siehe `x-bimetrics-limits`. | `application/json`: Error |
| 429 | Zu viele Anfragen (`APIRateLimit`). Nach `Retry-After` Sekunden wiederholen; einen Upload mit derselben `X-Upload-Request-Id`. (Header: Retry-After) | `application/json`: Error |
| 500 | Serverfehler (`Internal`; `APIUnavailable`, wenn der Schlüssel gerade nicht geprüft werden kann). Später wiederholen, einen Upload mit derselben `X-Upload-Request-Id`. | `application/json`: Error |

#### Felder der Antwort 200

Array aus `UploadResult`.

| Feld | Typ | Beschreibung |
| --- | --- | --- |
| `bookings` | Array<AccountBooking>, kann null sein | Buchungen des Belegs. |
| `cashDiscount` | CashDiscountSnapshot | Skonto der Zuordnung; fehlt ohne Skonto. |
| `companyId` | string (uuid) |  |
| `contentSource` | string | Herkunft der Belegdaten: `auto` erkannt, `manual` erfasst, `collection` aus Vertrag oder Serie. |
| `createdAt` | string (date-time) | Anlage in bimetrics. |
| `deliveryDate` | NaiveDate | Liefer- bzw. Leistungsdatum. |
| `documentContract` | DocumentContract | Der Vertrag, falls der Beleg zu einem gehört. |
| `documentContractId` | string (uuid), kann null sein | ID des Vertrags, falls der Beleg zu einem gehört. |
| `documentSeries` | DocumentSeries | Die Belegserie, falls der Beleg zu einer gehört. |
| `documentSeriesId` | string (uuid), kann null sein | ID der Belegserie, falls der Beleg zu einer gehört. |
| `dueDate` | NaiveDate | Fälligkeitsdatum. |
| `duplicate` | boolean | Die Datei lag in der Firma schon als Beleg vor. Fehlt sonst. |
| `id` | string (uuid) | ID des Belegs. |
| `importOrigin` | string, kann null sein | Eingangsweg: `upload`, `email`, `generated` (in bimetrics erstellt) oder `collection`. |
| `invoiceDate` | NaiveDate | Rechnungsdatum. |
| `invoiceNumber` | string | Rechnungsnummer. |
| `invoicePositions` | Array<DocumentInvoicePosition>, kann null sein | Positionen; `null`, solange nichts erkannt ist. |
| `issuer` | DocumentIssuer | Aussteller. |
| `kind` | string: `invoice`, `receipt` | Belegart: `invoice` Ausgangsrechnung, `receipt` Eingangsbeleg. |
| `match` | Match | Zuordnung zu Umsätzen und anderen Belegen; `null` ohne Zuordnung. |
| `paymentTerms` | string | Zahlungsbedingungen als Text. |
| `performancePeriodFrom` | NaiveDate | Beginn des Leistungszeitraums. |
| `performancePeriodTo` | NaiveDate | Ende des Leistungszeitraums. |
| `recipient` | DocumentRecipient | Empfänger. |
| `updatedAt` | string (date-time) | Letzte Änderung. |
| `uploadDocument` | UploadDocument | Die hochgeladene Datei und der Stand ihrer Erkennung. |
| `uploadDocumentId` | string (uuid), kann null sein | ID der hochgeladenen Datei; `null` bei Belegen aus Verträgen oder Serien. |

Verschachtelte Schemas stehen vollständig in der OpenAPI-Beschreibung: https://app.bimetrics.de/api/openapi.json
