This is the full developer documentation for Shirtee Händler-API # Shirtee Händler-API > Bestellungen, Katalog, Rechnungen, Reklamationen und Lager aus deiner eigenen Software steuern. Händler-API · REST · JSON # Shirtee in deine Software einbauen Bestellungen anlegen, Sendungen verfolgen, Katalog und Rechnungen abrufen. Eine API, die jeden Aufruf erklärt und dich vor Fehlern schützt. [Erste Bestellung anlegen](/guides/first-order/)[API-Referenz öffnen](/reference/) * OpenAPI 3.1 * Bearer-Schlüssel mit Scopes * Vorschau ohne Risiko * Sicher wiederholbar ******curl ``` $ curl https://gateway.shirtee.cloud/api/orders/900001 \ -H "Authorization: Bearer $SHIRTEE_API_KEY" 200 OK { "id": 900001, "external_reference": "SHOP-10045", "status": "PENDING", "retention": null } ``` ## In drei Schritten startklar 1. [1**Schlüssel anlegen**Erstelle im Portal einen API-Schlüssel mit genau den Berechtigungen, die du brauchst.](/guides/api-keys/) 2. [2**Anmelden**Sende den Schlüssel als Bearer-Token und prüfe deinen Zugang.](/guides/authentication/) 3. [3**Bestellen**Prüfe mit der Vorschau und lege die Bestellung sicher an.](/guides/first-order/) ## Was du steuern kannst [**Bestellungen**Anlegen, ändern, stornieren, nachbestellen und per Status verfolgen.*Mehr erfahren*](/reference/)[**Katalog**Produkte, Varianten, Farben, Größen und Bestand lesen.*Mehr erfahren*](/reference/)[**Rechnungen**Rechnungen und Gutschriften auflisten, PDF abrufen.*Mehr erfahren*](/guides/polling/)[**Reklamationen**Mit Fotos melden, einreichen, Rückfragen beantworten.*Mehr erfahren*](/reference/)[**Lager**Anlieferungen planen, Versandlisten einlesen, Bestand pflegen.*Mehr erfahren*](/reference/)[**Sicher von Anfang an**Scopes je Schlüssel, Vorschau-Endpunkte und Idempotency-Key.*Mehr erfahren*](/guides/scopes/) ## Bereit für KI-Agenten Claude Code, Codex & Co. verstehen die API selbst: mit OpenAPI-Spec, llms.txt und einem fertigen Anweisungs-Snippet für dein Repo. [Mit KI-Agenten arbeiten](/guides/ai-agents/) * [`llms.txt`Index](/llms.txt) * [`llms-full.txt`Markdown](/llms-full.txt) * [`openapi.json`OpenAPI 3.1](https://gateway.shirtee.cloud/public/merchant-api/openapi.json) # Änderungsprotokoll > Was sich an der Händler-API und dieser Dokumentation geändert hat. Neueste Änderungen zuerst. Änderungen der API sind additiv, siehe [Stabilität und Änderungen](/guides/stability/). ## Oktober 2026 [Abschnitt betitelt „Oktober 2026“](#oktober-2026) ### Offizielle Adresse und Entwickler-Dokumentation [Abschnitt betitelt „Offizielle Adresse und Entwickler-Dokumentation“](#offizielle-adresse-und-entwickler-dokumentation) * Die Händler-API ist unter `https://gateway.shirtee.cloud` erreichbar. Bisherige Adressen bleiben erreichbar; neue Integrationen nutzen `gateway.shirtee.cloud`. * Diese Dokumentation mit API-Referenz ist online. * Die API-Referenz zeigt für jede Operation Beschreibung, Parameter, Beispiele und alle Antwortcodes. # Mit KI-Agenten arbeiten > Wie du die Händler-API mit Claude Code, Codex oder anderen Coding-Agenten nutzt, und welche maschinenlesbaren Fassungen es gibt. Wenn dein Team mit einem Coding-Agenten wie Claude Code oder Codex arbeitet, kann der Agent die Händler-API selbst verstehen und Integrationen bauen. Dafür gibt es drei maschinenlesbare Quellen, die ohne Schlüssel erreichbar sind. ## Maschinenlesbare Quellen [Abschnitt betitelt „Maschinenlesbare Quellen“](#maschinenlesbare-quellen) | Quelle | Adresse | Wofür | | ------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **OpenAPI-Spec** | `https://gateway.shirtee.cloud/public/merchant-api/openapi.json` | Vollständiger Vertrag: alle Operationen, Parameter, Beispiele, Antwortcodes und die nötigen Scopes (`x-customer-scopes`). Beste Quelle, um einen Client zu erzeugen. | | **`llms.txt`** | [`/llms.txt`](/llms.txt) | Kurzer Index dieser Dokumentation mit Links, gedacht für Sprachmodelle. | | **`llms-full.txt`** | [`/llms-full.txt`](/llms-full.txt) | Alle Anleitungen in einer Markdown-Datei. Passt in den Kontext eines Agenten. | Tipp Gib deinem Agenten zuerst `llms-full.txt` für die Konzepte (Anmeldung, Vorschau, Idempotenz, Fehler) und die OpenAPI-Spec für die genauen Operationen. ## Ein Anweisungs-Snippet für dein Repo [Abschnitt betitelt „Ein Anweisungs-Snippet für dein Repo“](#ein-anweisungs-snippet-für-dein-repo) Lege diesen Abschnitt in die Projektanweisungen deines Agenten (`AGENTS.md` bei Codex, `CLAUDE.md` bei Claude Code): ```markdown ## Shirtee Händler-API - Spec: https://gateway.shirtee.cloud/public/merchant-api/openapi.json - Konzepte: https://developers.shirtee.cloud/llms-full.txt - Basis-Adresse: https://gateway.shirtee.cloud, Anmeldung per `Authorization: Bearer $SHIRTEE_API_KEY`. - Das Token steht nur in der Umgebungsvariable. Es nie in Code, Logs, Tests oder Ausgaben schreiben. - Es gibt keine Sandbox. Schreibende Aufrufe gehen live. Vor Änderungen die `.../preview`-Endpunkte nutzen und echte Bestellungen nur nach ausdrücklicher Freigabe anlegen. - `POST /api/orders` immer mit `Idempotency-Key` senden und nur mit demselben Key wiederholen. - Fehler nach `extra.error` auswerten, nicht nach `detail`. Nur `429` und `5xx` wiederholen, bei `429` mindestens `RateLimit-Reset` Sekunden warten. - Unbekannte Felder in Antworten ignorieren. ``` ## Sicher arbeiten lassen [Abschnitt betitelt „Sicher arbeiten lassen“](#sicher-arbeiten-lassen) Ein Agent handelt schnell und in Schleifen. Das braucht Leitplanken: * **Eigener Schlüssel pro Agent**, mit den **kleinsten nötigen Scopes**. Zum Entwickeln genügen oft `merchant_order:read` und `merchant_catalog:read`. Schreibrechte erst, wenn du sie brauchst, siehe [Scopes](/guides/scopes/). * **Kurze Gültigkeit.** Ein Schlüssel für eine Entwicklungsphase darf nach Tagen ablaufen, siehe [API-Schlüssel](/guides/api-keys/). * **Keine Sandbox.** Lass den Agenten Tests gegen die Vorschau-Endpunkte und gegen Lese-Operationen schreiben. Die Anlage echter Bestellungen bleibt eine bewusste Handlung. * **Mengenbegrenzung beachten.** Eine Agenten-Schleife erreicht schnell das Budget, siehe [Mengenbegrenzung](/guides/rate-limits/). * **Token nie im Chat.** Gib ihn per Umgebungsvariable, nicht im Gesprächsverlauf. ## Und Chat-Assistenten? [Abschnitt betitelt „Und Chat-Assistenten?“](#und-chat-assistenten) Für Assistenten wie Claude oder ChatGPT, die Aufgaben in deinem Konto erledigen sollen, richtest du im Portal unter **KI-Assistent & API** eine eigene Verbindung ein. Sie läuft nicht über `gateway.shirtee.cloud`, siehe [Überblick](/guides/overview/). # API-Schlüssel anlegen > Wie du im Portal einen API-Schlüssel erstellst, wie lange er gilt und wie du ihn widerrufst. Ein API-Schlüssel ist das Zugangsdatum deiner Software. Er handelt als dein Händlerkonto und sieht nur deine eigenen Daten. ## Schlüssel erstellen [Abschnitt betitelt „Schlüssel erstellen“](#schlüssel-erstellen) 1. Melde dich im Portal an: [portal.shirtee.cloud](https://portal.shirtee.cloud). 2. Öffne **KI-Assistent & API** und wechsle auf den Bereich **API-Schlüssel**. 3. Lege einen Schlüssel an und vergib diese Angaben: | Angabe | Regel | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | **Name** | 1 bis 64 Zeichen. Wähle einen Namen, an dem du die Software erkennst, zum Beispiel „Shop-Anbindung“. | | **Berechtigungen** | Mindestens eine. Angeboten werden nur Berechtigungen, die für dein Konto freigeschaltet sind, siehe [Scopes und Freischaltung](/guides/scopes/). | | **Gültigkeit** | 1 bis 365 Tage, voreingestellt 90 Tage. | Das Token siehst du nur einmal Nach dem Anlegen zeigt das Portal das Token genau einmal an. Kopiere es sofort in deinen Passwortmanager oder dein Secret-Management. Später ist es nicht mehr abrufbar. Hast du es verloren, widerrufe den Schlüssel und lege einen neuen an. Zur Kontrolle schickt Shirtee an die Adresse des angemeldeten Benutzers eine E-Mail mit Name, Kennung, Berechtigungen und Ablaufdatum. Das Token steht nie in der Mail. Erkennst du den Schlüssel nicht wieder, widerrufe ihn. ## Kennung und Status [Abschnitt betitelt „Kennung und Status“](#kennung-und-status) In der Liste siehst du je Schlüssel eine **Kennung** (die ersten Zeichen), Berechtigungen, Erstellungs- und Ablaufdatum sowie den Status **Aktiv**, **Widerrufen** oder **Abgelaufen**. Die Kennung nennst du dem Support, wenn du Hilfe zu einem Schlüssel brauchst. Das Token selbst nennst du nie. ## Berechtigungen ändern [Abschnitt betitelt „Berechtigungen ändern“](#berechtigungen-ändern) Ein Schlüssel trägt genau die Berechtigungen, die du beim Anlegen gewählt hast. Brauchst du später mehr, lege einen neuen Schlüssel an und stelle deine Software um. Du kannst den alten danach widerrufen. ## Schlüssel widerrufen [Abschnitt betitelt „Schlüssel widerrufen“](#schlüssel-widerrufen) Widerrufe einen Schlüssel im selben Bereich. Der Widerruf wirkt ab der nächsten Anfrage: Sie liefert dann `403` mit der Meldung `Scoped API key revoked`. Ein abgelaufener Schlüssel liefert `401`. ## Wer Schlüssel anlegen kann [Abschnitt betitelt „Wer Schlüssel anlegen kann“](#wer-schlüssel-anlegen-kann) Nur angemeldete Händler. Der Schlüssel gilt für dein Konto. Gehört der Benutzer, der ihn angelegt hat, nicht mehr zu diesem Händler, antwortet der Schlüssel ebenfalls mit `403`. ## Sicher aufbewahren [Abschnitt betitelt „Sicher aufbewahren“](#sicher-aufbewahren) * Speichere das Token nie im Quellcode, in Tickets oder in Chatnachrichten. * Nutze für jede Software einen eigenen Schlüssel, damit du einzelne Zugänge widerrufen kannst. * Gib einem Schlüssel nur die Berechtigungen, die die Software braucht. * Trage Produktivschlüssel in der [API-Referenz](/reference/) nur auf deinem eigenen Rechner ein. # Anmeldung > Wie du dich mit einem API-Schlüssel als Bearer-Token anmeldest und was 401, 403 und 404 bedeuten. Jede Anfrage trägt deinen API-Schlüssel als Bearer-Token im Header `Authorization`. ```bash curl https://gateway.shirtee.cloud/api/orders \ -H "Authorization: Bearer $SHIRTEE_API_KEY" ``` Setze das Token aus deinem Secret-Management in die Umgebungsvariable und schreibe es nie fest in den Befehl oder das Skript. ## Die Spec ist öffentlich [Abschnitt betitelt „Die Spec ist öffentlich“](#die-spec-ist-öffentlich) Die OpenAPI-Spec brauchst du ohne Schlüssel: ```bash curl https://gateway.shirtee.cloud/public/merchant-api/openapi.json ``` Sie enthält genau die Operationen, die ein Händler-Schlüssel erreicht, und nennt je Operation in `x-customer-scopes` die Berechtigungen, von denen dein Schlüssel mindestens eine tragen muss. Alle anderen Schnittstellen lehnt ein Händler-Schlüssel mit `403` ab. ## 401, 403 und 404 unterscheiden [Abschnitt betitelt „401, 403 und 404 unterscheiden“](#401-403-und-404-unterscheiden) | Status | Meldung (`detail`) | Bedeutung | Was du tust | | ------ | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | | `401` | `Authentication required` | Der Header fehlt oder das Token ist ungültig oder abgelaufen. Die Meldung ist in allen drei Fällen gleich. | Header und Token prüfen, Ablaufdatum im Portal ansehen, bei Bedarf neuen Schlüssel anlegen | | `403` | `No permission to access this resource` | Der Schlüssel ist gültig, aber keine seiner wirksamen Berechtigungen passt zum Endpunkt, oder der Endpunkt steht Händler-Schlüsseln nicht offen. | Entscheidungsbaum unter [Scopes und Freischaltung](/guides/scopes/) | | `403` | `Scoped API key revoked` | Der Schlüssel wurde widerrufen. | Neuen Schlüssel anlegen | | `404` | `Not Found` o. ä. | Die Ressource gibt es nicht **oder sie gehört einem anderen Konto**. | ID prüfen | Fremde Ressourcen liefern bewusst `404` statt `403`. So verrät die API nicht, ob eine fremde Bestellung existiert. ## Fehlerformat [Abschnitt betitelt „Fehlerformat“](#fehlerformat) Alle Fehler haben dieselbe Form, siehe [Fehler](/guides/errors/). # Fehler > Das einheitliche Fehlerformat, die Bedeutung der Statuscodes und wie du Wiederholungen richtig steuerst. ## Format [Abschnitt betitelt „Format“](#format) Fehler der API sind JSON: ```json { "status_code": 404, "detail": "Not Found", "extra": {} } ``` | Feld | Bedeutung | | ------------- | ----------------------------------------------------------------------------------------------------------- | | `status_code` | HTTP-Statuscode, identisch mit dem der Antwort | | `detail` | Kurze Meldung in englischer Sprache. Für Menschen gedacht, nicht für Auswertung. | | `extra` | Optional. Maschinenlesbare Details, oft mit einem Code in `extra.error`. **Werte auswerten, nie `detail`.** | Unterscheide Fälle über `extra.error`. Jede Operation in der [Referenz](/reference/) nennt ihre Codes. ## Statuscodes [Abschnitt betitelt „Statuscodes“](#statuscodes) | Status | Bedeutung | Wiederholen? | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ | | `400` | Die Anfrage ist formal falsch oder erfüllt eine Regel nicht (fehlendes Feld, falscher Typ, ungültiger Wert). `extra.error` nennt, wenn vorhanden, den Grund. | Nein, erst korrigieren | | `401` | Nicht angemeldet oder Token ungültig oder abgelaufen | Nein, siehe [Anmeldung](/guides/authentication/) | | `403` | Keine passende Berechtigung oder Schlüssel widerrufen | Nein, siehe [Scopes](/guides/scopes/) | | `404` | Gibt es nicht oder gehört einem anderen Konto | Nein | | `409` | Konflikt mit dem aktuellen Zustand, etwa eine Aktion, die im Status der Ressource nicht mehr geht. `extra.error` nennt den Grund. | Erst Zustand neu lesen | | `413` | Upload zu groß | Nein, Datei verkleinern | | `422` | Die Anfrage ist verständlich, kann aber fachlich nicht ausgeführt werden, zum Beispiel Vorschau-Fehler oder `IDEMPOTENCY_KEY_REUSED` | Nein, erst korrigieren | | `429` | Zu viele Anfragen, siehe [Mengenbegrenzung](/guides/rate-limits/) | Ja, nach Wartezeit | | `5xx` | Fehler oder Störung auf Shirtee-Seite | Ja, mit Backoff | ## Wiederholen [Abschnitt betitelt „Wiederholen“](#wiederholen) * Wiederhole nur `429` und `5xx`, mit wachsendem Abstand (Backoff) und einer Obergrenze. * Wiederhole schreibende Aufrufe nur, wenn sie wiederholbar sind. Für die Bestellanlage gilt: [Idempotency-Key](/guides/idempotency/). * Plattform-Fehler kommen nicht immer als JSON an. Ein `502` oder `504` kann eine Fehlerseite im HTML-Format sein. Werte zuerst den Statuscode aus, dann erst den Inhalt. ## Antwort lesen [Abschnitt betitelt „Antwort lesen“](#antwort-lesen) Prüfe den Statuscode, bevor du den Inhalt als JSON parst. Dein Client sollte unbekannte Felder in Antworten ignorieren, siehe [Stabilität und Änderungen](/guides/stability/). # Die erste Bestellung > Von der Vorschau bis zum Status: eine Bestellung anlegen, prüfen und verfolgen. Dieser Ablauf legt eine Bestellung an. Du brauchst einen [API-Schlüssel](/guides/api-keys/) mit `merchant_order:read` (Vorschau und Abfrage) und `merchant_order:create` (Anlage). Achtung Es gibt keine Sandbox. Die Anlage erzeugt eine echte Bestellung. Prüfe zuerst mit der Vorschau. ## 1. Bestellung vorbereiten [Abschnitt betitelt „1. Bestellung vorbereiten“](#1-bestellung-vorbereiten) Speichere den Inhalt als `order.json`. Die SKU und die Motiv-URL ersetzt du durch eigene Werte. ```json { "external_reference": "SHOP-10045", "delivery_address": { "first_name": "Max", "last_name": "Mustermann", "street": "Musterstraße", "house_number": "1", "postcode": "50667", "city": "Köln", "country": "DE", "email": "max.mustermann@example.com" }, "billing_address": { "first_name": "Max", "last_name": "Mustermann", "street": "Musterstraße", "house_number": "1", "postcode": "50667", "city": "Köln", "country": "DE", "email": "max.mustermann@example.com" }, "items": [ { "sku": "TSHIRT-SCHWARZ-M", "external_id": "LINE-1", "amount": 2, "processings": [ { "processing_type": "DTG", "position": "FRONT", "design_url": "https://example.com/designs/motiv-001.png" } ] } ] } ``` Preise, Versandart und Hersteller sendest du nicht mit. Preise stammen aus dem Katalog, alles Übrige legt das System fest. Andere als die im Schema genannten Felder lehnt die API mit `403` ab. Eine Position mit `amount` 2 wird als zwei einzelne Stücke angelegt. ## 2. Vorschau [Abschnitt betitelt „2. Vorschau“](#2-vorschau) ```bash curl -X POST https://gateway.shirtee.cloud/api/orders/preview \ -H "Authorization: Bearer $SHIRTEE_API_KEY" \ -H "Content-Type: application/json" \ -d @order.json ``` Die Vorschau schreibt nichts. Bei einem Fehler in den Angaben antwortet sie mit `422` und einem Code in `extra.error`, zum Beispiel `UNKNOWN_SKU` oder `VARIANT_INACTIVE`. Mehr dazu unter [Vorschau vor Änderungen](/guides/previews/). ## 3. Anlegen [Abschnitt betitelt „3. Anlegen“](#3-anlegen) ```bash curl -X POST https://gateway.shirtee.cloud/api/orders \ -H "Authorization: Bearer $SHIRTEE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d @order.json ``` Speichere den `Idempotency-Key` bei deiner Bestellung. Bei einem Timeout wiederholst du mit demselben Key und demselben Inhalt, es entsteht keine zweite Bestellung, siehe [Bestellungen sicher wiederholen](/guides/idempotency/). Die Antwort (`201`) enthält die Bestellung im Status direkt nach der Anlage, zum Beispiel: ```json { "id": 900001, "slug": "CL-7K3M9QX", "external_reference": "SHOP-10045", "status": "PENDING", "retention": null } ``` Merke dir `id`. Sie adressiert die Bestellung in allen weiteren Aufrufen. ## 4. Status deuten [Abschnitt betitelt „4. Status deuten“](#4-status-deuten) Normalerweise lautet der Status `PENDING`, danach läuft die Verarbeitung automatisch weiter. Je nach Prüfergebnis kann direkt nach der Anlage ein anderer Status stehen: | Status | Bedeutung | | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `PENDING` | Angelegt, die Verarbeitung startet automatisch | | `PAUSE` | Kurze Wartezeit vor der Zuweisung | | `CHECK` | Die Bestellung braucht eine Prüfung, zum Beispiel wegen einer inaktiven Variante oder weil kein Produktionspartner verfügbar ist. `retention` nennt den Grund. | | `ERROR` | Ein Fehler hält die Bestellung an, zum Beispiel fehlende Preise. `retention` nennt den Grund. | `CHECK` und `ERROR` sind kein HTTP-Fehler: Die Bestellung existiert. Die Referenz der Operation `POST /api/orders` beschreibt alle Fälle. ## 5. Bestellung abfragen [Abschnitt betitelt „5. Bestellung abfragen“](#5-bestellung-abfragen) ```bash curl "https://gateway.shirtee.cloud/api/orders/900001?tracking=true" \ -H "Authorization: Bearer $SHIRTEE_API_KEY" ``` Mit `tracking=true` enthält die Antwort die Sendungen (Tracking-Nummer, Link, Versanddienstleister). Ohne den Parameter ist die Liste leer. Hast du deine eigene Nummer vergeben, findest du die Bestellung auch darüber: `GET /api/orders/by-external-reference/{external_reference}`. ## Weiter [Abschnitt betitelt „Weiter“](#weiter) * [Status abfragen statt Webhooks](/guides/polling/) * [Fehler](/guides/errors/) * [API-Referenz](/reference/) # Bestellungen sicher wiederholen > Mit dem Header Idempotency-Key legst du eine Bestellung bei Wiederholungen nur einmal an. Schlägt `POST /api/orders` wegen eines Timeouts oder Netzfehlers fehl, weißt du nicht, ob die Bestellung angelegt wurde. Ohne weitere Maßnahme würde ein Wiederholen eine zweite Bestellung erzeugen. Der Header `Idempotency-Key` verhindert das. ## So funktioniert es [Abschnitt betitelt „So funktioniert es“](#so-funktioniert-es) Schicke bei der Bestellanlage einen Schlüssel mit: ```bash curl -X POST https://gateway.shirtee.cloud/api/orders \ -H "Authorization: Bearer $SHIRTEE_API_KEY" \ -H "Idempotency-Key: 6b0e4c1e-8a57-4f7b-9d6a-2f6e0f8a1c11" \ -H "Content-Type: application/json" \ -d @order.json ``` | Wiederholung mit … | Ergebnis | | ------------------------------------------ | -------------------------------------------------------------------------- | | gleichem Schlüssel und **gleichem** Inhalt | Du erhältst die erste Bestellung zurück (`201`), es entsteht keine zweite. | | gleichem Schlüssel und **anderem** Inhalt | `422` mit `extra.error` = `IDEMPOTENCY_KEY_REUSED`. Es entsteht nichts. | | ohne Schlüssel | Jeder Aufruf legt eine neue Bestellung an. | ## Regeln für den Schlüssel [Abschnitt betitelt „Regeln für den Schlüssel“](#regeln-für-den-schlüssel) * 1 bis 128 sichtbare ASCII-Zeichen. Eine UUID eignet sich gut. * Er gilt nur für dein Konto. Zwei Händler können denselben Wert verwenden, ohne sich zu stören. * Er bleibt an die angelegte Bestellung gebunden. Der Code kennt keine Ablaufzeit. * Gleichzeitige Anfragen mit demselben Schlüssel legen die Bestellung nur einmal an. ## Empfohlener Ablauf [Abschnitt betitelt „Empfohlener Ablauf“](#empfohlener-ablauf) 1. Erzeuge **pro Bestellung** einmal einen Schlüssel und speichere ihn bei deiner Bestellung, bevor du sendest. 2. Wiederhole bei Timeout, Netzfehler oder `5xx` mit **demselben Schlüssel und demselben Inhalt**. 3. Erzeuge nur dann einen neuen Schlüssel, wenn du bewusst eine neue Bestellung willst. Hinweis Auch das Nachbestellen (`POST /api/orders/{order_id}/reorder`) kennt den Header. Die Referenz beschreibt die Details der Operation. # Überblick > Was die Shirtee Händler-API kann, unter welcher Adresse sie läuft und was es nicht gibt. Mit der Händler-API steuerst du dein Shirtee-Konto aus deiner eigenen Software: Bestellungen anlegen und verfolgen, den Katalog lesen, Rechnungen abrufen, Reklamationen melden und Anlieferungen ins Lager planen. Die API ist eine REST-Schnittstelle mit JSON. ## Basis-Adresse [Abschnitt betitelt „Basis-Adresse“](#basis-adresse) ```text https://gateway.shirtee.cloud ``` Alle Pfade beginnen mit `/api`, zum Beispiel `GET /api/orders`. Die Verbindung läuft nur über HTTPS. Anfragen und Antworten sind JSON; Datei-Uploads (Lieferbeleg, Reklamationsfotos, Anlieferungsdokumente, Versandliste) sind `multipart/form-data`. ## Was du damit machst [Abschnitt betitelt „Was du damit machst“](#was-du-damit-machst) | Bereich | Was möglich ist | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Bestellungen** | Bestellung per Vorschau prüfen und anlegen, Status und Verlauf lesen, stornieren, Adressen und Positionen ändern, nachbestellen, Lieferbeleg hochladen | | **Katalog** | Produkte, Varianten, Farben und Größen lesen, Variante per SKU finden, Verfügbarkeit prüfen | | **Rechnungen** | Rechnungen und Gutschriften auflisten, PDF abrufen | | **Reklamationen** | Reklamation mit Fotos als Entwurf anlegen, einreichen, Rückfragen beantworten, zurückziehen | | **Lager** | Anlieferungen planen und ändern, Versandliste einlesen, Dokumente hochladen, Lagerprodukte pflegen, Sicherheitsbestand lesen | Die [API-Referenz](/reference/) beschreibt jede Operation mit Parametern, Beispielen und allen Antwortcodes. ## So fängst du an [Abschnitt betitelt „So fängst du an“](#so-fängst-du-an) 1. [API-Schlüssel im Portal anlegen](/guides/api-keys/) 2. [Mit dem Schlüssel anmelden](/guides/authentication/) 3. [Die erste Bestellung anlegen](/guides/first-order/) ## Was es nicht gibt [Abschnitt betitelt „Was es nicht gibt“](#was-es-nicht-gibt) Bitte vorab lesen * **Keine Webhooks.** Änderungen holst du per Abfrage, siehe [Status abfragen statt Webhooks](/guides/polling/). * **Keine Sandbox.** Schreibende Aufrufe wirken im Live-System. Die [Vorschau-Endpunkte](/guides/previews/) schreiben nichts und zeigen vorab, was passieren würde. * **Keine Version im Pfad.** Es gibt kein `/v1`. Änderungen sind additiv, siehe [Stabilität und Änderungen](/guides/stability/). * **Kein MCP über diese Adresse.** Für KI-Assistenten wie Claude oder ChatGPT richtest du im Portal unter „KI-Assistent & API“ eine eigene Verbindung ein. Sie läuft nicht über `gateway.shirtee.cloud`. ## Voraussetzungen [Abschnitt betitelt „Voraussetzungen“](#voraussetzungen) Du brauchst ein Händlerkonto mit Portal-Login. Welche Funktionen deine Schlüssel nutzen dürfen, hängt von der Freischaltung deines Kontos ab, siehe [Scopes und Freischaltung](/guides/scopes/). # Status abfragen statt Webhooks > Wie du Änderungen an Bestellungen und Rechnungen per Abfrage verfolgst, ohne das Limit zu belasten. Die API sendet keine Webhooks. Änderungen erfährst du, indem du abfragst. ## Bestellungen [Abschnitt betitelt „Bestellungen“](#bestellungen) Die Liste `GET /api/orders` ist nach Eingang absteigend sortiert (neueste zuerst) und lässt sich filtern. Der Filter `status` ist mehrwertig: Wiederhole den Parameter, zum Beispiel `status=CHECK&status=ERROR`. Alle Filter gelten gleichzeitig. Für eine einzelne Bestellung nutzt du `GET /api/orders/{order_id}` mit `tracking=true`. Dort stehen Status, Rückhaltegrund und Sendungen. Empfehlung: * Frage **Listen** in einem festen Takt ab, zum Beispiel alle paar Minuten, und nicht jede Bestellung einzeln. * Frage **einzelne Bestellungen** nur ab, solange du auf eine Änderung wartest, und werde dabei langsamer: erst nach Sekunden, dann nach Minuten. * Höre auf zu fragen, sobald die Bestellung einen Endstatus erreicht hat. * Beachte das [Budget](/guides/rate-limits/): `RateLimit-Remaining` zeigt dir, wie viel übrig ist. ## Rechnungs-PDF [Abschnitt betitelt „Rechnungs-PDF“](#rechnungs-pdf) Rechnungs-PDFs entstehen erst beim ersten Abruf im Hintergrund. `GET /api/invoices/user/{invoice_id}/pdf` meldet deshalb einen Zwischenstand: | Fall | HTTP | `status` | `pdf_url` | | -------------------- | ----- | ------------ | ------------- | | PDF liegt vor | `200` | `ready` | signierte URL | | PDF wird erzeugt | `202` | `generating` | `null` | | PDF kommt nicht mehr | `200` | `failed` | `null` | Solange `202` mit `generating` kommt, wiederholst du denselben Aufruf. Ein Abstand von einigen Sekunden genügt. Wichtig: * `failed` kommt mit **`200`**, nicht mit `202` und nicht als Fehler. Prüfe `status`, nicht nur den HTTP-Code. * Der erste Abruf stößt die Erzeugung an. Weitere Abrufe innerhalb von 5 Minuten stoßen sie nicht erneut an. Danach wird sie bis zu dreimal angestoßen. `failed` kommt frühestens etwa 15 Minuten nach dem ersten Abruf. * Die URL in `pdf_url` ist signiert und **15 Minuten gültig**. Lade die PDF sofort oder hole mit einem neuen Aufruf eine frische URL. ```bash curl -i https://gateway.shirtee.cloud/api/invoices/user/123/pdf \ -H "Authorization: Bearer $SHIRTEE_API_KEY" ``` Die genauen Pfade und Antworten stehen in der [API-Referenz](/reference/). # Vorschau vor Änderungen > Die Vorschau-Endpunkte schreiben nichts und zeigen vorab, was eine Änderung bewirken würde. Weil es keine Sandbox gibt, prüfst du Änderungen vorab mit den Vorschau-Endpunkten. Sie schreiben **nichts**. Sie zeigen, was die Änderung jetzt bewirken würde. | Vorschau | Zweck | | ------------------------------------------------------ | ----------------------------------------------------- | | `POST /api/orders/preview` | Neue Bestellung prüfen | | `POST /api/orders/{order_id}/cancel/preview` | Prüfen, ob und zu welchen Bedingungen ein Storno geht | | `POST /api/orders/{order_id}/delivery-address/preview` | Prüfen, ob die Lieferadresse noch änderbar ist | | `POST /api/orders/{order_id}/items/preview` | Variantentausch prüfen | Alle vier brauchen nur `merchant_order:read`. ## Antwort [Abschnitt betitelt „Antwort“](#antwort) Jede Vorschau liefert `fingerprint` und `confirmed_summary`. Zwei Vorschauen einer unveränderten Bestellung haben denselben `fingerprint`. Daran erkennst du, dass sich zwischen Vorschau und Änderung nichts verändert hat. Die REST-API verlangt **keine** vorherige Vorschau. Du kannst jede Änderung auch direkt senden. ## Fehler und Zustand [Abschnitt betitelt „Fehler und Zustand“](#fehler-und-zustand) * Ist die **Anfrage selbst** fehlerhaft, antwortet die Vorschau mit `422` und einem Code in `extra.error`, zum Beispiel `UNKNOWN_SKU` oder `INVALID_DELIVERY_ADDRESS`. Die Codes stehen in der Referenz bei der jeweiligen Operation. * Dass eine Bestellung **nicht mehr änderbar oder stornierbar** ist, ist kein Fehler. Es steht im `200`-Ergebnis der Vorschau. # Mengenbegrenzung > Wie viele Anfragen die API zulässt, woran du dein Budget erkennst und wie du auf 429 reagierst. Die API begrenzt die Anfragen pro Minute, damit eine fehlerhafte Schleife nicht andere Händler beeinträchtigt. ## Wie gezählt wird [Abschnitt betitelt „Wie gezählt wird“](#wie-gezählt-wird) * **Pro Schlüssel.** Jeder gültige API-Schlüssel hat ein eigenes Budget. Mehrere Integrationen hinter derselben IP-Adresse teilen sich also kein Budget. * **Zusätzlich pro IP-Adresse** gilt eine höhere Obergrenze über alle Schlüssel dieser Quelle. * **Fenster:** 60 Sekunden. Derzeit gilt ein Budget von **300 Anfragen pro Minute und Schlüssel**. Shirtee kann diesen Wert ohne Ankündigung ändern. Verlasse dich auf die Header, nicht auf die Zahl. ## Header [Abschnitt betitelt „Header“](#header) Jede Antwort trägt die Header zur Mengenbegrenzung, auch ein `401` und ein `429`: | Header | Bedeutung | Beispiel | | --------------------- | ----------------------------- | ----------- | | `RateLimit-Policy` | Budget und Fenster | `300; w=60` | | `RateLimit-Limit` | Anfragen pro Fenster | `300` | | `RateLimit-Remaining` | Verbleibende Anfragen | `298` | | `RateLimit-Reset` | Sekunden bis zum Zurücksetzen | `48` | ## Bei 429 [Abschnitt betitelt „Bei 429“](#bei-429) Du hast das Budget aufgebraucht. Warte mindestens `RateLimit-Reset` Sekunden und wiederhole dann. Es gibt keinen `Retry-After`-Header. ```text wenn RateLimit-Remaining klein: langsamer senden bei 429: RateLimit-Reset Sekunden warten, dann erneut bei 429 trotz Wartezeit: Wartezeit verdoppeln (Backoff), Obergrenze setzen ``` ## Weniger Anfragen brauchen [Abschnitt betitelt „Weniger Anfragen brauchen“](#weniger-anfragen-brauchen) * Nutze Filter und Seitenwerte der Listen, statt jede Ressource einzeln abzufragen. * Frage Status nicht dichter ab als nötig, siehe [Status abfragen statt Webhooks](/guides/polling/). * Speichere Katalogdaten, die sich selten ändern, bei dir zwischen. # Scopes und Freischaltung > Welche Berechtigungen es gibt, wer sie freischaltet und warum ein Schlüssel trotz gültigem Token 403 liefern kann. Berechtigungen heißen **Scopes**. Ob ein Aufruf klappt, entscheidet sich auf drei Ebenen. ## Die drei Ebenen [Abschnitt betitelt „Die drei Ebenen“](#die-drei-ebenen) 1. **Freischaltung deines Kontos.** Shirtee legt fest, welche Scopes dein Konto überhaupt nutzen darf: ein Standard für alle Händler plus Zusatzrechte für einzelne Händler. Wirksam ist beides zusammen. Diese Menge kann sich ändern. 2. **Scopes des Schlüssels.** Beim Anlegen wählst du aus den freigeschalteten Scopes die aus, die der Schlüssel tragen soll. Der Schlüssel behält sie bis zum Ablauf. 3. **Anforderung des Endpunkts.** Jede Operation nennt in der Spec unter `x-customer-scopes` die Scopes, die sie akzeptiert. Dein Schlüssel braucht **mindestens einen** davon. Beim Aufruf zählt der **Schnitt** aus Ebene 1 und 2, bei jeder Anfrage neu. Nimmt Shirtee einen Scope aus der Freischaltung, verliert ihn auch ein bereits ausgestellter Schlüssel ab der nächsten Anfrage. ## Wo du siehst, was freigeschaltet ist [Abschnitt betitelt „Wo du siehst, was freigeschaltet ist“](#wo-du-siehst-was-freigeschaltet-ist) Im Portal unter **KI-Assistent & API** bietet das Anlegen eines Schlüssels nur freigeschaltete Berechtigungen an. Der Bereich **Fähigkeiten** erklärt sie. Fehlt dir eine Berechtigung, wende dich an den [Support](/support/). ## Die Scopes [Abschnitt betitelt „Die Scopes“](#die-scopes) | Scope | Erlaubt | | --------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `merchant_order:read` | Eigene Bestellungen, Sendungsverfolgung und Verlauf lesen; Vorschauen für Storno, Adressänderung und Variantentausch | | `merchant_order:create` | Bestellungen anlegen, nachbestellen und Lieferbelege hochladen | | `merchant_order:cancel` | Bestellungen stornieren | | `merchant_order:address` | Liefer- und Rechnungsadresse ändern | | `merchant_order:items` | Varianten tauschen und Positionen hinzufügen, ändern oder löschen | | `merchant_order:write` | Sammel-Scope: alle Schreibrechte für Bestellungen | | `merchant_catalog:read` | Produktkatalog, Varianten und Bestand lesen | | `merchant_invoice:read` | Eigene Rechnungen lesen | | `merchant_complaint:write` | Reklamationsentwürfe anlegen | | `warehouse:read` | Anlieferungen und Lagerartikel lesen | | `warehouse:shipment_write` | Anlieferungen anlegen, ändern und Versandlisten einlesen | | `warehouse:shipment_cancel` | Anlieferungen stornieren | | `warehouse:document_write` | Dokumente an Anlieferungen hochladen und entfernen | | `warehouse:write` | Sammel-Scope: alle Schreibrechte im Lager | Eine Operation akzeptiert den feinen Scope **und** den passenden Sammel-Scope. Fordere für neue Schlüssel die feinen Scopes an, dann gibst du nicht mehr frei, als die Software braucht. ## Warum liefert mein Schlüssel 403? [Abschnitt betitelt „Warum liefert mein Schlüssel 403?“](#warum-liefert-mein-schlüssel-403) Gehe in dieser Reihenfolge vor: 1. **Meldung lesen.** `Scoped API key revoked` heißt: Schlüssel widerrufen. Lege einen neuen an. 2. **Operation prüfen.** Steht der Endpunkt in der [Referenz](/reference/)? Alles andere lehnt ein Händler-Schlüssel ab. 3. **Scopes vergleichen.** Nimm `x-customer-scopes` der Operation und vergleiche mit den Berechtigungen deines Schlüssels (Portal, API-Schlüssel). Trägt der Schlüssel keinen davon, braucht es einen neuen Schlüssel. 4. **Freischaltung prüfen.** Trägt der Schlüssel den Scope, ist er aber für dein Konto nicht (mehr) freigeschaltet, hilft nur der [Support](/support/). # Stabilität und Änderungen > Wie sich die API weiterentwickelt und wie du deine Integration dagegen absicherst. Die Spec ist der Vertrag zwischen deiner Software und Shirtee. Wir entwickeln sie **additiv** weiter. ## Das darfst du erwarten [Abschnitt betitelt „Das darfst du erwarten“](#das-darfst-du-erwarten) * Neue Endpunkte, neue Felder in Antworten und neue optionale Parameter können jederzeit erscheinen. * Bestehende Felder, Pfade und Antwortcodes ändern wir nicht still. Eine Änderung, die bestehende Integrationen brechen könnte, kommt zuerst auf einem neuen Pfad. Der alte Pfad bleibt, bis die Umstellung angekündigt und abgeschlossen ist. * Was sich geändert hat, steht im [Änderungsprotokoll](/changelog/). ## So sicherst du dich ab [Abschnitt betitelt „So sicherst du dich ab“](#so-sicherst-du-dich-ab) * **Ignoriere unbekannte Felder** in Antworten. Ein neues Feld darf deine Software nicht zum Absturz bringen. * **Werte `extra.error` aus**, nicht `detail`. Die Meldungstexte können sich ändern, die Codes bleiben. * **Lies Enum-Werte tolerant.** Eine Liste von Statuswerten kann um neue Werte wachsen. Behandle unbekannte Werte als „weiter beobachten“, nicht als Fehler. * **Pinne nichts auf Reihenfolge.** Die Reihenfolge von Feldern in JSON ist nicht festgelegt. # Support > Wie du Hilfe zur Händler-API bekommst und welche Angaben dem Support helfen. Bei Fragen zur API, zur Freischaltung von Berechtigungen oder bei Fehlern wende dich an: **** ## Das hilft uns [Abschnitt betitelt „Das hilft uns“](#das-hilft-uns) Schicke diese Angaben mit, dann können wir den Fall ohne Rückfrage nachvollziehen: * Deine **Kundennummer** und die **Kennung des Schlüssels** (aus dem Portal, nie das Token). * **Methode und Pfad** der Anfrage, zum Beispiel `POST /api/orders`. * **Uhrzeit** mit Zeitzone, zu der der Fehler auftrat. * **Statuscode und Antwortinhalt** (der Inhalt enthält keine Geheimnisse). * Bei Bestellproblemen die **Bestellnummer**. Gefahr Schicke **nie** dein Token, weder per Mail noch in einem Ticket. Hast du es versehentlich geteilt, widerrufe den Schlüssel im Portal und lege einen neuen an. ## Berechtigung fehlt? [Abschnitt betitelt „Berechtigung fehlt?“](#berechtigung-fehlt) Fehlt dir eine Berechtigung, die du für deine Integration brauchst, nenne dem Support den Scope und den Zweck, zum Beispiel „`merchant_order:create`, um Bestellungen aus unserem Shop anzulegen“. Siehe [Scopes und Freischaltung](/guides/scopes/).