Übersicht
Stapelimporte laufen asynchron: DerPOST legt einen Import-Job an und antwortet
sofort mit 202 und einer jobId. Ihr System fragt anschließend den Job-Status ab
(GET /api/v1/import-jobs/{jobId}), bis der Import abgeschlossen ist, und erhält dort das
vollständige Ergebnis — inklusive der Gründe für übersprungene oder fehlgeschlagene Zeilen.
Der Import nutzt dieselbe Engine wie der CSV-Import in der App: gleiche Validierung,
gleicher idempotenter Abgleich, gleiches Ergebnisformat.
Ein
POST mit einem einzelnen Objekt (ohne rows-Array) bleibt synchron und
antwortet unverändert mit 201. Nur die Stapel-Form (Array bzw. Objekt mit rows) ist asynchron.Dieser Ablauf gilt für die Endpunkte mit 5.000-Zeilen-Limit — die drei oben und
POST /api/v1/ppwr/quantities. Die PPWR-Stammdaten-Endpunkte und POST /api/v1/ppwr/tonnage
(1.000-Zeilen-Limit; darüber 400, nicht 413) sind synchron: 200 mit dem Ergebnis im
Body, es entsteht kein Job. Siehe PPWR.Ablauf
-
Stapel senden —
POSTmit einem Array von Zeilen oder einem Objekt mitrows:Bei Erfolg:202mit{ "jobId": "…", "status": "queued", "statusUrl": "/api/import-jobs/…" }(auch alsLocation-Header;statusUrlist host-relativ — nur an den Ursprung anhängen). Zu diesem Zeitpunkt ist noch nichts importiert. Die Zeilen-Validierung läuft synchron — ein fehlerhafter Stapel wird sofort mit400abgelehnt, ohne dass ein Job entsteht. Das erste Element vonpathin jedem Eintrag vondetailsist der 0-basierte Index der fehlerhaften Zeile inrows, z. B.[17, "quantity"]. Eine fehlerhafte Zeile lehnt die ganze Anfrage ab, nichts wird angelegt — diese Zeile korrigieren oder entfernen und den Stapel erneut senden. -
Status abfragen —
GET /api/v1/import-jobs/{jobId}etwa alle 2 Sekunden, bei großen Jobs mit steigendem Abstand (z. B. exponentiell bis ~30 s).completedundfailedsind final — danach nicht weiter abfragen. -
Ergebnis auswerten — bei
status: "completed"enthältresultdas zusammengeführte Import-Ergebnis (imported,updated,failed,skipped, … je nach Entität). Jeder Eintrag infailednennt seinen Datensatz (orderNumber,internalArticleNrbzw.name) und trägterror.key— einen stabilen, nicht lokalisierten Schlüssel — und manchmalerror.params. Einfailed-Job trägt seinen Grund stattdessen inerror(siehe Tabelle unten).
Limits
- Maximal 5.000 Zeilen pro Anfrage. Darüber:
413 { "error": "batchTooLarge", "maxBatchSize": 5000 }— es wird nichts angelegt. Größere Abgleiche auf mehrere Anfragen aufteilen. - ~4,5 MB pro Anfrage (Plattform-Limit, greift vor unserer Anwendung).
- Für einen großen Erstimport Stapel mit etwa 100 bis 500 Bestellungen (jeweils mit allen
Zeilen, bis zum 5.000-Zeilen-Limit) senden statt einer Anfrage je Bestellung: Jede Anfrage wird
ein Job, die Jobs eines Unternehmens laufen nur zu wenigen gleichzeitig, und weniger Jobs heißt
weniger
jobIds zum Abfragen. - Ein leeres Array oder ein fehlerhaftes Objekt mit
rows→400.
Teil-Akzeptanz und Idempotenz
- Gültige Zeilen werden übernommen, auch wenn andere Zeilen in
failedlanden. - Ein Job schreibt in Abschnitten. Bricht er unterwegs ab (
workerError, oderlineReplacementRequirednach einer gleichzeitigen Änderung), können frühere Abschnitte schon geschrieben sein. Den Stapel erneut zu senden ist gefahrlos. - Ein identischer Import lässt sich gefahrlos wiederholen: bereits vorhandene Zeilen kommen als übersprungen/aktualisiert zurück, es entstehen keine Duplikate.
- Artikelfelder in Bestellzeilen (
hsCode,articleDescription) wirken nur beim Anlegen — siehe Bestellungen.
Fehlerschlüssel (stabil, nicht lokalisiert)
Daserror eines fehlgeschlagenen Jobs ist ein Text: entweder ein reiner Schlüssel oder JSON,
dessen key der stabile Teil ist. Zeilen- und Bestellschlüssel stehen im Ergebnis eines
abgeschlossenen Jobs als failed[].error.key.
Die bestellspezifischen Schlüssel (
lineReplacementRequired, positionIdMixed,
duplicatePositionId, conflictingHsCodeForArticle, conflictingDuplicateOrderRows) erklärt
Bestellungen. Ein Bestellschlüssel lässt die ganze Bestellung
fehlschlagen; nichts davon wird geschrieben.
Aufbewahrung
Das Job-Ergebnis bleibt abfragbar; die übermittelten Eingabedaten werden ~24 Stunden nach Abschluss gelöscht, der Job-Datensatz ~30 Tage nach Erstellung gelöscht. Fragen Sie das Ergebnis innerhalb dieses Fensters ab und persistieren Sie es auf Ihrer Seite.Berechtigungen
DerPOST erfordert die Schreibberechtigung der Entität (articles:write, suppliers:write,
orders:write), das Abfragen des Jobs die jeweilige Leseberechtigung (in der
Schreibberechtigung enthalten).
Jobs sind strikt mandantengebunden: eine unbekannte jobId und die jobId eines anderen
Unternehmens liefern dieselbe 404.