Ü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/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,
gleiches idempotentes Upsert, 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. Envelope) ist asynchron.Ablauf
-
Stapel senden —
POSTmit einem Array von Zeilen oder einem Envelope-Objekt:Bei Erfolg:202mit{ "jobId": "…", "status": "queued", "statusUrl": "/api/import-jobs/…" }(auch alsLocation-Header). Zu diesem Zeitpunkt ist noch nichts importiert. Die Zeilen-Validierung läuft synchron — ein fehlerhafter Payload wird sofort mit400abgelehnt, ohne dass ein Job entsteht. -
Status abfragen —
GET /api/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). Fehlgeschlagene Zeilen tragen stabile, nicht lokalisierte Fehlerschlüssel.
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 Request-Body (Plattform-Limit, greift vor unserer Anwendung).
- Ein leeres Array oder ein fehlerhaftes Envelope →
400.
Teil-Akzeptanz und Idempotenz
- Gültige Zeilen werden übernommen, auch wenn andere Zeilen in
failedlanden. - Ein identischer Import lässt sich gefahrlos wiederholen: bereits vorhandene Zeilen kommen als übersprungen/aktualisiert zurück, es entstehen keine Duplikate.
Bestellungen: replaceLines und die Vollständigkeitsregel
Der Import einer Bestellung ersetzt deren komplette Positionsliste. Eine Anfrage,
die Bestellung O enthält, muss deshalb alle Positionen von O enthalten. Werden
die Positionen einer Bestellung über mehrere Anfragen verteilt, würde die zweite Anfrage
die zuvor importierten Positionen löschen.
Die Positions-Schutzsperre macht daraus einen lauten Fehler statt eines stillen Datenverlusts:
-
Standard (
replaceLinesfehlt oderfalse): Würde der Stapel gespeicherte Positionen löschen, schlägt der gesamte Job vor dem ersten Schreibvorgang fehl. Imerror-Feld des Jobs steht:Senden Sie die betroffenen Bestellungen mit ihrer vollständigen Positionsliste erneut. -
"replaceLines": trueautorisiert das Ersetzen: Die gesendete Positionsliste wird maßgeblich, auch wenn dabei Positionen entfallen.
Fehlerschlüssel (stabil, nicht lokalisiert)
Aufbewahrung
Das Job-Ergebnis bleibt abfragbar; der gestagte Eingabe-Payload wird ~24 Stunden nach Abschluss freigegeben, 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 den Write-Scope der Entität (articles:write, suppliers:write,
orders:write), das Abfragen des Jobs den jeweiligen Read-Scope (im Write-Scope enthalten).
Jobs sind strikt mandantengebunden: eine unbekannte jobId und die jobId eines anderen
Unternehmens liefern dieselbe 404.