{"openapi":"3.0.0","info":{"title":"ATF-Liniensystem — Partner-Schnittstelle","description":"Die Schnittstelle für die Partner des ATF-Liniensystems: Sendungen anlegen,\nStatus und Label abrufen, Preise erfragen, Stammdaten und Routing nachschlagen.\n\n**Anmeldung:** jeder Aufruf braucht den Kopf `X-Api-Key` mit dem Schlüssel,\nden die ATF-Zentrale ausgegeben hat. Jeder Schlüssel gehört zu genau einem\nPartner; angelegte Sendungen werden diesem Partner zugeordnet.\n\nEine deutsche Einstiegsseite mit durchgespieltem Beispiel steht unter\n`\/api\/doku`.\n","contact":{"name":"ATF-Zentrale"},"version":"1.0"},"servers":[{"url":"https:\/\/api.nexcargo.at","description":"ATF-Liniensystem"}],"paths":{"\/api\/v1\/partner":{"get":{"tags":["Partner"],"summary":"Stationsverzeichnis: alle aktiven Partner","description":"Das Verzeichnis der Kooperation – Name, Anschrift, Lageranschrift samt Öffnungszeiten, Kürzel und Kontakt. Gedacht für Selbstabholung und Direktzustellung: Sie brauchen die Stationsdaten auch von Partnern, mit denen Sie noch keine gemeinsame Sendung hatten. **Preise, Mengen und Finanzdaten anderer Partner werden hier grundsätzlich nicht ausgegeben.** Enthalten sind auch Einrichtungen der ATF selbst (Hub, Nachtumschlag, Zentrale) – erkennbar am Feld \u0022typ\u0022.","operationId":"get_app_api_partner_liste","responses":{"200":{"description":"Alle aktiven Partner, nach Kürzel sortiert.","content":{"application\/json":{"schema":{"properties":{"partner":{"type":"array","items":{"$ref":"#\/components\/schemas\/PartnerOeffentlich"}}},"type":"object"}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/partner\/{kuerzel}":{"get":{"tags":["Partner"],"summary":"Ein einzelner Partner über sein Kürzel","description":"Das Kürzel steht auf jedem Label und in jeder Routing-Auskunft. **Es darf einen Schrägstrich enthalten** – die echten ATF-Stationscodes sehen aus wie \u0022CAM\/ANS\u0022, und der Schrägstrich wird hier ganz normal als Teil der Adresse übergeben (nicht kodiert).","operationId":"get_app_api_partner_einzeln","parameters":[{"name":"kuerzel","in":"path","description":"Das Stationskürzel, z. B. CAM\/ANS. Groß-\/Kleinschreibung spielt keine Rolle.","required":true,"schema":{"type":"string","pattern":".+"},"example":"CAM\/ANS"}],"responses":{"200":{"description":"Der Partner.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/PartnerOeffentlich"}}}},"404":{"description":"Zum Kürzel gibt es keinen aktiven Partner (PARTNER_NICHT_GEFUNDEN).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/preisauskunft":{"post":{"tags":["Preis"],"summary":"Was kostet diese Sendung?","description":"Rechnet nur – **es entsteht nichts**: keine Sendung, keine Nummer, kein Angebot, kein Eintrag im Verlauf. Wer zweimal fragt, hat nichts doppelt; einen Idempotency-Key braucht es hier deshalb nicht.\n\n**Derselbe Rumpf wie bei der Sendungsanlage.** Stellen Sie Ihre Sendung einmal zusammen, fragen Sie hier den Preis und schicken Sie für die Anlage genau denselben Inhalt an POST \/api\/v1\/sendungen.\n\n**Weniger Pflichtfelder als bei der Anlage:** Nur was den Preis bestimmt – beide Länder, beide Postleitzahlen und mindestens ein Packstück. Name, Straße und Ort ändern keinen Cent; sie zu verlangen hieße, einen Preis erst nennen zu können, wenn die Adresse vollständig durchgegeben wurde.\n\n**POST statt GET,** obwohl nichts verändert wird: Eine Sendung hat beliebig viele Packstücke mit je vier Zahlen und zwei Adressen. Das in eine Adresszeile zu pressen wäre eine eigene Kodierung – und Adresszeilen landen im Protokoll jedes Vermittlers, mitsamt der Empfängeranschrift.\n\nEigene, engere Bremse – sie wird je Schlüssel eingestellt – und ein kurzer Zwischenspeicher für gleiche Anfragen.","operationId":"post_app_api_preisauskunft","requestBody":{"description":"Wie bei der Sendungsanlage. Pflicht sind hier nur absenderLand, absenderPlz, empfaengerLand, empfaengerPlz und mindestens ein Packstück.","required":true,"content":{"application\/json":{"schema":{"required":["absenderLand","absenderPlz","empfaengerLand","empfaengerPlz","packstuecke"],"type":"object","allOf":[{"$ref":"#\/components\/schemas\/Sendungsfelder"},{"properties":{"packstuecke":{"type":"array","items":{"$ref":"#\/components\/schemas\/PackstueckEingabe"},"minItems":1},"produktCode":{"type":"string","example":"ND","nullable":true}},"type":"object"}]}}}},"responses":{"200":{"description":"Die Auskunft. **Auch dann 200, wenn es für die Strecke keinen Tarif gibt** – „kein Preis hinterlegt\u0022 ist eine gültige Antwort auf die Frage, was etwas kostet, und kein Fehler Ihrerseits.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Preisauskunft"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Preisauskunft\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Pflichtfeld fehlt oder ein Packstück ist unbrauchbar.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"429":{"description":"Eigene, engere Bremse für die Preisauskunft.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"500":{"description":"Die Rechnung selbst ist gescheitert (PREIS_NICHT_BERECHENBAR) – ein Loch in den Preisstammdaten, kein Fehler Ihres Aufrufs. Bitte bei der ATF melden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/routing":{"get":{"tags":["Stammdaten"],"summary":"Wer bedient diese Adresse?","description":"Land und PLZ hinein – heraus kommen Hub, Abholpartner mit Zulauflinie und Zustellpartner mit Ablauflinie. **Zwei Rollen, zwei Antworten:** Für dieselbe PLZ kann ein anderer Partner abholen als zustellt, die Gebiete werden je Richtung gepflegt. Das Feld \u0022bedient\u0022 sagt, ob überhaupt etwas gepflegt ist – so muss man leere Felder nicht deuten.","operationId":"get_app_api_routing","parameters":[{"name":"land","in":"query","description":"Zweistelliges Länderkürzel, z. B. DE oder AT. Pflicht – es gibt bewusst keine stille Annahme.","required":true,"schema":{"type":"string"},"example":"DE"},{"name":"plz","in":"query","description":"Postleitzahl der Adresse.","required":true,"schema":{"type":"string"},"example":"40210"}],"responses":{"200":{"description":"Die Auskunft. Auch dann 200, wenn nichts gepflegt ist – dann steht \u0022bedient\u0022 auf false.","content":{"application\/json":{"schema":{"properties":{"land":{"type":"string","example":"DE"},"plz":{"type":"string","example":"40210"},"hub":{"type":"object","nullable":true},"abholung":{"properties":{"partner":{"type":"object","nullable":true},"linie":{"type":"object","nullable":true}},"type":"object"},"zustellung":{"properties":{"partner":{"type":"object","nullable":true},"linie":{"type":"object","nullable":true}},"type":"object"},"bedient":{"type":"boolean"}},"type":"object"}}}},"422":{"description":"Land oder PLZ fehlt bzw. ist unbrauchbar (PARAMETER_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen\/{nummer}\/packstuecke\/{laufendeNummer}":{"delete":{"tags":["Sendung ändern"],"summary":"Ein Packstück aus der Sendung nehmen","description":"**Das Packstück wird nicht gelöscht, sondern markiert.** Es zählt danach nirgends mehr mit – nicht im Gewicht, nicht in der Anzahl, nicht im Preis –, steht in der Antwort aber weiter in \u0022packstuecke\u0022 mit `\u0022entfernt\u0022: true`.\n\n**Das gedruckte Etikett bleibt gültig.** Wird sein Barcode doch gescannt, kommt das Packstück automatisch und ohne Rückfrage zurück in die Sendung und in die Abrechnung, und der Preis wird neu berechnet. Das ist Absicht: Wenn das Etikett gescannt wird, fährt die Ware wirklich mit.\n\n**Das letzte Packstück lässt sich nicht entfernen** – eine Sendung ohne Packstück hätte kein Gewicht, keinen Preis und kein Etikett. Wer sie loswerden will, storniert sie.\n\nEin zweiter Aufruf auf dasselbe Packstück ist KEIN Fehler, sondern liefert 200 mit einem Hinweis – nach einem Netzabbruch soll niemand rätseln müssen, ob es geklappt hat.","operationId":"delete_app_api_packstueck_entfernen","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}},{"name":"laufendeNummer","in":"path","description":"Die laufende Nummer des Packstücks, beginnend bei 1.","required":true,"schema":{"type":"integer","pattern":"\\d+"},"example":2}],"responses":{"200":{"description":"Entfernt (oder war es bereits). Die Antwort enthält die Sendung, den neuen Preis und die Hinweise.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Aenderungsantwort"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Sendungen ändern und stornieren\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung oder Packstück nicht gefunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"409":{"description":"Zu spät – ein Scan hat das Entfernen gesperrt (AENDERUNG_ZU_SPAET).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Es ist das letzte Packstück der Sendung (LETZTES_PACKSTUECK). Der Text nennt die Adresse für das Storno.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}},"patch":{"tags":["Sendung ändern"],"summary":"Maße oder Gewicht eines Packstücks ändern","description":"Es genügt, die geänderten Angaben zu schicken – was fehlt, bleibt stehen. Braucht das Recht \u0022Sendungen ändern und stornieren\u0022.\n\n**Diese Aktion hat eine eigene zeitliche Grenze**, und zwar eine strengere als die übrigen: Ab der Abholung wiegt und misst die ATF selbst nach. Wer das Gewicht danach noch selbst korrigieren dürfte, könnte die Gewichtsdifferenz-Gebühr aushebeln.","operationId":"patch_app_api_packstueck_aendern","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}},{"name":"laufendeNummer","in":"path","description":"Die laufende Nummer des Packstücks, beginnend bei 1.","required":true,"schema":{"type":"integer","pattern":"\\d+"},"example":1}],"requestBody":{"description":"Mindestens eine der vier Angaben.","required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/PackstueckEingabe"}}}},"responses":{"200":{"description":"Geändert. Die Antwort enthält die Sendung, den neuen Preis und den Hinweis auf den Etiketten-Nachdruck.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Aenderungsantwort"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Sendungen ändern und stornieren\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung oder Packstück nicht gefunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"409":{"description":"Zu spät – ein Scan hat diese Änderung gesperrt (AENDERUNG_ZU_SPAET). Der Text nennt den Scan mit Zeitpunkt.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Keine oder unbrauchbare Zahlen, oder das Packstück ist aus der Sendung genommen.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen\/{nummer}\/packstuecke":{"post":{"tags":["Sendung ändern"],"summary":"Ein weiteres Packstück zur Sendung nehmen","description":"Das neue Packstück bekommt die **nächste freie** laufende Nummer. Bereits vergebene Nummern werden nie neu verteilt – auch die von entfernten Packstücken nicht –, damit alle gedruckten Etiketten gültig bleiben. Die aufgedruckte Zählung „1 von 3\u0022 stimmt danach nicht mehr; die Etiketten funktionieren trotzdem, und die Antwort weist auf den Nachdruck hin.","operationId":"post_app_api_packstueck_hinzufuegen","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}}],"requestBody":{"description":"Alle vier Angaben sind Pflicht.","required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/PackstueckEingabe"}}}},"responses":{"200":{"description":"Angelegt. Die Antwort enthält die Sendung mit dem neuen Packstück, den neuen Preis und dessen Etikett-Adresse.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Aenderungsantwort"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Sendungen ändern und stornieren\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung nicht gefunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"409":{"description":"Zu spät – ein Scan hat das Hinzufügen gesperrt (AENDERUNG_ZU_SPAET).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Eine der vier Angaben fehlt oder ist keine positive Zahl (PACKSTUECK_UNGUELTIG).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen\/{nummer}\/storno":{"post":{"tags":["Sendung ändern"],"summary":"Die ganze Sendung stornieren","description":"Storniert wird immer die **ganze** Sendung; einen Teil-Storno gibt es bewusst nicht. Wer ein einzelnes Packstück loswerden will, nimmt es aus der Sendung (DELETE auf das Packstück).\n\nEine stornierte Sendung fällt aus Tourenplanung und Abrechnung heraus, und es können keine Scans mehr darauf gesetzt werden. **Der Aufruf braucht keinen Rumpf.**\n\nNach der Zustellung ist das Stornieren immer gesperrt – eine erbrachte Leistung lässt sich nicht nachträglich wegdiskutieren. Ab welchem früheren Scan zusätzlich gesperrt wird, stellt die ATF-Zentrale ein; es gilt für alle Partner gleich.","operationId":"post_app_api_sendung_storno","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}}],"responses":{"200":{"description":"Storniert. Die Antwort enthält die Sendung mit Status \u0022storniert\u0022.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Aenderungsantwort"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Sendungen ändern und stornieren\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung nicht gefunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"409":{"description":"Zu spät – die Sendung ist zugestellt oder ein Scan hat das Stornieren gesperrt (AENDERUNG_ZU_SPAET).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Die Sendung ist bereits storniert (BEREITS_STORNIERT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen\/{nummer}":{"get":{"tags":["Sendung"],"summary":"Sendungsstatus mit allen Scans je Packstück","description":"Gesamtstatus **plus** eine Liste je Packstück mit dessen Scans. Der Gesamtstatus allein beantwortet „ist es angekommen?\u0022 bei drei Packstücken nicht ehrlich – eines kann noch im Hub liegen.\n\nAls {nummer} geht die **Sendungsnummer ODER eine Packstücknummer** (z. B. \u0022TST-100-0000123-2\u0022). Im Lager liegt oft nur ein Label vor, und dort unterscheidet niemand die beiden. Welcher Weg getroffen hat, sagt das Feld \u0022gefundenUeber\u0022. Groß-\/Kleinschreibung spielt keine Rolle.\n\nEine Sendung eines anderen Partners ergibt **404 und nicht 403** – sie soll aussehen wie eine, die es nicht gibt.","operationId":"get_app_api_sendung_status","parameters":[{"name":"nummer","in":"path","description":"Sendungsnummer oder Packstücknummer. Darf Schrägstriche enthalten (Nummernkreise wie \u0022CAM\/ANS-200-\u0022).","required":true,"schema":{"type":"string","pattern":".+"},"example":"TST-100-0000123"}],"responses":{"200":{"description":"Der Status. Je Packstück sind zusätzlich dessen Scans enthalten.","content":{"application\/json":{"schema":{"type":"object","allOf":[{"$ref":"#\/components\/schemas\/Sendung"},{"properties":{"gefundenUeber":{"description":"Welcher der beiden Suchwege getroffen hat.","type":"string","enum":["sendungsnummer","packstuecknummer"]},"gesuchtesPackstueck":{"description":"Bei der Suche über eine Packstücknummer: welches Packstück gemeint war.","type":"string","nullable":true}},"type":"object"}]}}}},"401":{"description":"Schlüssel fehlt, ist unbekannt oder gesperrt (SCHLUESSEL_UNGUELTIG).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Status und Label lesen\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Nicht gefunden – oder die Sendung gehört einem anderen Partner (SENDUNG_NICHT_GEFUNDEN).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"429":{"description":"Rate-Limit erreicht. Der Kopf \u0022Retry-After\u0022 nennt die Wartezeit in Sekunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}},"patch":{"tags":["Sendung ändern"],"summary":"Sendungsdaten ändern","description":"**PATCH und nicht PUT:** Es wird nur geändert, was im Rumpf steht. Wer die Empfängeranschrift korrigieren will, schickt die drei Felder – und leert damit nicht versehentlich alles andere.\n\nErlaubt sind alle Felder aus \u0022Sendungsfelder\u0022 sowie \u0022produktCode\u0022. Nach der Änderung werden Volumengewicht-Teiler, Hub-Routing und Linienzuteilung neu gesetzt, genau wie bei einer Änderung im Portal – und der Preis wird neu berechnet.\n\nEine Zieladresse, die niemand bedient, wird auch per Änderung abgelehnt (422). Fehlende Zollangaben lehnen NICHT ab; sie stehen als Hinweis in der Antwort.\n\nPackstücke werden hier NICHT geändert – dafür gibt es die drei Packstück-Adressen.","operationId":"patch_app_api_sendung_aendern","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}}],"requestBody":{"description":"Nur die zu ändernden Felder. Ein leerer Rumpf ergibt 422 – er wäre eine Änderung, die nichts ändert.","required":true,"content":{"application\/json":{"schema":{"type":"object","allOf":[{"$ref":"#\/components\/schemas\/Sendungsfelder"},{"properties":{"produktCode":{"description":"Sendungsart aus \/api\/v1\/produkte.","type":"string","example":"ND","nullable":true}},"type":"object"}]}}}},"responses":{"200":{"description":"Geändert. Die Antwort enthält die Sendung in ihrem neuen Stand, den neuen Preis und den Hinweis auf den Etiketten-Nachdruck.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Aenderungsantwort"}}}},"400":{"description":"Ungültiges JSON im Rumpf.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Sendungen ändern und stornieren\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung nicht gefunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"409":{"description":"Zu spät – ein Scan hat das Ändern gesperrt (AENDERUNG_ZU_SPAET).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Leerer Rumpf, unbrauchbarer Feldwert, unbekanntes Produkt oder eine Adresse, die nicht bedient wird.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen":{"post":{"tags":["Sendung"],"summary":"Eine Sendung anlegen","description":"Ein Aufruf legt **genau eine** Sendung an; eine Massenanlage gibt es bewusst nicht. Der Auftraggeber ergibt sich aus dem API-Schlüssel und wird nie aus dem Rumpf übernommen. Die Antwort enthält die **vollständige angelegte Sendung** – alle Felder so, wie sie gespeichert wurden, die Packstücknummern und die **Links** auf Label und Status. So lässt sich prüfen, was von den eigenen Angaben angekommen ist; bitte die Adressen von dort übernehmen, statt sie selbst zu bauen.\n\nFehlende Zollangaben verhindern die Anlage NICHT: Die Sendung entsteht, der Hinweis steht in \u0022hinweise\u0022, und die Papiere werden nachgereicht. Eine laufende Anbindung soll nicht an etwas scheitern, das gestern noch durchging.","operationId":"post_app_api_sendung_anlegen","parameters":[{"name":"Idempotency-Key","in":"header","description":"Freiwillig, aber dringend empfohlen. Geht die Antwort auf dem Rückweg verloren, schicken Sie denselben Aufruf mit DEMSELBEN Schlüssel erneut – Sie bekommen die alte Antwort samt derselben Sendungsnummer zurück (Kopf \u0022Idempotency-Replayed: true\u0022) und keine zweite Sendung. Derselbe Schlüssel mit anderem Inhalt ergibt 409. Höchstens 200 Zeichen, 24 Stunden gemerkt.","required":false,"schema":{"type":"string"},"example":"auftrag-4711"}],"requestBody":{"description":"Alle Felder aus \u0022Sendungsfelder\u0022, dazu die Packstücke und optional produktCode und kundennummer. Genau derselbe Rumpf funktioniert auch bei der Preisauskunft.","required":true,"content":{"application\/json":{"schema":{"required":["packstuecke"],"type":"object","allOf":[{"$ref":"#\/components\/schemas\/Sendungsfelder"},{"properties":{"packstuecke":{"type":"array","items":{"$ref":"#\/components\/schemas\/PackstueckEingabe"},"minItems":1},"produktCode":{"description":"Sendungsart aus \/api\/v1\/produkte. Fehlt sie, gilt die Standard-Sendungsart.","type":"string","example":"ND","nullable":true},"kundennummer":{"description":"Nur bei Partnern mit mehreren Nummernkreisen – wählt den passenden Kreis.","type":"string","nullable":true}},"type":"object"}]}}}},"responses":{"201":{"description":"Die Sendung ist angelegt.","content":{"application\/json":{"schema":{"type":"object","allOf":[{"$ref":"#\/components\/schemas\/Sendung"},{"properties":{"hinweise":{"description":"Nur vorhanden, wenn etwas nachzutragen ist – zurzeit fehlende Zollangaben.","type":"array","items":{"type":"string"},"nullable":true}},"type":"object"}]}}}},"400":{"description":"Ungültiges JSON oder zu langer Idempotency-Key.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"401":{"description":"Schlüssel fehlt, ist unbekannt oder gesperrt (SCHLUESSEL_UNGUELTIG).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Sendungen anlegen\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"409":{"description":"Idempotenz-Konflikt oder ein Aufruf mit demselben Schlüssel läuft noch.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"422":{"description":"Pflichtfeld fehlt, Feld hat das falsche Format, Packstück unbrauchbar, Produkt unbekannt oder die Sendungsart wird an der Zieladresse nicht angeboten.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"429":{"description":"Rate-Limit des Schlüssels oder der IP-Adresse erreicht. Der Kopf \u0022Retry-After\u0022 nennt die Wartezeit in Sekunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen\/{nummer}\/label\/{laufendeNummer}":{"get":{"tags":["Sendung"],"summary":"Label eines einzelnen Packstücks (Nachdruck)","description":"Für den Fall, dass im Lager ein Etikett abgerissen ist. Braucht das Recht \u0022Status und Label lesen\u0022. Die fertige Adresse steht in der Antwort der Sendungsanlage bei jedem Packstück unter \u0022label\u0022 – bitte von dort übernehmen, statt sie zusammenzubauen.","operationId":"get_app_api_sendung_label_packstueck","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}},{"name":"laufendeNummer","in":"path","description":"Die laufende Nummer des Packstücks, beginnend bei 1.","required":true,"schema":{"type":"integer","pattern":"\\d+"},"example":1}],"responses":{"200":{"description":"Das Label als PDF.","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"Dem Schlüssel fehlt das Recht \u0022Status und Label lesen\u0022 (RECHT_FEHLT).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung oder Packstück nicht gefunden – eine fremde Sendung sieht aus wie eine, die es nicht gibt.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/sendungen\/{nummer}\/label":{"get":{"tags":["Sendung"],"summary":"Alle Label der Sendung als ein PDF","description":"Ein Label je Packstück, alle in einem Dokument. Die Sendungsanlage liefert bewusst diesen LINK und nicht das PDF selbst – ein Base64-Klotz in der JSON-Antwort müsste auch der mitschleppen, der die Etiketten gar nicht selbst druckt. **Der Link trägt kein Geheimnis in sich:** Er verlangt denselben X-Api-Key wie jeder andere Aufruf, denn auf dem Label stehen Empfängername, Anschrift und Route.","operationId":"get_app_api_sendung_label","parameters":[{"name":"nummer","in":"path","description":"Sendungs- oder Packstücknummer. Darf Schrägstriche enthalten.","required":true,"schema":{"type":"string","pattern":".+"}}],"responses":{"200":{"description":"Die Label als PDF.","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel – das Label ist nicht öffentlich.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"404":{"description":"Sendung nicht gefunden oder ohne Packstück.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"429":{"description":"Eigene, engere Bremse für den Label-Abruf – sie wird je Schlüssel eingestellt. Der Kopf \u0022Retry-After\u0022 nennt die Wartezeit in Sekunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/produkte":{"get":{"tags":["Stammdaten"],"summary":"Buchbare Sendungsarten","description":"Liefert alle aktiven Sendungsarten mit ihrem Code. Genau diese Codes werden im Feld \u0022produktCode\u0022 der Sendungsanlage akzeptiert. Ein abgeschaltetes Produkt steht nicht in der Liste – es wäre ein Angebot, das nicht gilt.","operationId":"get_app_api_produkte","responses":{"200":{"description":"Die aktiven Sendungsarten, sortiert wie im Portal.","content":{"application\/json":{"schema":{"properties":{"produkte":{"type":"array","items":{"properties":{"code":{"type":"string","example":"ND"},"bezeichnung":{"type":"string","example":"Next Day"},"zeitfensterVon":{"type":"string","example":"09:00","nullable":true},"zeitfensterBis":{"type":"string","example":"17:00","nullable":true},"beschreibung":{"type":"string","nullable":true}},"type":"object"}}},"type":"object"}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}},"429":{"description":"Zu viele Anfragen – der Kopf \u0022Retry-After\u0022 nennt die Wartezeit in Sekunden.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}},"\/api\/v1\/laender":{"get":{"tags":["Stammdaten"],"summary":"Länder mit Abweichung vom Normalfall","description":"ACHTUNG, das ist KEINE Länderliste: Aufgeführt sind nur die Länder, für die etwas vom Normalfall abweicht – ein anderer Volumengewicht-Teiler oder Zollpflicht. Ein Land ohne Eintrag ist der Regelfall, kein Fehler. Was der Regelfall ist, steht als \u0022standard\u0022 in der Antwort.","operationId":"get_app_api_laender","responses":{"200":{"description":"Der Normalfall und die Abweichungen.","content":{"application\/json":{"schema":{"properties":{"standard":{"properties":{"volumengewichtTeiler":{"type":"integer","example":6000},"zollpflichtig":{"type":"boolean","example":false}},"type":"object"},"hinweis":{"type":"string"},"laender":{"type":"array","items":{"properties":{"land":{"type":"string","example":"IT"},"volumengewichtTeiler":{"type":"integer","example":5000},"zollpflichtig":{"type":"boolean","example":false}},"type":"object"}}},"type":"object"}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Fehler"}}}}}}}},"components":{"schemas":{"Fehler":{"title":"Fehlerantwort","description":"Jede Fehlerantwort dieser Schnittstelle hat genau diese Form. Der deutsche Text darf sich jederzeit ändern und präziser werden; das Kürzel in \u0022code\u0022 ändert sich NIE und wird auch nie wiederverwendet – darauf darf ein Partnersystem seine Logik stützen.","required":["fehler","code"],"properties":{"fehler":{"description":"Der Fehler im Klartext, auf Deutsch – für den Menschen, der die Anbindung baut.","type":"string","example":"Pflichtfelder fehlen: empfaengerName"},"code":{"description":"Das maschinenlesbare Kürzel. Die Liste ist vollständig und wird aus dem Code erzeugt, nicht abgetippt.","type":"string","example":"PFLICHTFELD_FEHLT","enum":["AENDERUNG_ZU_SPAET","BEREITS_STORNIERT","FELD_UNGUELTIG","IDEMPOTENZ_KONFLIKT","IDEMPOTENZ_LAEUFT_NOCH","IDEMPOTENZ_SCHLUESSEL_ZU_LANG","IP_LIMIT_ERREICHT","JSON_UNGUELTIG","LETZTES_PACKSTUECK","PACKSTUECK_FEHLT","PACKSTUECK_NICHT_GEFUNDEN","PACKSTUECK_UNGUELTIG","PARAMETER_FEHLT","PARTNER_NICHT_GEFUNDEN","PFLICHTFELD_FEHLT","PREIS_NICHT_BERECHENBAR","PRODUKT_UNBEKANNT","RATE_LIMIT_ERREICHT","RECHT_FEHLT","ROUTING_NICHT_MOEGLICH","SCHLUESSEL_UNGUELTIG","SENDUNGSNUMMER_KONFLIKT","SENDUNG_NICHT_GEFUNDEN","SENDUNG_UNGUELTIG","TARIF_FEHLT"]}},"type":"object"},"Sendungsfelder":{"title":"Felder einer Sendung","description":"Alle Angaben, die eine Sendung tragen kann. Dieselbe Liste gilt für die Sendungsanlage über diese Schnittstelle, für den CSV-Import und für die Eingabemasken in beiden Portalen – es gibt sie im System nur einmal. Ein Feld, das hier steht, ist auf allen Wegen befüllbar; kommt eines dazu, erscheint es ohne Zutun auch in dieser Beschreibung.","required":["absenderName","absenderStrasse","absenderPlz","absenderOrt","empfaengerName","empfaengerStrasse","empfaengerPlz","empfaengerOrt"],"properties":{"absenderName":{"description":"Absender: Name 1","type":"string"},"absenderName2":{"description":"Absender: Name 2 (Abteilung, z. Hd.)","type":"string","nullable":true},"absenderStrasse":{"description":"Absender: Straße","type":"string"},"absenderHausnummer":{"description":"Absender: Hausnummer","type":"string","nullable":true},"absenderPlz":{"description":"Absender: PLZ","type":"string"},"absenderOrt":{"description":"Absender: Ort","type":"string"},"absenderLand":{"description":"Absender: Land (ISO-Code, z. B. DE)","type":"string","nullable":true},"absenderAnsprechpartner":{"description":"Absender: Ansprechpartner Abholung","type":"string","nullable":true},"absenderEmail":{"description":"Absender: E-Mail","type":"string","nullable":true},"absenderTelefon":{"description":"Absender: Telefon","type":"string","nullable":true},"empfaengerName":{"description":"Empfänger: Name 1","type":"string"},"empfaengerName2":{"description":"Empfänger: Name 2","type":"string","nullable":true},"empfaengerStrasse":{"description":"Empfänger: Straße","type":"string"},"empfaengerHausnummer":{"description":"Empfänger: Hausnummer","type":"string","nullable":true},"empfaengerPlz":{"description":"Empfänger: PLZ","type":"string"},"empfaengerOrt":{"description":"Empfänger: Ort","type":"string"},"empfaengerLand":{"description":"Empfänger: Land (ISO-Code, z. B. DE)","type":"string","nullable":true},"empfaengerAnsprechpartner":{"description":"Empfänger: Ansprechpartner","type":"string","nullable":true},"empfaengerEmail":{"description":"Empfänger: E-Mail","type":"string","nullable":true},"empfaengerTelefon":{"description":"Empfänger: Telefon","type":"string","nullable":true},"referenz1":{"description":"Referenz 1 (eigene Auftragsnummer)","type":"string","nullable":true},"referenz2":{"description":"Referenz 2","type":"string","nullable":true},"abholdatum":{"description":"Abholdatum (JJJJ-MM-TT) Format JJJJ-MM-TT.","type":"string","nullable":true},"abholzeitVon":{"description":"Abholzeit von (HH:MM) Format HH:MM.","type":"string","nullable":true},"abholzeitBis":{"description":"Abholzeit bis (HH:MM) Format HH:MM.","type":"string","nullable":true},"zustelldatum":{"description":"Zustelldatum (JJJJ-MM-TT) Format JJJJ-MM-TT.","type":"string","nullable":true},"zustellzeitVon":{"description":"Zustellzeit von (HH:MM) Format HH:MM.","type":"string","nullable":true},"zustellzeitBis":{"description":"Zustellzeit bis (HH:MM) Format HH:MM.","type":"string","nullable":true},"nachnahmeBetrag":{"description":"Nachnahmebetrag in EUR Betrag in EUR, Komma oder Punkt als Trennzeichen (z. B. \u0022199,90\u0022).","type":"string","nullable":true},"warenwert":{"description":"Warenwert in EUR (Zoll) Betrag in EUR, Komma oder Punkt als Trennzeichen (z. B. \u0022199,90\u0022).","type":"string","nullable":true},"warenbeschreibung":{"description":"Warenbeschreibung (Zoll)","type":"string","nullable":true},"abholInfo":{"description":"Abhol-Info für den Fahrer","type":"string","nullable":true},"zustellInfo":{"description":"Zustell-Info für den Fahrer","type":"string","nullable":true},"adr":{"description":"Gefahrgut ADR (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"schockwaechter":{"description":"Schockwächter (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"nichtStapelbar":{"description":"Nicht stapelbar (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"fixtermin":{"description":"Fixtermin (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"samstagszustellung":{"description":"Samstagszustellung (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"angeliefertSelbstabholer":{"description":"Selbstabholer am Depot (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"angeliefert":{"description":"Angeliefert - keine Abholfahrt (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"persoenlicheZustellung":{"description":"Persönliche Zustellung (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"versicherung":{"description":"Versicherung (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"telefonischesAbholAvis":{"description":"Telefonisches Abhol-Avis (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"telefonischesZustellAvis":{"description":"Telefonisches Zustell-Avis (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"nachwiegen":{"description":"Nachwiegen (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"briefkastenzustellung":{"description":"Briefkastenzustellung (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"abstellgenehmigung":{"description":"Abstellgenehmigung (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"abstellort":{"description":"Abstellort (bei Abstellgenehmigung Pflicht)","type":"string","nullable":true},"adressermittlung":{"description":"Adressermittlung nötig (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"avisierungVortag":{"description":"Abholung am Vortag avisiert (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"folgeauftragMehrfachabholung":{"description":"Folgeauftrag Mehrfachabholung (ja\/nein) Wahr oder falsch; über CSV auch \u0022x\u0022, \u0022ja\u0022, \u00221\u0022.","type":"boolean","nullable":true},"wartezeitMinuten":{"description":"Wartezeit in Minuten","type":"integer","nullable":true}},"type":"object"},"PackstueckEingabe":{"title":"Ein Packstück","description":"Aus Länge, Breite, Höhe und Realgewicht ergibt sich das frachtpflichtige Gewicht: das Höhere aus Realgewicht und Volumengewicht (L×B×H ÷ Teiler des Landes). Die Reihenfolge der Packstücke im Aufruf bestimmt ihre laufende Nummer und damit die Zählung „1 von 3\u0022 auf dem Label.","required":["laengeCm","breiteCm","hoeheCm","realgewichtKg"],"properties":{"laengeCm":{"description":"Länge in Zentimetern – muss größer als 0 sein.","type":"number","format":"float","example":25},"breiteCm":{"description":"Breite in Zentimetern – muss größer als 0 sein.","type":"number","format":"float","example":25},"hoeheCm":{"description":"Höhe in Zentimetern – muss größer als 0 sein.","type":"number","format":"float","example":25},"realgewichtKg":{"description":"Tatsächliches Gewicht in Kilogramm – muss größer als 0 sein.","type":"number","format":"float","example":25}},"type":"object"},"PartnerOeffentlich":{"title":"Partner im Stationsverzeichnis","description":"Name, Anschrift, Lageranschrift mit Öffnungszeiten, Kürzel und Kontakt. AUSDRÜCKLICH NICHT enthalten: Bankverbindung, Kaution, Preislisten, Vergütungen, Steuersatz, Zahlungsziel, Abrechnungsintervall, Tagesdurchsatz, Rechnungsanschrift, Steuernummern und interne Bemerkungen. Das Feld \u0022typ\u0022 unterscheidet echte Geschäftspartner von Einrichtungen der ATF (Hub, Nachtumschlag, Zentrale). Zum Datenschutz: \u0022notruf\u0022 und die Ansprechpartner sind personenbezogene Angaben und stehen jedem gültigen Schlüssel offen – sie gehören zum Stationsverzeichnis, weil sie um 22 Uhr vor einem geschlossenen Tor gebraucht werden.","properties":{"kuerzel":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"nameZusatz":{"type":"string","nullable":true},"typ":{"type":"string","nullable":true},"anschrift":{"properties":{"strasse":{"type":"string","nullable":true},"hausnummer":{"type":"string","nullable":true},"plz":{"type":"string","nullable":true},"ort":{"type":"string","nullable":true},"land":{"type":"string","nullable":true}},"type":"object"},"lageranschrift":{"properties":{"name":{"type":"string","nullable":true},"strasse":{"type":"string","nullable":true},"hausnummer":{"type":"string","nullable":true},"plz":{"type":"string","nullable":true},"ort":{"type":"string","nullable":true},"land":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"oeffnungszeiten":{"type":"string","nullable":true}},"type":"object"},"kontakt":{"properties":{"telefon":{"type":"string","nullable":true},"telefon2":{"type":"string","nullable":true},"telefon3":{"type":"string","nullable":true},"fax":{"type":"string","nullable":true},"notruf":{"type":"string","nullable":true},"notruf2":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"homepage":{"type":"string","nullable":true},"ansprechpartner":{"type":"array","items":{"type":"string"}},"buerozeiten":{"type":"string","nullable":true}},"type":"object"}},"type":"object"},"Station":{"title":"Beteiligte Station","description":"Kürzel und Name einer beteiligten Station oder eines Hubs. Bewusst NUR diese zwei Angaben – keine Preise, keine Finanzdaten, keine Konditionen.","properties":{"kuerzel":{"type":"string","example":"ANS"},"name":{"type":"string","example":"Anspach Spedition GmbH"}},"type":"object","nullable":true},"PackstueckAntwort":{"title":"Ein Packstück in der Antwort","description":"ENTFERNTE PACKSTÜCKE BLEIBEN IN DIESER LISTE, mit \u0022entfernt\u0022: true. Sie zählen nirgends mehr mit – nicht im Gewicht, nicht in der Anzahl, nicht im Preis –, aber ihre Packstücknummer und ihr gedrucktes Etikett bleiben gültig: Wird das Etikett doch gescannt, kommt das Packstück automatisch zurück in die Sendung und in die Abrechnung, und der Preis wird neu berechnet.","properties":{"laufendeNummer":{"description":"Die Zählung „1 von 3\u0022 auf dem Etikett. Sie bleibt einem Packstück dauerhaft, auch nach dem Entfernen – Nummern werden nie neu vergeben.","type":"integer"},"packstuecknummer":{"description":"Steht als Barcode auf dem Etikett.","type":"string"},"laengeCm":{"type":"number","format":"float"},"breiteCm":{"type":"number","format":"float"},"hoeheCm":{"type":"number","format":"float"},"realgewichtKg":{"type":"number","format":"float"},"frachtpflichtigesGewichtKg":{"description":"Das Höhere aus Realgewicht und Volumengewicht.","type":"number","format":"float"},"entfernt":{"description":"true, wenn dieses Packstück aus der Sendung genommen wurde.","type":"boolean"},"entferntAm":{"type":"string","format":"date-time","nullable":true},"wiederAufgenommenAm":{"description":"Gesetzt, wenn ein entferntes Packstück durch einen Scan wieder aufgenommen wurde.","type":"string","format":"date-time","nullable":true},"label":{"description":"Fertige Adresse für den Nachdruck genau dieses Etiketts.","type":"string"},"scans":{"description":"NUR bei der Statusabfrage. Alle Scans dieses Packstücks, ältester zuerst.","type":"array","items":{"properties":{"zeitpunkt":{"type":"string","format":"date-time"},"code":{"type":"string"},"bezeichnung":{"type":"string"},"prozessschritt":{"type":"string"},"prozessschrittText":{"type":"string"},"hub":{"type":"string","nullable":true},"liniennummer":{"type":"string","nullable":true},"gewichtKg":{"type":"number","format":"float","nullable":true},"bemerkung":{"type":"string","nullable":true}},"type":"object"}}},"type":"object"},"Sendung":{"title":"Eine Sendung","description":"Diese Form liefern ALLE Endpunkte, die eine Sendung zurückgeben: die Anlage, die Statusabfrage und jede Änderung. Wer sie einmal versteht, versteht sie überall. Die beteiligten Stationen sind einzeln benannt – \u0022abholStation\u0022 holt ab, \u0022zustellStation\u0022 stellt zu –, damit niemand aus einer Liste erraten muss, wer was tut.","properties":{"sendungsnummer":{"type":"string","example":"TST-100-0000123"},"status":{"description":"Das maschinenlesbare Kürzel.","type":"string","example":"angemeldet"},"statusText":{"description":"Derselbe Status als deutscher Text.","type":"string","example":"Sendung angemeldet"},"test":{"description":"true, wenn mit einem Testschlüssel angelegt – dann läuft nichts ins Clearing.","type":"boolean"},"produktCode":{"description":"Die tatsächlich gebuchte Sendungsart – gefüllt auch dann, wenn der Aufruf keine angab.","type":"string","nullable":true},"anzahlPackstuecke":{"description":"Ohne entfernte Packstücke.","type":"integer"},"frachtpflichtigesGewichtKg":{"description":"Das Höhere aus Real- und Volumengewicht über alle nicht entfernten Packstücke.","type":"number","format":"float"},"auftraggeber":{"$ref":"#\/components\/schemas\/Station"},"abholStation":{"$ref":"#\/components\/schemas\/Station"},"zustellStation":{"$ref":"#\/components\/schemas\/Station"},"abholHub":{"$ref":"#\/components\/schemas\/Station"},"zustellHub":{"$ref":"#\/components\/schemas\/Station"},"ueberZweiHubs":{"description":"true, wenn zwischen den beiden Hubs ein Hauptlauf fährt – das ändert Laufzeit und Preis.","type":"boolean"},"felder":{"description":"Alle Sendungsfelder so, wie sie GESPEICHERT sind. Hier lässt sich ablesen, was aus den eigenen Angaben geworden ist – Ländercodes werden groß geschrieben, leere Felder werden zu null, eine fehlende Sendungsart wird die Standard-Sendungsart. ZWEI AUSNAHMEN von \u0022leer wird null\u0022: Wird \u0022abholdatum\u0022 nicht mitgeschickt, setzt die Anlage das heutige Datum; wird \u0022zustelldatum\u0022 nicht mitgeschickt, setzt sie das Abholdatum plus einen Kalendertag. Beides steht danach hier und lässt sich vor der Zustellung normal ändern. Grund: Eine Sendung ohne Abholdatum gehört zu keinem Tag und liefe damit in keine Abrechnung. Pflichtfelder werden die beiden dadurch nicht – wer sie mitschickt, dessen Werte gelten unverändert.","allOf":[{"$ref":"#\/components\/schemas\/Sendungsfelder"}]},"packstuecke":{"type":"array","items":{"$ref":"#\/components\/schemas\/PackstueckAntwort"}},"label":{"description":"Fertige Adresse des Label-PDF (alle Packstücke). Bitte von hier übernehmen, statt Adressen selbst zu bauen.","type":"string"},"statusUrl":{"description":"Fertige Adresse der Statusabfrage.","type":"string"}},"type":"object"},"Preisauskunft":{"title":"Preisrechnung","description":"Jede Position einzeln – Grundpreis (Abhol-, Linien-, Zustellanteil) und jeder Zuschlag mit eigenem Rechenweg. Jeder Betrag steht zweimal da: \u0022…\u0022 maschinell weiterrechenbar mit Punkt, \u0022…Anzeige\u0022 in deutscher Schreibweise wie im Portal.","properties":{"preisVerfuegbar":{"description":"Kam überhaupt ein Preis heraus?","type":"boolean"},"vollstaendig":{"description":"ACHTUNG, das ist eine ANDERE Aussage als preisVerfuegbar: Fehlt zu einer PLZ die Preiszone, kommen Linien- und Zustellanteil sauber heraus und der Abholanteil steht auf 0,00. Die Summe sieht dann plausibel aus. Wer sie ungeprüft als Angebot weitergibt, fährt die Abholung umsonst – deshalb dieses Feld zum Abfragen statt einer Hinweisliste zum Auswerten.","type":"boolean"},"test":{"description":"Testschlüssel? Der Preis ist derselbe – ein Testschlüssel rechnet mit denselben Tarifen.","type":"boolean"},"waehrung":{"type":"string","example":"EUR"},"frachtpflichtigesGewichtKg":{"description":"Das Höhere aus Real- und Volumengewicht – die Zahl, über die im Zweifel gestritten wird.","type":"number","format":"float"},"produktCode":{"type":"string","nullable":true},"positionen":{"type":"array","items":{"properties":{"art":{"type":"string"},"bezeichnung":{"type":"string"},"betrag":{"description":"Maschinell weiterrechenbar, mit Punkt.","type":"string","example":"12.50"},"betragAnzeige":{"type":"string","example":"12,50 EUR"},"rechenweg":{"description":"Sagt, WARUM der Betrag so hoch ist – ohne ihn bleibt jede Rückfrage eines Kunden unbeantwortbar.","type":"string","example":"bis 5 kg pauschal 4.93 + Klasse bis 30 kg: 20 kg je 0.2300 = 4.60"},"hinweis":{"type":"string","nullable":true}},"type":"object"}},"summe":{"properties":{"netto":{"type":"string","example":"42.00"},"nettoAnzeige":{"type":"string","example":"42,00 EUR"},"steuersatzProzent":{"type":"number","format":"float","example":19},"steuer":{"type":"string"},"steuerAnzeige":{"type":"string"},"brutto":{"type":"string"},"bruttoAnzeige":{"type":"string"}},"type":"object"},"hinweise":{"description":"Warum es keinen oder keinen vollständigen Preis gibt, im Klartext.","type":"array","items":{"type":"string"}},"unverbindlich":{"description":"Steht im Klartext dabei: Die Auskunft ist unverbindlich und trägt bewusst keine Vorgangsnummer.","type":"string"}},"type":"object"},"Aenderungsantwort":{"title":"Antwort auf eine Änderung","description":"Die vollständige Sendung in ihrem NEUEN Stand – dieselbe Form wie bei Anlage und Statusabfrage – plus den neu berechneten Preis und den Hinweis auf den Etiketten-Nachdruck.","type":"object","allOf":[{"$ref":"#\/components\/schemas\/Sendung"},{"properties":{"preis":{"description":"Nach jeder Änderung neu berechnet, in derselben Form wie die Preisauskunft.","allOf":[{"$ref":"#\/components\/schemas\/Preisauskunft"}]},"labelNeuDrucken":{"description":"true, wenn sich eine Angabe geändert hat, die AUF DEM ETIKETT steht. Dann bitte die Etiketten neu drucken und die alten vernichten: Die gedruckten Barcodes bleiben scanbar, zeigen aber veraltete Angaben.","type":"boolean"},"hinweise":{"description":"Was zu dieser Änderung zu sagen ist – der Nachdruck-Hinweis steht als erster, dazu je nach Aufruf fehlende Zollangaben oder der Hinweis, dass ein entferntes Etikett scanbar bleibt. Ist die Sendung bereits abgerechnet, steht hier außerdem, dass die bestehende Rechnung unverändert bleibt und der Unterschied als eigene Nachberechnung bzw. Gutschrift auf die nächste kommt.","type":"array","items":{"type":"string"}}},"type":"object"}]}},"securitySchemes":{"ApiSchluessel":{"type":"apiKey","description":"Der Schlüssel des Partners. Wird von der ATF-Zentrale ausgegeben und ist einzeln sperrbar.","name":"X-Api-Key","in":"header"}}},"security":[{"ApiSchluessel":[]}],"tags":[{"name":"Partner"},{"name":"Preis"},{"name":"Stammdaten"},{"name":"Sendung ändern"},{"name":"Sendung"}]}