Dokumentation zu Schnittstelle und Webhooks
Bauen Sie Anbindungen an NavyFlame: lesen und schreiben Sie Bestellungen, Lager, Rechnungen und Sendungen über eine REST-Schnittstelle und empfangen Sie signierte Webhooks zu Ereignissen nahezu in Echtzeit.
Einführung
Die öffentliche NavyFlame-Schnittstelle ist eine Server-zu-Server-Schnittstelle. Jeden Aufruf autorisieren Sie mit einem Schlüssel, und die Antworten haben eine stabile, versionierte Form. Die Basisadresse liegt auf Ihrer eigenen Kontodomain:
https://{your-slug}.navyflame.com/api/public/v1Die vollständige maschinenlesbare Spezifikation (OpenAPI 3.1) finden Sie unter /openapi-public-v1.yaml und importieren sie in Postman, Insomnia oder einen beliebigen OpenAPI-Client.
Schnellstart
Legen Sie zuerst in der Oberfläche einen Schlüssel an (Konto - API) und prüfen Sie die Verbindung mit GET /me - das verlangt keinen Bereich, ein gültiger Schlüssel genügt. Es liefert Ihren Tarif, Ihre Limits und die Bereiche des Schlüssels.
curl https://{your-slug}.navyflame.com/api/public/v1/me \
-H "Authorization: Bearer nf_live_your_key"Eine Beispielantwort:
{
"tenant": "your-slug",
"keyPrefix": "nf_live_abc123",
"scopes": ["orders:read", "orders:write"],
"plan": "Professional",
"rateLimitPerMin": 3000,
"apiVersion": "v1"
}Anmeldung
Den Schlüssel übergeben Sie im Kopfteil Authorization als Bearer-Token (empfohlen). Für Werkzeuge ohne Bearer-Unterstützung gibt es den Alias X-API-Key:
Authorization: Bearer nf_live_your_key
# or
X-API-Key: nf_live_your_keySchlüssel legen Sie in der Oberfläche an, erneuern und widerrufen sie dort. Wir speichern nur einen Hash des Schlüssels (SHA-256) - den vollen Wert sehen Sie einmal, beim Anlegen. Der Schlüssel wird aus allen Protokollen entfernt. Behandeln Sie ihn wie ein Passwort und legen Sie ihn nie im Browser ab.
Bereiche (Scopes)
Jeder Schlüssel trägt Bereiche. Ein Bereich :write schliesst den passenden :read ein. Fehlt ein nötiger Bereich, kommt 403 missing_scope zurück.
| Bereich | Berechtigt zu |
|---|---|
| orders:read | Bestellungen lesen (Liste, Details, Auswertungen, Statusverlauf). |
| orders:write | Status ändern, Bestellungen anlegen, Rechnungsstellung auslösen. |
| catalog:read | Katalog lesen: Artikel, Lager, Lagerorte, Reservierungen, Lagerdokumente, Bündel. |
| catalog:write | Vollständiger Katalogschreibzugriff: Artikel (anlegen, lesen, ändern, löschen), Bestände und Lagerorte, Lager, Reservierungen, Lagerdokumente, Bündel. |
| invoices:read | Rechnungen und Rechnungsauswertungen lesen. |
| shipments:read | Sendungen und Versandauswertungen lesen, dazu unterstützende Abfragen beim Transporteur (Etiketten-PDF, Abholstellen, Dienste, Aufgabezeiten). |
| shipments:write | Lebenszyklus der Sendung: anlegen, Etikett kaufen (beim Transporteur kostenpflichtig), stornieren, Verfolgung auffrischen, Sendungsnummer an Allegro übergeben. |
| shipping:read | Versandeinrichtung lesen: Regeln, Zonen mit Tarifen, Zustelloptionen, Ausnahmen je Artikel, dazu der Kostenrechner. |
| shipping:write | Versandeinrichtung schreiben: Regeln, Zonen und Tarife je Zone, Zustelloptionen, Versandausnahmen je Artikel. |
| integrations:read | Die Anbindungsliste des Kontos lesen (ohne Geheimnisse): Schlüssel, Kennung der Einrichtung, Name, Zustand von Aktivierung und Verbindung. Gibt nie Zugangsdaten zurück. |
| offers:read | Marktplatzangebote lesen: Zuordnungen Artikel zu Kanal je Artikel, Kategoriezuordnungen und Live-Abfragen bei der Anbindung (Artikel, Kategorien, Merkmale, GPSR-Einheiten). Live-Abfragen sind kostenpflichtig (sie zählen auf das Limit der Anbindung), aber nur lesend. |
| offers:write | Marktplatzangebote schreiben: Kategoriezuordnungen (anlegen, in Mengen, umleiten, löschen, Zwischenspeicher abgleichen) sowie Veröffentlichen, Abgleichen, Abholen, Status auffrischen und Import echter Angebote. Veröffentlichen und Abgleich sind kostenpflichtig (ein echter Aufruf beim Marktplatz). |
| reports:read | Auswertungen zu Verkauf, Artikeln und Vorgängen samt CSV/XLSX-Export. Geschäftlich sensible Daten. |
| analytics:read | KI-Auswertungen: Bestandsprognosen, Preisvorschläge, Auffälligkeiten, Verkaufsprognose, Erkenntnisse. |
| monitoring:read | Überwachung der Anbindungen (Webhooks, Rechnungen, Fehlerliste) und Verbrauch des Kontos. Die Details enthalten personenbezogene Daten. |
| monitoring:write | Einen Eintrag der Fehlerliste erneut verarbeiten - das startet den ursprünglichen Ablauf (bei Rechnungen entsteht eine echte Rechnung; kostenpflichtig). |
| customers:read | Kundschaft (aus Bestellungen zusammengeführt), Auswertungen, Verlauf und CSV-Export. Vollständige personenbezogene Daten. |
| email:read | E-Mail-Vorlagen und -Protokolle. Die Protokolle enthalten Empfangsadressen und Betreffzeilen. |
| email:write | E-Mail-Vorlagen schreiben (Tarifgrenze) und Nachrichten senden (beim Anbieter kostenpflichtig; eigenes Limit von etwa 10 pro Stunde). |
| notifications:read | Benachrichtigungen in der Anwendung und Einstellungen dazu. |
| notifications:write | Benachrichtigungen in der Anwendung anlegen (die empfangende Person muss Mitglied des Kontos sein) und als gelesen markieren. |
| alerts:read | Regeln für Warnungen und der Verlauf ihrer Auslösungen. |
| alerts:write | Regeln für Warnungen schreiben (ein E-Mail-Kanal erzeugt mittelbar Versand). |
| postsale:read | Nachverkaufsbearbeitung: Nachrichten, Streitfälle, Rücksendungen, Ansprüche (nur lesend). Personenbezogene Daten der Käuferschaft. |
| postsale:write | Nachverkaufsschreibzugriff ohne Geldbewegung: Antworten in Verläufen und Streitfällen, Entscheidung in einem Streitfall, Annahme oder Ablehnung einer Rücksendung (je Anbindung von deren Fähigkeiten abhängig). |
| postsale:refunds:write | Ein eigener Geldbereich: echte Rückzahlung an die Käuferschaft und Rückerstattung der Provision. Abgetrennt, damit ein durchgesickerter Schlüssel ohne ihn kein Geld bewegt. |
| templates:read | Beschreibungs- und Artikelvorlagen lesen (mit Varianten). |
| templates:write | Beschreibungs- und Artikelvorlagen schreiben; das Anwenden einer Vorlage legt einen Artikel an (verlangt zusätzlich catalog:write). |
| ai:read | Die KI-Einstellungen und den Verlauf der Inhaltserzeugung lesen. |
| ai:write | Inhalte mit KI erzeugen und übersetzen (bei Ihrem eigenen Anbieter kostenpflichtig). Das Schreiben in einen Artikel verlangt zusätzlich catalog:write. |
Limits je Tarif
Limits gelten je Konto, nicht je Schlüssel. Die Kopfteile X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset in jeder Antwort nennen den Stand des Zeitfensters. Ist das Limit überschritten, erhalten Sie 429 mit dem Kopfteil Retry-After.
| Tarif | Schlüssel | Anfragen | Webhooks |
|---|---|---|---|
| Basic | 5 | 1000 / Min. | 15 |
| Professional | 30 | 3000 / Min. | 50 |
| Enterprise | Ohne Limit | Ohne Limit | Ohne Limit |
Ressourcen und Vorgänge
Lesen (seitenweise Abfrage über Cursor, Filter, Sortierung):
GET /orders GET /orders/{id} GET /orders/stats
GET /orders/{id}/status-history
GET /warehouse-items GET /warehouse-items/{id}
GET /invoices GET /invoices/{id} GET /invoices/stats
GET /shipments GET /shipments/{id} GET /shipments/statsSchreiben:
PUT /orders/{id}/status # change the status (transition matrix)
POST /orders # create an order (source: api)
POST /orders/{id}/invoice # trigger invoicing
PATCH /warehouse-items/{id}/stock # stock correction (set / adjust)Ein Beispiel: die letzten Bestellungen.
curl "https://{your-slug}.navyflame.com/api/public/v1/orders?limit=25" \
-H "Authorization: Bearer nf_live_your_key"Ein Beispiel: den Bestand um 3 Stück verringern (atomar).
curl -X PATCH \
"https://{your-slug}.navyflame.com/api/public/v1/warehouse-items/{id}/stock" \
-H "Authorization: Bearer nf_live_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f9a...-unikat" \
-d '{"operation":"adjust","quantity":-3}'Auswertungen, Berichte und Überwachung
Nur lesende Auswertungsressourcen (die Bereiche reports:read, analytics:read, monitoring:read). Beträge in Berichten und Auswertungen sind Zahlen (Summen), anders als bei den Transaktionsressourcen, wo ein Betrag Text mit zwei Nachkommastellen ist.
GET /reports/sales GET /reports/sales/channels
GET /reports/sales/countries GET /reports/products/bestsellers
GET /reports/products/high-returns GET /reports/products/low-rotation
GET /reports/operations/sla GET /reports/operations/fulfillment
GET /reports/export/csv GET /reports/export/xlsx # binary files
GET /ai-ops/status GET /ai-ops/stock-predictions
GET /ai-ops/price-optimizations GET /ai-ops/anomalies
GET /ai-ops/sales-forecast GET /ai-ops/insights # billable (LLM)
GET /monitoring/webhooks GET /monitoring/webhooks/{id}
GET /monitoring/invoice-links GET /monitoring/dlq
GET /monitoring/dlq/{id} GET /monitoring/stats
GET /usage # counters, storage used, plan limitsDie Exporte /reports/export/csv und /xlsx sind die binäre Ausnahme von JSON - sie liefern eine Datei mit dem Kopfteil Content-Disposition: attachment (CSV in UTF-8 mit BOM, Semikolon als Trenner). Fehler kommen weiterhin als application/problem+json.
Die Details unter /monitoring/webhooks/{id} und /monitoring/dlq/{id} enthalten den rohen Inhalt der Anbindung (personenbezogene Daten der Käuferschaft), der Bereich monitoring:read ist deshalb als sensibel gekennzeichnet. Die Listen dieser Ressourcen geben keinen Inhalt zurück.
Ein Beispiel: eine Verkaufsübersicht der letzten 30 Tage.
curl "https://{your-slug}.navyflame.com/api/public/v1/reports/sales?periodDays=30" \
-H "Authorization: Bearer nf_live_your_key"Kundschaft, E-Mail, Benachrichtigungen und Nachverkaufsbearbeitung
Ressourcen mit personenbezogenen Daten (die Bereiche customers:read, email:read, notifications:read, alerts:read, postsale:read). Nur lesend.
GET /customers GET /customers/{email}
GET /customers/stats GET /customers/{email}/orders
GET /customers/growth GET /customers/export # CSV
GET /email-templates(/{id}) GET /email-logs
GET /notifications(/{id}) GET /notifications/unread-count
GET /notification-preferences # needs ?userId=
GET /alert-rules(/{id}) GET /alert-rules/history
GET /post-sale/capabilities GET /post-sale/inbox
GET /post-sale/conversations(/{id})(/messages)
GET /post-sale/disputes(/{id})(/messages)
GET /post-sale/returns(/{id}) GET /post-sale/refundsEine Kundin oder ein Kunde ist eine gedachte Einheit (aus Bestellungen zusammengeführt), angesprochen über die E-Mail-Adresse. Benachrichtigungen gelten für das ganze Konto (ein Schlüssel steht nicht für eine einzelne Person); das optionale ?userId= grenzt sie auf eine empfangende Person ein, und die Einstellungen verlangen es. Die Nachverkaufsbearbeitung liest nur, was im System gespeichert ist (keine Aufrufe beim Marktplatz auf Ihre Kosten); die Verfügbarkeit sehen Sie unter /post-sale/capabilities.
Die Bereiche customers:read, email:read und postsale:read geben personenbezogene Daten preis - vergeben Sie sie nur an Anbindungen, denen Sie vertrauen, und verarbeiten Sie die Daten im Einklang mit der DSGVO.
Katalog, Vorlagen und KI
Vollständiges Schreiben im Katalog (die Bereiche catalog:read / catalog:write). Anlegende und unumkehrbare Vorgänge verlangen den Kopfteil Idempotency-Key - eine Wiederholung mit demselben Schlüssel gibt das gespeicherte Ergebnis zurück, statt den Vorgang erneut auszuführen.
# Products
POST/PUT/DELETE /warehouse-items(/{id}) POST /warehouse-items/{id}/backorder
GET /warehouse-items/by-barcode GET /warehouse-items/{id}/stock-history
# Warehouses and locations
GET/POST/PUT/DELETE /warehouses(/{id})
GET /warehouse-items/{id}/locations PUT /warehouse-items/{id}/locations/{warehouseId}
GET/PUT /warehouse-settings
# Reservations and stock documents
GET/POST /reservations DELETE /reservations/{id}
GET/POST /stock-documents(/{id}) POST /stock-documents/{id}/lines
POST /stock-documents/{id}/commit POST /stock-documents/{id}/cancel
# Bundles
GET /bundles(/{id}) PUT /bundles/{id} DELETE /bundles/{id}Beschreibungs- und Artikelvorlagen (die Bereiche templates:read / templates:write). Das Anwenden einer Vorlage legt einen Artikel an, deshalb verlangt POST /product-templates/{id}/apply zusätzlich catalog:write.
GET/POST/PUT/DELETE /description-templates(/{id})
GET/POST/PUT/DELETE /product-templates(/{id})
PUT /product-templates/{id}/variants # replace the whole set of variants
POST /product-templates/{id}/variants # add a variant
PATCH/DELETE /product-templates/{id}/variants/{variantId}
POST /product-templates/{id}/apply # + catalog:writeKI-Inhalte (die Bereiche ai:read / ai:write). Erzeugen und Übersetzen sind bei Ihrem eigenen KI-Anbieter kostenpflichtige Vorgänge (den Schlüssel richten Sie unter Anbindungen ein), deshalb ist Idempotency-Key erforderlich - eine Wiederholung gibt das Ergebnis zurück und rechnet es nicht erneut ab. Das Schreiben des Ergebnisses in einen Artikel (applyToProduct / createNewProducts) verlangt zusätzlich catalog:write. Mengenvorgänge geben je Position eine gekürzte Vorschau zurück - den vollen Text holen Sie aus /ai/generation-logs oder aus dem Artikel.
GET/PUT /ai/settings GET /ai/generation-logs
POST /ai/generate-description POST /ai/translate
POST /ai/batch-generate POST /ai/batch-translate # up to 50 items
POST /ai/preview-template # no AI; templates:read + catalog:readEin Beispiel: eine Beschreibungsvorlage anlegen (idempotent).
curl -X POST \
"https://{your-slug}.navyflame.com/api/public/v1/description-templates" \
-H "Authorization: Bearer nf_live_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1e-tpl-001" \
-d '{"name":"Premium description","templateBody":"{{productName}} - {{price}} {{currency}}"}'Versandeinrichtung
Versandeinrichtung (die Bereiche shipping:read / shipping:write): Versandregeln, Zonen mit Tarifen, Zustelloptionen und Ausnahmen je Artikel, dazu der Kostenrechner. Anlegende Vorgänge verlangen den Kopfteil Idempotency-Key. Beträge und Gewicht übergeben Sie beim Schreiben als Zahlen (nicht als Text). Das ist die Einrichtung, nicht die Abwicklung beim Transporteur - das Aufgeben von Sendungen und die Etiketten kommen in einer eigenen Phase.
# Shipping rules
GET/POST/PUT/DELETE /shipping-rules(/{id})
# Zones and rates (a rate belongs to its owning zone)
GET/POST/PUT/DELETE /shipping-zones(/{id})
POST /shipping-zones/{id}/rates PUT/DELETE /shipping-zones/{id}/rates/{rateId}
# Delivery options
GET/POST/PUT/DELETE /delivery-options(/{id})
# Per-product shipping overrides
GET/POST /products/{productId}/shipping-overrides
PUT/DELETE /product-shipping-overrides/{id}
# Cost calculator (a POST, but it only needs shipping:read)
POST /shipping/calculateNamen sind nicht eindeutig, ein Konflikt durch Doppelung (409) entsteht also nicht. Die deliveryOptionId an einem Tarif oder einer Ausnahme muss auf Ihre eigene Zustelloption zeigen (sonst 422), und ein Tarif ausserhalb Ihrer Zone gibt 404. Der Rechner liefert die Optionen aufsteigend nach Kosten sortiert.
Ein Beispiel: die Versandkosten nach Polen berechnen.
curl -X POST \
"https://{your-slug}.navyflame.com/api/public/v1/shipping/calculate" \
-H "Authorization: Bearer nf_live_your_key" \
-H "Content-Type: application/json" \
-d '{"countryCode":"PL","orderValue":199.99,"totalWeightKg":1.5,"itemCount":2}'Sendungen, Etiketten und Transporteur
Lebenszyklus der Sendung (der Bereich shipments:write) und unterstützende Abfragen beim Transporteur (der Bereich shipments:read): Sie legen eine Sendung an, bestellen ein Etikett beim Transporteur, stornieren, frischen die Verfolgung auf und übergeben die Sendungsnummer an Allegro. Gewicht, Masse und Beträge übergeben Sie als Zahlen.
# Creating a shipment (status Draft; costs nothing)
POST /shipments # one at a time
POST /shipments/bulk # in bulk, up to 100 (partial success)
# The carrier label
POST /shipments/{id}/label # BILLABLE - buying a label (Idempotency-Key required)
GET /shipments/{id}/label # fetch the label (PDF, binary)
# The rest of the lifecycle
DELETE /shipments/{id} # delete a draft or cancel with the carrier
POST /shipments/{id}/refresh-tracking
POST /shipments/{id}/push-tracking
# Helper reads (shipments:read)
GET /shipments/points # pickup points (InPost, Poczta Polska, Furgonetka)
GET /couriers/{provider}/services # carrier services (Apaczka, Furgonetka)
GET /shipments/allegro/delivery-services # Allegro Delivery services
POST /shipments/available-dates # pickup dates (DHL; a POST, but shipments:read)Ein Etikett zu bestellen ist kostenpflichtig - es kauft eine echte Sendung beim Transporteur. Deshalb verlangt POST /shipments/{id}/label den Kopfteil Idempotency-Key: eine Wiederholung mit demselben Schlüssel gibt das gespeicherte Ergebnis zurück und kauft nie ein zweites Etikett (der Schutz liegt auf dem Server). Ein Etikett bestellen Sie nur für eine Sendung im Entwurf. Das Herunterladen des Etiketts (GET .../label) ist die binäre Ausnahme - es liefert application/pdf, nicht JSON.
Eine Transporteur- oder Allegro-Anbindung, die nicht verbunden ist, gibt 403 not_supported zurück (nie ein 500), ein Fehler beim Transporteur oder bei Allegro gibt 502 bad_gateway. Unterstützende Abfragen bei einem nicht unterstützten Anbieter geben { "supported": false } zurück statt eines Fehlers. Eine Stornierung ändert den lokalen Status nicht, wenn der Transporteur den Vorgang ablehnt.
Ein Beispiel: ein Etikett bestellen (idempotent, kostenpflichtig).
curl -X POST \
"https://{your-slug}.navyflame.com/api/public/v1/shipments/{id}/label" \
-H "Authorization: Bearer nf_live_your_key" \
-H "Idempotency-Key: 6f9a...-label-001"Anbindungen und Marktplatzangebote
Anbindungen entdecken (der Bereich integrations:read) sowie Lese- und Schreibvorgänge für Marktplatzangebote (die Bereiche offers:read / offers:write). Ein Teil der Vorgänge ist lokal (aus Ihren eigenen Daten, ohne Kosten), ein anderer sind Live-Aufrufe gegen Entgelt bei der Anbindung - unten gekennzeichnet.
Entdecken und lokale Abfragen (ohne Kosten):
GET /connectors # the list of connectors (no secrets)
GET /warehouse-items/{id}/listings # the product's marketplace offers (keyset)
GET /category-mappings # category mappings (keyset)GET /connectors gibt einen streng begrenzten Satz an Feldern zurück - key, configId, displayName, enabled und connected - und gibt nie Zugangsdaten zurück (keine Schlüssel, Tokens oder Passwörter der Anbindung). Das Feld connected ist ein errechneter Zustand: die Anbindung ist aktiviert und hat gespeicherte Zugangsdaten. Den Wert configId übergeben Sie in Kategoriezuordnungen als Filter ?sourceConfigId= oder ?destConfigId=.
Die Angebote eines Artikels (/warehouse-items/{id}/listings) verbinden eine Lagerposition mit einem Angebot im Kanal (die fremde Kennung, Preis und Status auf Seiten des Marktplatzes, eine mögliche Preisausnahme je Kanal). Jedes Angebotsobjekt trägt eine instanceId, also die dauerhafte Kennung einer bestimmten Verbindung, sowie einen instanceName zur Anzeige. So kann derselbe Artikel unabhängige Angebote, Preise und Abgleichszustände etwa auf ebay.de und ebay.com haben. Das Feld lastSyncError wird von Mustern bereinigt, die wie Zugangsdaten aussehen und in einem Fehler der Anbindung stecken könnten.
Ein Beispiel: die Anbindungen des Kontos.
curl "https://{your-slug}.navyflame.com/api/public/v1/connectors" \
-H "Authorization: Bearer nf_live_your_key"Live-Abfragen beim Marktplatz (der Bereich offers:read) führen einen echten Aufruf bei der Anbindung aus - sie sind kostenpflichtig (sie zählen auf das Limit der Anbindung), aber ausschliesslich lesend (sie veröffentlichen und ändern kein Angebot). Eine nicht verbundene Anbindung gibt 403 not_supported zurück (nie 500), ein Fehler auf Seiten des Marktplatzes gibt 502 bad_gateway. Die Form der Daten hängt von der Anbindung ab.
GET /marketplace/{connectorKey}/products
GET /marketplace/{connectorKey}/products/{externalProductId}
GET /marketplace/{connectorKey}/categories?q=fraza
GET /marketplace/{connectorKey}/categories/{categoryId}/parameters
GET /marketplace/{connectorKey}/responsible-producers
GET /marketplace/{connectorKey}/responsible-personsDas Schreiben von Kategoriezuordnungen (der Bereich offers:write) sind lokale Schreibvorgänge - keiner davon veröffentlicht oder ändert ein echtes, für die Käuferschaft sichtbares Angebot (das Veröffentlichen echter Angebote ist unten beschrieben). POST /category-mappings verlangt den Kopfteil Idempotency-Key (eine Doppelung gibt 409); sync frischt den lokalen Zwischenspeicher der Kategorien aus der Anbindung auf (kostenpflichtig, aber idempotent).
POST /category-mappings # create (Idempotency-Key required; a duplicate -> 409)
POST /category-mappings/bulk # in bulk (up to 1000; duplicates skipped)
PUT /category-mappings/{id} # repoint the mapping at another target
DELETE /category-mappings/{id} # delete the mapping
POST /category-mappings/sync # refresh the local category cache (billable, idempotent)Das Veröffentlichen und Abgleichen echter Angebote (der Bereich offers:write) legt ein für die Käuferschaft sichtbares Angebot im Kanal an oder aktualisiert es - kostenpflichtige Vorgänge (ein echter Aufruf beim Marktplatz). publish und sync verlangen den Kopfteil Idempotency-Key (eine Wiederholung mit demselben Schlüssel gibt die gespeicherte Antwort zurück, statt den kostenpflichtigen Aufruf zu wiederholen). publish gibt 409 zurück, wenn der Artikel auf genau dieser Verbindung bereits veröffentlicht ist (oder seine Veröffentlichung läuft) - ein Angebot auf einer anderen Instanz derselben Anbindung erzeugt keinen Konflikt. Nutzen Sie dann sync für dieselbe configId. Eine nicht verbundene Anbindung gibt 403 not_supported, ein Fehler auf Seiten des Marktplatzes gibt 502 bad_gateway.
Übergeben Sie im Inhalt von publish, sync und PUT .../pricing die configId, die Sie von GET /connectors erhalten haben. Hat eine Anbindung mehrere aktivierte Verbindungen, endet ein Weglassen des Feldes mit 422 validation_failed. Die Schnittstelle wählt kein Standardkonto blind aus. Gibt es genau eine aktivierte Verbindung, kann sie diese selbst auflösen.
Wichtig bei einem 502 beim Veröffentlichen: eine Zeitüberschreitung oder ein 5xx des Marktplatzes ist mehrdeutig - das Angebot kann entstanden sein. Eine Wiederholung mit demselben Idempotency-Key gibt dasselbe 502 zurück (sie veröffentlicht nicht erneut). Prüfen Sie das Angebot im Kanal und wiederholen Sie mit einem neuen Idempotency-Key erst, wenn Sie wissen, dass das Angebot nicht entstanden ist.
POST /warehouse-items/{id}/publish/{connectorKey} # publish the offer (billable; Idempotency-Key required)
POST /warehouse-items/{id}/sync/{connectorKey} # update the offer (billable; Idempotency-Key required)
POST /warehouse-items/{id}/pull/{connectorKey} # pull the offer from the channel into the catalogue
POST /warehouse-items/{id}/refresh-status/{connectorKey} # refresh the status of one offer
POST /warehouse-items/refresh-status # in bulk (up to 100 products)
PUT /warehouse-items/{id}/listings/{connectorKey}/pricing # price per instance (local, no outbound call)
# Body for publish / sync:
{ "configId": "8d1ec28d-..." }
# Body for pricing:
{ "configId": "8d1ec28d-...", "mode": "markup", "value": 12.5 }Ein Angebot ins Lager importieren ( POST /catalog/import) legt aus einem Marktplatzartikel eine Lagerposition an. Es verlangt zwei Bereiche zugleich - offers:write und catalog:write (fehlt einer, gibt es 403 missing_scope) - sowie den Kopfteil Idempotency-Key. Eine doppelte Artikelnummer oder ein doppelter Strichcode geben 409 conflict.
POST /catalog/import # import a marketplace product -> a stock item (offers:write + catalog:write)Schreiben: Benachrichtigungen, Warnungen, E-Mail und Nachverkauf
Schreibvorgänge für Kommunikation, erneute Verarbeitung und Nachverkauf (die Bereiche notifications:write, alerts:write, email:write, monitoring:write, postsale:write und postsale:refunds:write). Anlegende und unumkehrbare Vorgänge verlangen den Kopfteil Idempotency-Key; von Natur aus idempotente Vorgänge (als gelesen markieren, umschalten) beachten ihn wahlweise.
# Notifications (notifications:write)
POST /notifications # create (the recipient must be a member of the account; Idempotency-Key required)
POST /notifications/{id}/read # mark one as read
POST /notifications/read-all # mark all (needs ?userId=)
# Alerts (alerts:write)
POST /alert-rules # create a rule (Idempotency-Key required)
PUT/DELETE /alert-rules/{id} # update / delete
POST /alert-rules/{id}/toggle # enable / disable
# E-mail (email:write)
POST/PUT/DELETE /email-templates(/{id}) # templates (plan limit; a duplicate name -> 409)
POST /emails/send # BILLABLE - a real send (Idempotency-Key required)Das Anlegen einer Benachrichtigung prüft, ob recipientUserId Mitglied des Kontos ist (keine Mitgliedschaft gibt 422, eine unsichere Prüfung gibt 503) - ein Schlüssel darf nicht das Postfach einer beliebigen Person fluten. E-Mail-Vorlagen unterliegen der Tarifgrenze (Basic 10, Professional 24, Enterprise ohne Limit) und geben sonst 403 plan_limit, ein doppelter Name gibt 409. Der E-Mail-Versand (`POST /emails/send`) ist kostenpflichtig und hat ein eigenes Limit von etwa 10 pro Stunde je Konto ( 429); ein Anbieter ohne Einrichtung gibt 403 not_supported, ein Übertragungsfehler gibt 502 bad_gateway. Eine Warnregel mit dem Kanal email oder both erzeugt beim Auslösen mittelbar Versand.
Die erneute Verarbeitung der Fehlerliste (der Bereich monitoring:write) startet den ursprünglichen Ablauf eines Eintrags - bei Quellen der Rechnungsstellung entsteht eine echte Rechnung, sie ist also kostenpflichtig und folgenreich, und Idempotency-Key ist erforderlich. Wiederholbar sind nur drei Quellen (shopify_to_wfirma_pipeline, shopify, wfirma_invoice) - andere geben 422; ein nicht erreichbares Temporal gibt 503. Eine Wiederholung ist über eine feste Prozesskennung idempotent (sie gibt alreadyRunning zurück).
POST /monitoring/dlq/{id}/retry # BILLABLE - runs the original process (Idempotency-Key required)Nachverkaufsbearbeitung (der Bereich postsale:write): Sie antworten in Verläufen und Streitfällen, ändern den Status eines Streitfalls und nehmen eine Rücksendung an oder lehnen sie ab. Die Zugehörigkeit von Verlauf, Streitfall oder Rücksendung wird vor dem Aufruf des Kanals geprüft (eine fremde oder nicht vorhandene Kennung gibt 404), und die Vorgänge hängen je Anbindung von deren Fähigkeiten ab - fehlt eine Fähigkeit oder Methode, kommt 403 not_supported (nie 500). Ein Fehler des Kanals gibt 502 bad_gateway.
# Post-sale handling with no movement of money (postsale:write)
POST /post-sale/conversations/{id}/messages # reply to the buyer (Idempotency-Key required)
POST /post-sale/conversations/{id}/read # mark the thread read
POST /post-sale/disputes/{id}/messages # reply in a dispute (Idempotency-Key required)
POST /post-sale/disputes/{id}/status # a decision in a dispute (see money isolation)
POST /post-sale/returns/{id}/accept # accept the return
POST /post-sale/returns/{id}/reject # reject the return
# Refunds - a SEPARATE money scope (postsale:refunds:write)
POST /post-sale/refunds/issue # a REAL refund to the buyer
POST /post-sale/refunds/commission-claim # a commission refundGeld ist abgetrennt. Eine Rückzahlung hat einen eigenen Bereich `postsale:refunds:write`, getrennt von postsale:write, damit ein durchgesickerter Schlüssel ohne ihn kein Geld bewegen kann. Die Route POST /post-sale/disputes/{id}/status gehört zu postsale:write, doch wenn die Entscheidung Geld an die Käuferschaft bewegt (ein vorhandenes partialRefund oder der Status ACCEPTED_REFUND / ACCEPTED_PARTIAL_REFUND), muss der Schlüssel zusätzlich `postsale:refunds:write` tragen - sonst gibt die Anfrage 403 missing_scope zurück und es geschieht nichts.
Rückzahlungen wiederholen. refunds/issue und commission-claim sind auf Seiten des Kanals idempotent (Ihr Idempotency-Key wird zur Kennung des Vorgangs beim Kanal) - wiederholen Sie bei einem 502 mit demselben Schlüssel, der Kanal entfernt die Doppelung. Eine Entscheidung im Streitfall, die Geld bewegt, hat dagegen beim Kanal keine Idempotenz - prüfen Sie bei einem unklaren Fehler das Ergebnis im Verkaufskanal und wiederholen Sie erst mit einem neuen Idempotency-Key (für denselben Schlüssel kommt dasselbe 502 zurück).
Ein Beispiel: eine echte Rückzahlung (idempotent, kostenpflichtig).
curl -X POST \
"https://{your-slug}.navyflame.com/api/public/v1/post-sale/refunds/issue" \
-H "Authorization: Bearer nf_live_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f9a...-refund-001" \
-d '{"connectorKey":"shopify","instanceId":"shop-1","orderExternalId":"1234","amount":49.99,"currency":"PLN"}'Die vollständige Liste der Vorgänge (je Ressource)
Ein vollständiges, begehbares Verzeichnis aller öffentlichen v1-Endpunkte, nach Ressourcen gruppiert. Das ist die Ebene für Menschen - die vollständigen Schemata für Anfragen und Antworten bis auf Feldebene (179 Stück) stehen in der OpenAPI-Spezifikation . Jeder lebende Endpunkt ist hier aufgeführt.
- Bereich - der nötige Bereich des Schlüssels. Ein Bereich
:writeschliesst den passenden:readein. Die Schreibweisea + bheisst bereichsübergreifend (beide zugleich nötig). - Idem. -
K!= der KopfteilIdempotency-Keyist erforderlich;K?= wird beachtet (optional); leer = nicht zutreffend (Lesevorgang). - Fehler - die wichtigen Codes ausser den überall möglichen
401,403und429(sowie500/503, die überall auftreten können).
Meta
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /me | (brak) | - | Prüfung des Schlüssels: Tarif, Limits, Bereiche. Braucht keinen Bereich. | - |
Bestellungen
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /orders | orders:read | - | Bestellungen auflisten (Cursor; Filter nach Status / Quelle / Datum / Suche). | 422 |
POST /orders | orders:write | K! | Eine Bestellung anlegen (source=api); die Beträge rechnet der Server. | 409,413,415,422 |
GET /orders/{id} | orders:read | - | Details der Bestellung. | 404 |
PUT /orders/{id}/status | orders:write | K? | Status ändern (Übergangsmatrix; Rückschreiben an Allegro). | 404,415,422 |
POST /orders/{id}/invoice | orders:write | K! | Rechnungsstellung auslösen (asynchron). | 404,409,422 |
GET /orders/stats | orders:read | - | Auswertung der Bestellungen (Zähler je Status und Erlös aus Paid). | 422 |
GET /orders/{id}/status-history | orders:read | - | Verlauf der echten Statuswechsel einer Bestellung. | 404,422 |
Katalog: Artikel
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /warehouse-items | catalog:read | - | Artikel auflisten (Cursor; Filter nach Status / Artikelnummer / Strichcode). | 422 |
POST /warehouse-items | catalog:write | K! | Einen Lagerartikel anlegen. | 409,413,415,422 |
GET /warehouse-items/{id} | catalog:read | - | Details des Artikels (mit Varianten). | 404 |
PUT /warehouse-items/{id} | catalog:write | K! | Einen Artikel aktualisieren. | 404,409,413,415,422 |
DELETE /warehouse-items/{id} | catalog:write | K! | Einen Artikel archivieren (weiches Löschen). | 404,409,422 |
PATCH /warehouse-items/{id}/stock | catalog:write | K? | Bestand setzen oder korrigieren (set / adjust, atomar). | 404,415,422 |
GET /warehouse-items/by-barcode | catalog:read | - | Einen Artikel oder eine Variante über den Strichcode finden. | 404,422 |
GET /warehouse-items/{id}/stock-history | catalog:read | - | Verlauf der Bestandsänderungen eines Artikels (Cursor). | 404,422 |
POST /warehouse-items/{id}/backorder | catalog:write | K! | Nachbestellung für einen Artikel ein- oder ausschalten. | 404,409,415,422 |
Katalog: Lager und Lagerorte
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /warehouses | catalog:read | - | Lager und Lagerorte auflisten. | - |
POST /warehouses | catalog:write | K! | Ein Lager oder einen Lagerort anlegen. | 409,415,422 |
PUT /warehouses/{id} | catalog:write | K! | Ein Lager aktualisieren. | 404,409,415,422 |
DELETE /warehouses/{id} | catalog:write | K! | Ein Lager löschen. | 404,409,422 |
GET /warehouse-items/{id}/locations | catalog:read | - | Bestand eines Artikels nach Lagerorten aufgeschlüsselt. | 404 |
PUT /warehouse-items/{id}/locations/{warehouseId} | catalog:write | K! | Bestand eines Artikels an einem Lagerort setzen. | 404,409,415,422 |
GET /warehouse-settings | catalog:read | - | Einstellungen der Lagerautomatisierung. | - |
PUT /warehouse-settings | catalog:write | K! | Einstellungen der Lagerautomatisierung ändern. | 409,415,422 |
Katalog: Reservierungen und Lagerdokumente
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /reservations | catalog:read | - | Bestandsreservierungen auflisten (Cursor). | 422 |
POST /reservations | catalog:write | K! | Bestand eines Artikels reservieren. | 404,409,415,422 |
DELETE /reservations/{id} | catalog:write | K! | Eine Reservierung freigeben. | 404,409 |
GET /stock-documents | catalog:read | - | Lagerdokumente auflisten (Cursor). | 422 |
POST /stock-documents | catalog:write | K! | Ein Lagerdokument anlegen (Entwurf). | 409,415,422 |
GET /stock-documents/{id} | catalog:read | - | Details des Dokuments (mit Positionen). | 404 |
POST /stock-documents/{id}/lines | catalog:write | K! | Eine Position zum Dokument hinzufügen. | 404,409,415,422 |
DELETE /stock-documents/{id}/lines/{lineId} | catalog:write | K! | Eine Position aus dem Dokument entfernen. | 404,409,422 |
POST /stock-documents/{id}/commit | catalog:write | K! | Das Dokument bestätigen (Bestand anwenden). | 404,409,422 |
POST /stock-documents/{id}/cancel | catalog:write | K! | Ein Lagerdokument stornieren. | 404,409,422 |
Katalog: Bündel
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /bundles | catalog:read | - | Bündel auflisten (Cursor). | 422 |
GET /bundles/{id} | catalog:read | - | Details des Bündels (Bestandteile und errechneter Bestand). | 404 |
PUT /bundles/{id} | catalog:write | K! | Bestandteile eines Bündels setzen. | 404,409,415,422 |
DELETE /bundles/{id} | catalog:write | K! | Ein Bündel löschen (Bestandteile leeren). | 404,409,422 |
Vorlagen (Beschreibungen und Artikel)
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /description-templates | templates:read | - | Beschreibungsvorlagen auflisten (Cursor). | 422 |
POST /description-templates | templates:write | K! | Eine Beschreibungsvorlage anlegen. | 409,413,415,422 |
GET /description-templates/{id} | templates:read | - | Details der Beschreibungsvorlage. | 404 |
PUT /description-templates/{id} | templates:write | K? | Eine Beschreibungsvorlage aktualisieren. | 404,409,413,415,422 |
DELETE /description-templates/{id} | templates:write | K? | Eine Beschreibungsvorlage löschen. | 404 |
GET /product-templates | templates:read | - | Artikelvorlagen auflisten (Cursor). | 422 |
POST /product-templates | templates:write | K! | Eine Artikelvorlage anlegen. | 409,413,415,422 |
GET /product-templates/{id} | templates:read | - | Details der Artikelvorlage (mit Varianten). | 404 |
PUT /product-templates/{id} | templates:write | K? | Eine Artikelvorlage aktualisieren. | 404,409,413,415,422 |
DELETE /product-templates/{id} | templates:write | K? | Eine Artikelvorlage löschen. | 404 |
PUT /product-templates/{id}/variants | templates:write | K? | Den gesamten Variantensatz einer Vorlage ersetzen (in Mengen). | 404,409,413,415,422 |
POST /product-templates/{id}/variants | templates:write | K! | Eine Variante zur Vorlage hinzufügen. | 404,409,415,422 |
PATCH /product-templates/{id}/variants/{variantId} | templates:write | K? | Eine Variante der Vorlage aktualisieren. | 404,409,415,422 |
DELETE /product-templates/{id}/variants/{variantId} | templates:write | K? | Eine Variante der Vorlage löschen. | 404 |
POST /product-templates/{id}/apply | templates:write + catalog:write | K! | Einen Artikel aus einer Vorlage anlegen (bereichsübergreifend). | 404,409,422 |
KI: Inhalte erzeugen
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /ai/settings | ai:read | - | Globale Einstellungen der KI-Erzeugung. | - |
PUT /ai/settings | ai:write | K? | Globale KI-Einstellungen ändern. | 409,415,422 |
GET /ai/generation-logs | ai:read | - | Verlauf der KI-Aufrufe (Cursor). | 422 |
POST /ai/generate-description | ai:write | K! | Eine Artikelbeschreibung erzeugen (kostenpflichtig). | 404,409,415,422 |
POST /ai/translate | ai:write | K! | Einen Artikel übersetzen (kostenpflichtig). | 404,409,415,422 |
POST /ai/batch-generate | ai:write | K! | Beschreibungen in Mengen erzeugen (kostenpflichtig; höchstens 50). | 409,413,415,422 |
POST /ai/batch-translate | ai:write | K! | In Mengen übersetzen (kostenpflichtig; höchstens 50). | 409,413,415,422 |
POST /ai/preview-template | templates:read + catalog:read | - | Vorschau einer Vorlage mit Artikeldaten (ohne Sprachmodell; bereichsübergreifend). | 404,413,415,422 |
KI-Auswertungen (AI-Ops)
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /ai-ops/status | analytics:read | - | Zustand der KI-Einrichtung und Datenabdeckung. | - |
GET /ai-ops/stock-predictions | analytics:read | - | Prognose, wann der Bestand je Artikelnummer ausgeht (5 Min. zwischengespeichert). | 422 |
GET /ai-ops/price-optimizations | analytics:read | - | Preisvorschläge aus dem Verlauf der Preisänderungen (5 Min. zwischengespeichert). | 422 |
GET /ai-ops/anomalies | analytics:read | - | Auffälligkeiten gegenüber dem gleitenden Mittel (5 Min. zwischengespeichert). | 422 |
GET /ai-ops/sales-forecast | analytics:read | - | Verkaufsprognose (Regression; days = Horizont). | 422 |
GET /ai-ops/insights | analytics:read | - | Erkenntnisse (kostenpflichtig über das Sprachmodell des Kontos; 30 Min. zwischengespeichert; regelbasierter Ersatz). | - |
Rechnungen
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /invoices | invoices:read | - | Rechnungen auflisten (Cursor; issueDate absteigend). | 422 |
GET /invoices/{id} | invoices:read | - | Details der Rechnung (mit Positionen und dem Eintrag bei der Steuerverwaltung). | 404 |
GET /invoices/stats | invoices:read | - | Auswertung der Rechnungen (Kennzahlen über die gesamte Zeit). | - |
Sendungen und Transporteur
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /shipments | shipments:read | - | Sendungen auflisten (Cursor). | 422 |
GET /shipments/{id} | shipments:read | - | Details der Sendung (mit Verfolgungsverlauf). | 404 |
GET /shipments/stats | shipments:read | - | Auswertung der Sendungen (Zähler je Status). | - |
POST /shipments | shipments:write | K! | Eine Sendung anlegen (Status Entwurf; ohne Kosten). | 409,415,422 |
POST /shipments/bulk | shipments:write | K! | Sendungen in Mengen anlegen (höchstens 100, teilweiser Erfolg möglich). | 409,413,415,422 |
POST /shipments/{id}/label | shipments:write | K! | Ein Transporteuretikett bestellen (kostenpflichtig - echte Kosten). | 404,409 |
GET /shipments/{id}/label | shipments:read | - | Das Transporteuretikett herunterladen (PDF, binär). | 404,409,502 |
DELETE /shipments/{id} | shipments:write | K! | Einen nicht versandten Entwurf löschen oder eine Sendung beim Transporteur stornieren. | 404,409,502 |
POST /shipments/{id}/refresh-tracking | shipments:write | K? | Status und Verfolgung beim Transporteur auffrischen. | 404,409,502 |
POST /shipments/{id}/push-tracking | shipments:write | K! | Die Sendungsnummer an die Bestellung im Marktplatz übergeben, aus dem sie stammt (Allegro, TikTok Shop). | 404,400,502 |
POST /shipments/{id}/push-to-allegro | shipments:write | K! | Dasselbe, aber nur für Allegro. Aus Gründen der Abwärtskompatibilität erhalten - nutzen Sie in neuen Anbindungen push-tracking. | 404,409,422,502 |
POST /shipments/available-dates | shipments:read | - | Verfügbare Aufgabetermine (DHL; POST, aber lesend). | 415,422,502 |
GET /shipments/points | shipments:read | - | Abholstellen und Paketautomaten (InPost, Poczta Polska, Furgonetka; der Parameter service grenzt die Treffer von Furgonetka auf den Transporteur des Dienstes ein). | 502 |
GET /couriers/{provider}/services | shipments:read | - | Dienste eines Transporteurs auflisten (Apaczka, Furgonetka). | 502 |
GET /shipments/allegro/delivery-services | shipments:read | - | Dienste von Allegro Delivery auflisten. | 502 |
Versandeinrichtung
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /shipping-rules | shipping:read | - | Versandregeln auflisten (Cursor). | 422 |
POST /shipping-rules | shipping:write | K! | Eine Versandregel anlegen. | 409,415,422 |
GET /shipping-rules/{id} | shipping:read | - | Details der Versandregel. | 404 |
PUT /shipping-rules/{id} | shipping:write | K? | Eine Versandregel aktualisieren. | 404,409,415,422 |
DELETE /shipping-rules/{id} | shipping:write | K? | Eine Versandregel löschen. | 404 |
GET /shipping-zones | shipping:read | - | Versandzonen auflisten (mit eingebetteten Tarifen). | 422 |
POST /shipping-zones | shipping:write | K! | Eine Versandzone anlegen. | 409,415,422 |
GET /shipping-zones/{id} | shipping:read | - | Details der Zone (mit eingebetteten Tarifen). | 404 |
PUT /shipping-zones/{id} | shipping:write | K? | Eine Versandzone aktualisieren. | 404,409,415,422 |
DELETE /shipping-zones/{id} | shipping:write | K? | Eine Versandzone löschen. | 404 |
POST /shipping-zones/{id}/rates | shipping:write | K! | Einen Tarif zur Zone hinzufügen. | 404,409,415,422 |
PUT /shipping-zones/{id}/rates/{rateId} | shipping:write | K? | Einen Tarif in der Zone aktualisieren. | 404,409,415,422 |
DELETE /shipping-zones/{id}/rates/{rateId} | shipping:write | K? | Einen Tarif aus der Zone löschen. | 404 |
GET /delivery-options | shipping:read | - | Zustelloptionen auflisten (Cursor). | 422 |
POST /delivery-options | shipping:write | K! | Eine Zustelloption anlegen. | 409,415,422 |
GET /delivery-options/{id} | shipping:read | - | Details der Zustelloption. | 404 |
PUT /delivery-options/{id} | shipping:write | K? | Eine Zustelloption aktualisieren. | 404,409,415,422 |
DELETE /delivery-options/{id} | shipping:write | K? | Eine Zustelloption löschen. | 404 |
GET /products/{productId}/shipping-overrides | shipping:read | - | Versandausnahmen für einen Artikel (Cursor). | 404,422 |
POST /products/{productId}/shipping-overrides | shipping:write | K! | Eine Versandausnahme für einen Artikel anlegen. | 404,409,415,422 |
PUT /product-shipping-overrides/{id} | shipping:write | K? | Eine Versandausnahme eines Artikels aktualisieren. | 404,409,415,422 |
DELETE /product-shipping-overrides/{id} | shipping:write | K? | Eine Versandausnahme eines Artikels löschen. | 404 |
POST /shipping/calculate | shipping:read | - | Zustelloptionen und Versandkosten berechnen (POST, aber lesend). | 415,422 |
Kundschaft
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /customers | customers:read | - | Kundschaft auflisten (nach E-Mail zusammengeführt; Cursor). | 422 |
GET /customers/stats | customers:read | - | Auswertung der Kundschaft (Kennzahlen). | - |
GET /customers/growth | customers:read | - | Zuwachs der Kundschaft über die Zeit (Monatsreihe). | 422 |
GET /customers/export | customers:read | - | Kundschaft nach CSV exportieren (binär). | 422 |
GET /customers/{email} | customers:read | - | Details zur Kundschaft (Zusammenführung und Adressen). | 404 |
GET /customers/{email}/orders | customers:read | - | Bestellungen einer Person (Cursor). | 404,422 |
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /email-templates | email:read | - | E-Mail-Vorlagen auflisten (Cursor). | 422 |
GET /email-templates/{id} | email:read | - | Details der E-Mail-Vorlage. | 404 |
GET /email-logs | email:read | - | Protokolle gesendeter E-Mails auflisten (Cursor; personenbezogene Daten). | 422 |
POST /email-templates | email:write | K! | Eine E-Mail-Vorlage anlegen (Tarifgrenze). | 409,413,415,422 |
PUT /email-templates/{id} | email:write | K? | Eine E-Mail-Vorlage aktualisieren. | 404,409,413,415,422 |
DELETE /email-templates/{id} | email:write | K? | Eine E-Mail-Vorlage löschen. | 404,409 |
POST /emails/send | email:write | K! | Eine E-Mail senden (kostenpflichtig; etwa 10 pro Stunde). | 409,413,415,422,502 |
Benachrichtigungen
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /notifications | notifications:read | - | Benachrichtigungen des ganzen Kontos auflisten (Cursor; ?userId grenzt ein). | 422 |
GET /notifications/{id} | notifications:read | - | Details der Benachrichtigung. | 404 |
GET /notifications/unread-count | notifications:read | - | Zahl der ungelesenen Benachrichtigungen. | 422 |
GET /notification-preferences | notifications:read | - | Einstellungen zu Benachrichtigungen (verlangt ?userId=). | 422 |
POST /notifications | notifications:write | K! | Eine Benachrichtigung anlegen (die empfangende Person muss Mitglied des Kontos sein). | 413,415,422 |
POST /notifications/{id}/read | notifications:write | K? | Eine Benachrichtigung als gelesen markieren. | 404,409 |
POST /notifications/read-all | notifications:write | K? | Alle als gelesen markieren (verlangt ?userId=). | 409,422 |
Warnungen
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /alert-rules | alerts:read | - | Regeln für Warnungen auflisten (Cursor). | 422 |
GET /alert-rules/history | alerts:read | - | Verlauf der ausgelösten Warnungen (Cursor). | 422 |
GET /alert-rules/{id} | alerts:read | - | Details der Regel für Warnungen. | 404 |
POST /alert-rules | alerts:write | K! | Eine Regel für Warnungen anlegen. | 413,415,422 |
PUT /alert-rules/{id} | alerts:write | K? | Eine Regel für Warnungen aktualisieren. | 404,413,415,422 |
DELETE /alert-rules/{id} | alerts:write | K? | Eine Regel für Warnungen löschen. | 404,409 |
POST /alert-rules/{id}/toggle | alerts:write | K? | Eine Regel für Warnungen ein- oder ausschalten. | 404,409,422 |
Nachverkaufsbearbeitung
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /post-sale/capabilities | postsale:read | - | Übersicht der Nachverkaufsfähigkeiten je Anbindungsinstanz. | - |
GET /post-sale/inbox | postsale:read | - | Gesammelter Posteingang (Zusammenfassung von Verläufen und Streitfällen). | - |
GET /post-sale/conversations | postsale:read | - | Verläufe auflisten (Cursor). | 422 |
GET /post-sale/conversations/{id} | postsale:read | - | Details des Verlaufs. | 404 |
GET /post-sale/conversations/{id}/messages | postsale:read | - | Nachrichten in einem Verlauf (Cursor). | 404,422 |
GET /post-sale/disputes | postsale:read | - | Streitfälle und Reklamationen auflisten (Cursor). | 422 |
GET /post-sale/disputes/{id} | postsale:read | - | Details des Streitfalls. | 404 |
GET /post-sale/disputes/{id}/messages | postsale:read | - | Nachrichten in einem Streitfall (Cursor). | 404,422 |
GET /post-sale/returns | postsale:read | - | Rücksendungen auflisten (Cursor). | 422 |
GET /post-sale/returns/{id} | postsale:read | - | Details der Rücksendung. | 404 |
GET /post-sale/refunds | postsale:read | - | Rückzahlungen auflisten (Cursor). | 422 |
POST /post-sale/conversations/{id}/messages | postsale:write | K! | Der Käuferschaft in einem Verlauf antworten. | 404,413,415,422,502 |
POST /post-sale/conversations/{id}/read | postsale:write | K? | Einen Verlauf als gelesen markieren. | 404,409 |
POST /post-sale/disputes/{id}/messages | postsale:write | K! | In einem Streitfall antworten. | 404,413,415,422,502 |
POST /post-sale/disputes/{id}/status | postsale:write | K! | Status eines Streitfalls ändern (eine Geldbewegung verlangt refunds:write). | 404,413,415,422,502 |
POST /post-sale/returns/{id}/accept | postsale:write | K! | Eine Rücksendung annehmen. | 404,409,502 |
POST /post-sale/returns/{id}/reject | postsale:write | K! | Eine Rücksendung ablehnen. | 404,413,415,422,502 |
Rückzahlungen (ein abgetrennter Geldbereich)
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
POST /post-sale/refunds/issue | postsale:refunds:write | K! | Echte Rückzahlung an die Käuferschaft (je Kanal idempotent). | 413,415,422,502 |
POST /post-sale/refunds/commission-claim | postsale:refunds:write | K! | Eine Rückerstattung der Provision beantragen. | 413,415,422,502 |
Auswertungen
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /reports/sales | reports:read | - | Verkaufsbericht (Zeitreihe, Summen und Marge). | 422 |
GET /reports/sales/channels | reports:read | - | Verkauf nach Kanälen aufgeteilt. | 422 |
GET /reports/sales/countries | reports:read | - | Verkauf nach Ländern aufgeteilt. | 422 |
GET /reports/products/bestsellers | reports:read | - | Meistverkaufte Artikel (Verkauf und Bruttomarge). | 422 |
GET /reports/products/high-returns | reports:read | - | Artikel mit hoher Rücksendequote. | 422 |
GET /reports/products/low-rotation | reports:read | - | Artikel mit geringem Umschlag. | 422 |
GET /reports/operations/sla | reports:read | - | Kennzahlen zur Abwicklungszusage. | 422 |
GET /reports/operations/fulfillment | reports:read | - | Abwicklungsdauer je Kanal. | 422 |
GET /reports/export/csv | reports:read | - | Einen Bericht nach CSV exportieren (binär). | 422 |
GET /reports/export/xlsx | reports:read | - | Einen Bericht nach XLSX exportieren (binär). | 422 |
Überwachung und Verbrauch
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /monitoring/webhooks | monitoring:read | - | Eingehende Webhooks auflisten (ohne Inhalt). | 422 |
GET /monitoring/webhooks/{id} | monitoring:read | - | Details eines Webhooks (roher Inhalt - personenbezogene Daten). | 404 |
GET /monitoring/invoice-links | monitoring:read | - | Verknüpfungen der Rechnungsstellung (Bestellung zu Rechnung). | 422 |
GET /monitoring/dlq | monitoring:read | - | Die Fehlerliste (unzustellbare Vorgänge, ohne Inhalt). | 422 |
GET /monitoring/dlq/{id} | monitoring:read | - | Ein Eintrag der Fehlerliste (ursprünglicher Inhalt - personenbezogene Daten). | 404 |
GET /monitoring/stats | monitoring:read | - | Gesammelte Auswertung der Anbindungen. | - |
GET /usage | monitoring:read | - | Verbrauch des Kontos (Zähler, Speicherplatz, Tariflimits). | - |
POST /monitoring/dlq/{id}/retry | monitoring:write | K! | Einen Eintrag der Fehlerliste wiederholen (kostenpflichtig; startet den ursprünglichen Ablauf). | 404,409,422 |
Anbindungen und Marktplatzangebote
| Vorgang | Bereich | Idem. | Zweck | Fehler |
|---|---|---|---|---|
GET /connectors | integrations:read | - | Die Anbindungen des Kontos auflisten (Projektion ohne Geheimnisse). | - |
GET /warehouse-items/{id}/listings | offers:read | - | Marktplatzangebote eines Artikels, getrennt je Instanz (Cursor). | 404,422 |
GET /category-mappings | offers:read | - | Kategoriezuordnungen auflisten (Cursor). | 422 |
POST /category-mappings | offers:write | K! | Eine Kategoriezuordnung anlegen (lokal). | 409,413,415,422 |
POST /category-mappings/bulk | offers:write | K? | Zuordnungen in Mengen anlegen (höchstens 1000). | 409,413,415,422 |
PUT /category-mappings/{id} | offers:write | K? | Eine Zuordnung auf ein anderes Ziel umleiten. | 404,409,413,415,422 |
DELETE /category-mappings/{id} | offers:write | K? | Eine Kategoriezuordnung löschen. | 404,409 |
POST /category-mappings/sync | offers:write | K? | Den lokalen Zwischenspeicher der Kategorien auffrischen (kostenpflichtig). | 409,413,415,422,502 |
GET /marketplace/{connectorKey}/products | offers:read | - | Eine Live-Liste der Artikel aus der Anbindung (kostenpflichtig). | 422,502 |
GET /marketplace/{connectorKey}/products/{externalProductId} | offers:read | - | Ein einzelner Artikel live aus der Anbindung (kostenpflichtig). | 502 |
GET /marketplace/{connectorKey}/categories | offers:read | - | Eine Live-Suche in den Kategorien der Anbindung (kostenpflichtig). | 502 |
GET /marketplace/{connectorKey}/categories/{categoryId}/parameters | offers:read | - | Live-Merkmale einer Kategorie (kostenpflichtig). | 502 |
GET /marketplace/{connectorKey}/responsible-producers | offers:read | - | Eine Live-Liste der GPSR-Herstellerfirmen (kostenpflichtig). | 502 |
GET /marketplace/{connectorKey}/responsible-persons | offers:read | - | Eine Live-Liste der GPSR-Verantwortlichen (kostenpflichtig). | 502 |
POST /warehouse-items/{id}/publish/{connectorKey} | offers:write | K! | Ein Angebot auf der über configId genannten Instanz veröffentlichen (kostenpflichtig, echtes Angebot). | 404,409,413,415,422,502 |
POST /warehouse-items/{id}/sync/{connectorKey} | offers:write | K! | Ein Angebot auf der über configId genannten Instanz aktualisieren (kostenpflichtig). | 404,409,413,415,422,502 |
POST /warehouse-items/{id}/pull/{connectorKey} | offers:write | K? | Ein Angebot aus der Anbindung in den Katalog holen (kostenpflichtig). | 404,409,502 |
POST /warehouse-items/{id}/refresh-status/{connectorKey} | offers:write | K? | Den Status eines Angebots auffrischen (kostenpflichtig). | 404,409,502 |
POST /warehouse-items/refresh-status | offers:write | K? | Den Status von Angeboten in Mengen auffrischen (höchstens 100). | 409,413,415,422 |
PUT /warehouse-items/{id}/listings/{connectorKey}/pricing | offers:write | K? | Den Preis für eine bestimmte Instanz aus configId setzen (lokal, ohne Aufruf). | 404,409,413,415,422 |
POST /catalog/import | offers:write + catalog:write | K! | Einen Marktplatzartikel ins Lager importieren (bereichsübergreifend). | 409,413,415,422 |
Seitenweise Abfrage und Filter
Listen geben wir seitenweise über Cursor aus (ohne Offset). Die Antwort trägt pagination.nextCursor - übergeben Sie ihn im Parameter cursor, um die nächste Seite zu holen. Der Parameter updatedSince (ein Zeitpunkt nach ISO mit Zone) liefert Datensätze, die seit diesem Moment geändert wurden. Fragen Sie für einen abholenden Abgleich mit überlappendem Fenster ab und entfernen Sie Doppel über die id.
GET /orders?limit=50&cursor=eyJjIjoi...&updatedSince=2026-07-01T00:00:00ZIdempotenz
Schreibvorgänge schützt der Kopfteil Idempotency-Key (ein beliebiger eindeutiger Wert, empfohlen ist eine UUID, bis 255 Zeichen). Er ist bei POST /orders und POST /orders/{id}/invoice erforderlich und wird bei PUT und PATCH beachtet.
- Eine Wiederholung mit demselben Schlüssel und demselben Inhalt gibt das gespeicherte Ergebnis zurück (Kopfteil
Idempotency-Replayed: true), ohne doppelte Wirkung. - Derselbe Schlüssel mit anderem Inhalt gibt
409 idempotency_conflictzurück. - Ein gleichzeitiges Duplikat in Bearbeitung gibt
409 idempotency_in_progressmitRetry-Afterzurück. - Schlüssel laufen nach 24 Stunden ab.
Beispiele im Code
Fertige Ausschnitte in drei Varianten: curl, JavaScript (fetch, Node 20+) und Python (die Bibliothek requests). Die Varianten für JS und Python setzen die Konstanten BASE (Basisadresse) und KEY (der Schlüssel aus einem sicheren Speicher) voraus, gesetzt im Beispiel zur Anmeldung.
Anmeldung (Bearer und X-API-Key)
curl
# Bearer (recommended)
curl https://{your-slug}.navyflame.com/api/public/v1/me \
-H "Authorization: Bearer nf_live_your_key"
# The X-API-Key alias (tools without Bearer support)
curl https://{your-slug}.navyflame.com/api/public/v1/me \
-H "X-API-Key: nf_live_your_key"JavaScript
const BASE = "https://my-shop.navyflame.com/api/public/v1";
const KEY = process.env.NAVYFLAME_API_KEY;
const res = await fetch(BASE + "/me", {
headers: { Authorization: "Bearer " + KEY },
});
if (!res.ok) throw new Error("HTTP " + res.status);
const me = await res.json();
console.log(me.plan, me.scopes);Python
import os, requests
BASE = "https://my-shop.navyflame.com/api/public/v1"
KEY = os.environ["NAVYFLAME_API_KEY"]
r = requests.get(BASE + "/me", headers={"Authorization": "Bearer " + KEY})
r.raise_for_status()
me = r.json()
print(me["plan"], me["scopes"])Seitenweise Abfrage über Cursor (Schleife und Entdopplung)
curl
curl "https://{your-slug}.navyflame.com/api/public/v1/orders?limit=100&updatedSince=2026-07-01T00:00:00Z" \
-H "Authorization: Bearer nf_live_your_key"
# the response carries pagination.nextCursor -> pass it as &cursor=... on the next callJavaScript
async function* paginate(path) {
let cursor = null;
do {
const url = new URL(BASE + path);
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: "Bearer " + KEY },
});
if (res.status === 429) {
const wait = Number(res.headers.get("Retry-After") || 1);
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
if (!res.ok) throw new Error("HTTP " + res.status);
const page = await res.json();
for (const row of page.data) yield row;
cursor = page.pagination.nextCursor;
} while (cursor);
}
const seen = new Set();
for await (const order of paginate("/orders?updatedSince=2026-07-01T00:00:00Z")) {
if (seen.has(order.id)) continue; // deduplicate by id
seen.add(order.id);
// ... process the order
}Python
import time
def paginate(path, params=None):
params = dict(params or {})
params["limit"] = 100
while True:
r = requests.get(BASE + path, params=params,
headers={"Authorization": "Bearer " + KEY})
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", "1")))
continue
r.raise_for_status()
page = r.json()
for row in page["data"]:
yield row
cursor = page["pagination"]["nextCursor"]
if not cursor:
break
params["cursor"] = cursor
seen = set()
for order in paginate("/orders", {"updatedSince": "2026-07-01T00:00:00Z"}):
if order["id"] in seen: # deduplicate by id
continue
seen.add(order["id"])
# ... process the orderEin idempotenter Schreibvorgang (Idempotency-Key und wachsende Abstände)
curl
curl -X POST "https://{your-slug}.navyflame.com/api/public/v1/orders" \
-H "Authorization: Bearer nf_live_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1c9a20-7b2e-4c6d-9f10-000000000001" \
-d '{"customer":{"name":"Jan Kowalski"},"lineItems":[{"title":"Kubek 300 ml","sku":"KUB-300-BIA","quantity":2,"unitPrice":"39.99","taxRate":"23"}],"currency":"PLN"}'JavaScript
import { randomUUID } from "node:crypto";
async function createOrder(body) {
const key = randomUUID(); // the same key on every retry
for (let attempt = 0; attempt < 5; attempt++) {
const res = await fetch(BASE + "/orders", {
method: "POST",
headers: {
Authorization: "Bearer " + KEY,
"Content-Type": "application/json",
"Idempotency-Key": key,
},
body: JSON.stringify(body),
});
if (res.status === 429 || res.status === 502 || res.status === 503) {
const wait = Number(res.headers.get("Retry-After") || 2 ** attempt);
await new Promise((r) => setTimeout(r, wait * 1000));
continue; // transient - retry with the same key
}
if (res.status === 409) {
const problem = await res.json();
if (problem.code === "idempotency_in_progress") {
await new Promise((r) => setTimeout(r, 1000));
continue;
}
throw new Error("idempotency conflict: " + problem.code); // a different body
}
if (!res.ok) throw new Error("HTTP " + res.status);
return res.json(); // 201 or replayed (Idempotency-Replayed: true)
}
throw new Error("wyczerpano proby ponowienia");
}Python
import time
from uuid import uuid4
def create_order(body):
key = str(uuid4()) # the same key on every retry
for attempt in range(5):
r = requests.post(BASE + "/orders", json=body, headers={
"Authorization": "Bearer " + KEY,
"Idempotency-Key": key,
})
if r.status_code in (429, 502, 503):
time.sleep(int(r.headers.get("Retry-After", 2 ** attempt)))
continue # transient - retry with the same key
if r.status_code == 409:
code = r.json().get("code")
if code == "idempotency_in_progress":
time.sleep(int(r.headers.get("Retry-After", "1")))
continue
raise RuntimeError("idempotency conflict: " + str(code))
r.raise_for_status()
return r.json() # 201 or replayed
raise RuntimeError("wyczerpano proby ponowienia")Die Prüfung der Webhook-Signatur (JavaScript und Python) finden Sie im Abschnitt Ausgehende Webhooks .
Format der Fehler
Fehler geben wir nach RFC 9457 zurück (application/problem+json). Jeder trägt einen stabilen code und eine requestId zur Zuordnung beim Support.
{
"type": "https://navyflame.com/dokumentacja/api/bledy#validation_failed",
"title": "Validation failed",
"status": 422,
"detail": "Invalid order input.",
"code": "validation_failed",
"requestId": "req_abc123",
"errors": [{ "field": "lineItems[0].unitPrice", "message": "Kwota >= 0 (jako string)." }]
}| Code | HTTP | Wann | Was zu tun ist |
|---|---|---|---|
| unauthorized | 401 | Ein fehlender, ungültiger, abgelaufener oder widerrufener Schlüssel. | Prüfen Sie den Kopfteil Authorization / X-API-Key. Wurde der Schlüssel widerrufen oder ist er abgelaufen, legen Sie in der Oberfläche einen neuen an. |
| missing_scope | 403 | Dem Schlüssel fehlt ein nötiger Bereich (etwa orders:write), auch wenn ein Vorgang zwei Bereiche verlangt. | Vergeben Sie den fehlenden Bereich, indem Sie den Schlüssel mit dem vollständigen Satz erneuern. Die Bereiche eines bestehenden Schlüssels lassen sich nicht nachträglich ändern. |
| plan_limit | 403 | Der Tarif enthält die Schnittstelle nicht, das Tariflimit ist erschöpft, oder das Abo ist abgelaufen oder gekündigt. | Verlängern oder erweitern Sie den Tarif. Die Schnittstelle kehrt nach der Freischaltung von selbst zurück (das Limit wird in etwa 5 Minuten verteilt). |
| not_supported | 403 | Der Vorgang braucht eine Transporteur- oder Marktplatzanbindung, die nicht verbunden ist (Fähigkeitsprüfung; nie ein 500). | Verbinden und aktivieren Sie die richtige Anbindung in der Oberfläche (Anbindungen). Die Verfügbarkeit sehen Sie unter /post-sale/capabilities oder /connectors. |
| not_found | 404 | Die Ressource gibt es in Ihrem Konto nicht (oder sie gehört einem anderen Konto, was ununterscheidbar bleibt, als Schutz vor Zugriff über fremde Kennungen). | Prüfen Sie die Kennung. Eine fremde Kennung sieht immer aus wie eine nicht vorhandene. |
| conflict | 409 | Ein Zustandskonflikt der Ressource: das Angebot ist bereits veröffentlicht, eine doppelte Artikelnummer, ein doppelter Strichcode oder Name, kein Bestand, oder ein Dokument nicht im Entwurf. | Lösen Sie den Konflikt: nutzen Sie beim Veröffentlichen sync statt publish; ändern Sie Artikelnummer oder Namen; prüfen Sie den Status der Ressource. |
| idempotency_conflict | 409 | Derselbe Idempotency-Key mit einem anderen Anfrageinhalt verwendet. | Nutzen Sie für einen neuen Inhalt einen neuen Idempotency-Key. Derselbe Schlüssel muss denselben Inhalt tragen. |
| idempotency_in_progress | 409 | Eine Anfrage mit diesem Schlüssel wird gerade verarbeitet (ein gleichzeitiges Duplikat). | Warten Sie gemäss dem Kopfteil Retry-After und wiederholen Sie mit demselben Schlüssel. |
| payload_too_large | 413 | Der Anfrageinhalt überschreitet 2 MB. | Verkleinern Sie den Inhalt (etwa kleinere Mengen bei Massenvorgängen). |
| unsupported_media_type | 415 | Ein Schreibvorgang ohne den Kopfteil Content-Type: application/json. | Setzen Sie bei Schreibvorgängen Content-Type: application/json. |
| validation_failed | 422 | Fehlerhafte Eingabe: ein falscher Wert, ein unzulässiger Statuswechsel, ein falscher Cursor, ein Zeitpunkt ohne Zeitzone. | Korrigieren Sie die Daten gemäss dem Feld errors in der Antwort (Feld und Meldung). |
| rate_limited | 429 | Ein Limit wurde überschritten (Tariflimit je Konto, je IP-Adresse, gleichzeitige Anfragen oder das eigene Limit für E-Mail-Versand). | Drosseln Sie das Tempo, beachten Sie Retry-After und warten Sie exponentiell länger. Prüfen Sie die Kopfteile X-RateLimit-*. |
| internal | 500 | Ein Fehler auf Seiten von NavyFlame. | Wiederholen Sie mit wachsendem Abstand. Tritt er wiederholt auf, melden Sie die requestId dem Support. |
| bad_gateway | 502 | Ein Fehler bei einem fremden Dienst (Transporteur, Allegro oder ein anderer Marktplatz) - als vorübergehend behandeln. | Wiederholen Sie mit wachsendem Abstand. Bei einem Schreibvorgang mit demselben Idempotency-Key (der Kanal entfernt Doppel). Siehe die Hinweise zu Veröffentlichung und Rückzahlungen. |
| service_unavailable | 503 | Ein Neustart, eine Auslieferung oder eine noch nicht fertige Einrichtung (laufende Auslieferungen). | Wiederholen Sie mit wachsendem Abstand, dieser Zustand ist vorübergehend. |
Die Codes 500 (internal) und 503 (service_unavailable) können bei jedem Vorgang auftreten und werden nicht je Endpunkt aufgeführt. Auslieferungen laufen fortlaufend - ein Client sollte vereinzelte 502/503 als vorübergehend behandeln (Wiederholung mit wachsendem Abstand) und Schreibvorgänge mit einem Idempotency-Key absichern. Das Feld type in problem+json zeigt auf den Anker dieses Abschnitts (etwa #validation_failed).
Ausgehende Webhooks
Sie abonnieren ein Ereignis und geben eine HTTPS-Adresse an, dann senden wir dorthin eine signierte Benachrichtigung. Die Ereignisse in v1 sind order.synced, order.status_changed, invoice.issued, shipment.status_updated und catalog.updated. Jede Zustellung trägt die Kopfteile X-NavyFlame-Event, X-NavyFlame-Delivery-Id und X-NavyFlame-Signature. Erfolg ist eine 2xx-Antwort innerhalb von 5 Sekunden; bei einem Fehlschlag wiederholen wir mit wachsendem Abstand etwa 24 Stunden lang, und den Zustellverlauf sehen Sie in der Oberfläche.
Die Form des Inhalts (der gemeinsame Rahmen):
{
"id": "evt_9f4c2f6a-...",
"type": "order.synced",
"apiVersion": "v1",
"occurredAt": "2026-07-07T12:00:00Z",
"tenant": "your-slug",
"origin": { "channel": "api", "apiKeyPrefix": "nf_live_abc123" },
"data": { "order": { }, "isNew": true }
}Das Feld origin.channel (api | panel | sync | automation) erlaubt es, eine Rückkopplung zu unterbrechen - haben Sie die Änderung selbst mit einem Schlüssel ausgelöst, erkennen Sie das an apiKeyPrefix und überspringen das Ereignis. Die empfangende Seite entfernt Doppel über die id des Ereignisses und über den Kopfteil X-NavyFlame-Delivery-Id (Zustellung mindestens einmal, ohne Zusage zur Reihenfolge).
Der Ereigniskatalog (v1)
Eine geschlossene Liste der Ereignisse in v1 - neue Typen sind eine ergänzende Änderung, die empfangende Seite muss also unbekannte Felder und Typen übergehen. Jedes Ereignis trägt den gemeinsamen Rahmen (oben); der typspezifische Inhalt steht im Feld data:
order.synced - Nach dem Speichern einer Bestellung, nur bei einer echten Datenänderung (neue Bestellung oder Statuswechsel). Das Feld isNew unterscheidet neu von aktualisiert.
{
"id": "evt_9f4c2f6a-1b2c-4d3e-8a9b-000000000001",
"type": "order.synced",
"apiVersion": "v1",
"occurredAt": "2026-07-09T12:00:00Z",
"tenant": "my-shop",
"origin": { "channel": "sync" },
"data": {
"order": { "id": "0e6b7c...", "orderNumber": "2026/07/000123",
"status": "Processing", "totalPrice": "129.99", "currency": "PLN" },
"isNew": false
}
}order.status_changed - Nach dem bestätigten Speichern einer echten Statusänderung, unabhängig von der Quelle. Denselben Status erneut zu setzen und ein abgelehnter Wechsel senden kein Ereignis. Das Feld order enthält den Zustand nach dem Speichern, previousStatus den Status davor, und origin nennt die Quelle der Änderung.
{
"id": "evt_2b3c4d5e-6f70-4a8b-9c0d-000000000005",
"type": "order.status_changed",
"apiVersion": "v1",
"occurredAt": "2026-08-30T10:30:00Z",
"tenant": "my-shop",
"origin": { "channel": "api", "apiKeyPrefix": "nf_live_abc123" },
"data": {
"order": { "id": "0e6b7c...", "orderNumber": "2026/08/000321",
"status": "Processing", "totalPrice": "129.99", "currency": "PLN" },
"previousStatus": "New"
}
}invoice.issued - Nachdem im Buchhaltungssystem des Kontos eine Rechnung ausgestellt wurde.
{
"id": "evt_1a2b3c4d-5e6f-4a7b-8c9d-000000000002",
"type": "invoice.issued",
"apiVersion": "v1",
"occurredAt": "2026-07-09T12:03:00Z",
"tenant": "my-shop",
"origin": { "channel": "automation" },
"data": {
"invoice": { "id": "7a1c9e...", "number": "FV/2026/07/45",
"status": "Issued", "grossAmount": "129.99", "currency": "PLN" }
}
}shipment.status_updated - Nachdem sich der Status einer Sendung beim Transporteur geändert hat. Das Feld previousStatus trägt den vorherigen Status (oder null).
{
"id": "evt_2b3c4d5e-6f7a-4b8c-9d0e-000000000003",
"type": "shipment.status_updated",
"apiVersion": "v1",
"occurredAt": "2026-07-09T12:10:00Z",
"tenant": "my-shop",
"origin": { "channel": "sync" },
"data": {
"shipment": { "id": "b2d9f1...", "courierProvider": "inpost",
"status": "InTransit", "trackingNumber": "6800000000001" },
"previousStatus": "PickedUp"
}
}catalog.updated - Nachdem sich ein Artikel oder ein Bestand geändert hat. Einzelne Änderungen je Position; ausdrücklich massenhafte Vorgänge (Import aus dem Grosshandel, Mengenaufruf) als ein gesammeltes Ereignis (bulk: true).
{
"id": "evt_3c4d5e6f-7a8b-4c9d-0e1f-000000000004",
"type": "catalog.updated",
"apiVersion": "v1",
"occurredAt": "2026-07-09T12:15:00Z",
"tenant": "my-shop",
"origin": { "channel": "api", "apiKeyPrefix": "nf_live_abc123" },
"data": {
"warehouseItemId": "c4e1a2...", "sku": "KUB-300-BIA",
"changeType": "updated", "stockQuantity": 42
}
}
// The bulk variant (data):
// { "bulk": true, "source": "wholesale-import", "itemsChanged": 128 }Prüfung der Signatur
Der Kopfteil X-NavyFlame-Signature hat die Form t=<unix>,v1=<hex>, wobei v1 = HMAC-SHA256(Geheimnis, "<t>." + roher_Inhalt). Der Kopfteil kann mehrere Paare v1= tragen (ein Zeitfenster für den Wechsel des Geheimnisses - altes und neues Geheimnis signieren 24 h parallel) - nehmen Sie jedes an, das passt. Prüfen Sie, ob der Zeitstempel stimmt (Toleranz 300 s), um sich gegen eine Wiedereinspielung zu schützen.
JavaScript (Node)
import crypto from "node:crypto";
function verify(signatureHeader, rawBody, secret) {
const parts = Object.create(null);
const sigs = [];
for (const p of String(signatureHeader).split(",")) {
const [k, v] = p.split("=");
if (k === "t") parts.t = v;
if (k === "v1" && v) sigs.push(v);
}
if (!parts.t || sigs.length === 0) return false;
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const computed = crypto
.createHmac("sha256", secret)
.update(parts.t + "." + rawBody)
.digest("hex");
return sigs.some(
(s) =>
s.length === computed.length &&
crypto.timingSafeEqual(
Buffer.from(computed, "hex"),
Buffer.from(s, "hex"),
),
);
}Python
import hashlib, hmac, time
def verify(signature_header, raw_body, secret):
t = None
sigs = []
for part in signature_header.split(","):
k, _, v = part.partition("=")
if k == "t":
t = v
elif k == "v1" and v:
sigs.append(v)
if not t or not sigs:
return False
if abs(time.time() - int(t)) > 300: # replay protection
return False
computed = hmac.new(
secret.encode(), (t + "." + raw_body).encode(), hashlib.sha256
).hexdigest()
return any(hmac.compare_digest(computed, s) for s in sigs)Prüfen Sie die Signatur gegen den rohen Anfrageinhalt (die Bytes vor dem Auswerten des JSON) - ein erneutes Serialisieren ändert die Bytes und die Signatur passt nicht mehr. raw_body / rawBody sind genau die im POST-Inhalt empfangenen Bytes, vor dem Dekodieren des JSON.
Ein Rezept für Zapier und Make
- Legen Sie in Zapier einen Zap mit dem Auslöser Webhooks by Zapier - Catch Hook an (in Make: das Modul Custom Webhook). Kopieren Sie die erzeugte Adresse.
- Fügen Sie in der NavyFlame-Oberfläche (Konto - API - Webhooks) ein Abonnement hinzu: wählen Sie das Ereignis und fügen Sie die Adresse als Ziel ein. Das Signaturgeheimnis sehen Sie einmal, bewahren Sie es auf.
- Nutzen Sie die Schaltfläche Test senden in der Oberfläche, um zu bestätigen, dass Ihr Ablauf den Inhalt empfängt.
- (Empfohlen) Fügen Sie mit der obigen Funktion einen Schritt zur Signaturprüfung ein, bevor Sie den Daten vertrauen.
DSGVO
Die Inhalte der Webhooks tragen personenbezogene Daten der Käuferschaft. Wenn Sie ein Abonnement einrichten (die Zieladresse wählen, etwa Zapier, meist eine Übermittlung ausserhalb des EWR), handeln Sie als verantwortliche Stelle für diese Daten, und das Abonnement ist Ihre dokumentierte Weisung zur Verarbeitung. Die Löschung oder Anonymisierung von Käuferdaten in Systeme weiterzugeben, die über Schnittstelle und Webhooks gespeist werden, liegt bei Ihnen.
Anleitungen
Schnellstart (vom Schlüssel zum ersten Aufruf)
- Legen Sie in der Oberfläche (Konto - API) einen Schlüssel mit den nötigen Bereichen an. Den Schlüssel sehen Sie nur einmal, bewahren Sie ihn in einem sicheren Speicher auf.
- Bestätigen Sie die Verbindung:
GET /me(braucht keinen Bereich). Es liefert Tarif, Limits und die Bereiche des Schlüssels. - Machen Sie den ersten Aufruf gegen die gewünschte Ressource, etwa
GET /orders?limit=25.
Abholender Abgleich (updatedSince, überlappendes Fenster und Entdopplung)
- Fragen Sie mit
updatedSince = letzter_Abgleich - Überlappungsfensterab (etwa 5 Minuten). Die Bedeutung ist einschliessend (>=), auf die Millisekunde genau. - Blättern Sie über den Cursor, bis
pagination.nextCursorgleichnullist. - Entdoppeln Sie über die
id->=allein schützt nicht vor einem Datensatz, dessen Transaktion nach Ihrem Lesen bestätigt wurde (daher das überlappende Fenster). - Merken Sie sich das höchste
updatedAtder Seite als Startpunkt des nächsten Durchlaufs. - Führen Sie nach einer Wiederherstellung des Kontos aus einer Sicherung einen vollständigen Neuabgleich durch - verlassen Sie sich nicht auf
updatedSince(und legen Sie neue Schlüssel an).
Zapier und Make (ein Webhook in eine Aktion)
- Legen Sie in Zapier den Auslöser Webhooks by Zapier - Catch Hook an (in Make: Custom Webhook) und kopieren Sie die erzeugte Adresse.
- Fügen Sie in der Oberfläche (Konto - API - Webhooks) ein Abonnement hinzu: Ereignis wählen, Adresse als Ziel einfügen, das Geheimnis sichern (wird einmal gezeigt).
- Klicken Sie in der Oberfläche auf Test senden, um den Empfang des Inhalts zu bestätigen.
- Fügen Sie einen Schritt zur Signaturprüfung ein (siehe den Abschnitt Webhooks), bevor Sie den Daten vertrauen.
- Nutzen Sie für Rückrufe an die Schnittstelle das Modul HTTP / Custom Request mit dem Kopfteil
Authorization: Bearer.
Schlüssel und Webhook-Geheimnis wechseln (Fenster von 24 Std.)
- Schlüssel: ein Wechsel in der Oberfläche gibt einmalig ein neues Token aus; das alte gilt noch 24 Std. (ohne Ausfall) - tauschen Sie es in diesem Fenster in Ihrer Anbindung. Ein Widerruf wirkt sofort.
- Webhook-Geheimnis: der Wechsel hat ein Überlappungsfenster - altes und neues Geheimnis signieren 24 Std. parallel. Der Signatur-Kopfteil kann mehrere Paare
v1=tragen, sodass der Wechsel keine brechende Änderung ist, wenn Sie jedes passende annehmen. - Nach einer Wiederherstellung aus einer Sicherung werden die Schlüssel automatisch widerrufen - legen Sie neue an und gleichen Sie vollständig neu ab.
Mit Limits umgehen (Retry-After und wachsende Abstände)
- Lesen Sie das Tariflimit aus
GET /me(rateLimitPerMin) oderGET /usage. Limits gelten je Konto, nicht je Schlüssel. - Jede Antwort trägt
X-RateLimit-Limit,X-RateLimit-RemainingundX-RateLimit-Reset- steuern Sie Ihr Tempo laufend. - Beachten Sie bei
429dasRetry-After(Sekunden) und warten Sie exponentiell länger. Halten Sie die Gleichzeitigkeit unter dem Limit laufender Anfragen (20 parallele Anfragen je Konto). - Bei Enterprise ist das Minutenlimit abgeschaltet; der Schutz gegen Fluten je IP-Adresse und die Obergrenze der Gleichzeitigkeit gelten immer (Schutz der Infrastruktur, keine Tarifeigenschaft).
Versionierung und Änderungen
Die Version steht im Pfad (/api/public/v1). Ergänzende Änderungen (neue Felder, neue Endpunkte, neue Ereignistypen) brechen die Verträglichkeit nicht - Ihr Client muss unbekannte Felder übergehen. Brechende Änderungen kündigen wir vorher an: ein Eintrag im Änderungsverlauf, eine E-Mail an die Inhaberschaft aktiver Schlüssel sowie die Kopfteile Deprecation und Sunset.
Änderungsverlauf
Der Versionsverlauf von v1 (die Versionsnummer ist die jeweils nächste Ausbaustufe). Alle Änderungen sind ergänzend - wir haben keinen Endpunkt und kein Feld entfernt und die Bedeutung keines davon geändert. Aktuelle Fassung der OpenAPI-Spezifikation: v1.10.0.
| Fassung | Phase | Was hinzukam (ergänzend) |
|---|---|---|
| v1.0 | GA | Der Kern der Schnittstelle: /me, Bestellungen (lesen, schreiben und Rechnungsstellung), Lager (lesen und Bestand ändern), Rechnungen (lesen), Sendungen (lesen). Webhooks: order.synced, invoice.issued, shipment.status_updated, catalog.updated. Seitenweise Abfrage über Cursor, Idempotenz, Fehler nach RFC 9457. |
| v1.1 | Phase A | Nur lesende Auswertungen: Berichte zu Verkauf, Artikeln und Vorgängen (samt CSV/XLSX-Export), AI-Ops, Überwachung, Verbrauch sowie Auswertungen und Statusverlauf der Bestellungen. |
| v1.2 | Phase B | Nur lesende personenbezogene Daten: Kundschaft, E-Mail-Vorlagen und -Protokolle, Benachrichtigungen und Einstellungen, Regeln für Warnungen, Nachverkaufsbearbeitung. |
| v1.3 | Phase C | Schreiben im Katalog: Artikel (anlegen, lesen, ändern, löschen), Lager und Lagerorte, Reservierungen, Lagerdokumente, Bündel, Vorlagen (Beschreibungen und Artikel) sowie KI-Inhalte (kostenpflichtig). |
| v1.4 | Phase D1 | Schreiben der Versandeinrichtung: Regeln, Zonen mit Tarifen, Zustelloptionen, Ausnahmen je Artikel und der Kostenrechner. |
| v1.5 | Phase D2 | Lebenszyklus der Sendung und Transporteur: Anlegen (einzeln und in Mengen), Etikett kaufen (kostenpflichtig), Stornieren, Verfolgung, Übergabe an Allegro sowie unterstützende Abfragen beim Transporteur (Etiketten-PDF, Stellen, Dienste, Zeiten). |
| v1.6 | Phase E1 | Anbindungen entdecken (ohne Geheimnisse) sowie lokale Abfragen von Marktplatzangeboten und Kategoriezuordnungen. |
| v1.7 | Phase E2 | Live-Abfragen beim Marktplatz gegen Entgelt (Artikel, Kategorien, GPSR) sowie das Schreiben von Kategoriezuordnungen (und Abgleich des Zwischenspeichers). |
| v1.8 | Phase E3 | Veröffentlichen, Abgleichen, Abholen, Importieren und Preisliste je Kanal für echte Marktplatzangebote (kostenpflichtig). |
| v1.9 | Phase F | Schreiben in Kommunikation und Nachverkauf: Benachrichtigungen, Warnungen, E-Mail (Versand kostenpflichtig), erneute Verarbeitung der Fehlerliste sowie Nachverkaufsbearbeitung und Rückzahlungen (der abgetrennte Bereich postsale:refunds:write). |
| v1.10 | Webhooks | Das neue Ereignis order.status_changed nach einer bestätigten echten Statusänderung einer Bestellung, mit previousStatus und origin. Kein Ereignis bei einem Vorgang ohne Wirkung (no-op) und bei einem abgelehnten Wechsel. |
Die Versionierung steht im Pfad: eine brechende Änderung käme nach /v2, wobei v1 daneben mindestens 6 Monate ab der Ankündigung weiterläuft (ein Eintrag im Änderungsverlauf, eine E-Mail an die Inhaberschaft aktiver Schlüssel sowie die Kopfteile Deprecation und Sunset).
Bewährte Vorgehensweisen
- Prüfen Sie die Verbindung mit
GET /me, bevor Sie die erste Anbindung bauen. - Fügen Sie Schreibvorgängen immer einen
Idempotency-Keybei und wiederholen Sie vorübergehende Fehler mit wachsendem Abstand. - Führen Sie nach einer Wiederherstellung des Kontos aus einer Sicherung einen vollständigen Neuabgleich durch (verlassen Sie sich nicht auf
updatedSince) und legen Sie neue Schlüssel an - die alten werden dabei ungültig. - Nutzen Sie für den abholenden Abgleich
updatedSincemit überlappendem Fenster und entdoppeln Sie über dieid.
Häufige Fragen
Melden Sie sich in der Oberfläche an, gehen Sie zu Konto - API und legen Sie einen Schlüssel mit den nötigen Bereichen an. Den Schlüssel sehen Sie nur einmal, bewahren Sie ihn also sicher auf. Machen Sie den ersten Versuch gegen GET /me, um die Verbindung zu bestätigen und Tarif und Limits zu sehen.
Ein Schlüssel dient eingehenden Aufrufen: Ihr System fragt NavyFlame nach Daten oder führt einen Vorgang aus. Ein Webhook ist eine ausgehende Benachrichtigung: NavyFlame schickt Ihnen ein Signal über ein Ereignis (etwa eine neue Bestellung), sobald es eintritt.
Nutzen Sie zum Empfangen von Webhooks das Modul Webhooks (Zapier) oder Custom Webhook (Make) und geben Sie die Adresse in der Oberfläche als Ziel des Abonnements an. Für Aufrufe der Schnittstelle nutzen Sie das Modul HTTP / Custom Request mit dem Kopfteil Authorization: Bearer. Die Prüfung der Signatur beschreibt der Abschnitt Webhooks.
Nicht, wenn Sie den Kopfteil Idempotency-Key nutzen. Eine Wiederholung mit demselben Schlüssel gibt dasselbe Ergebnis zurück, ohne doppelte Wirkung. Der Kopfteil ist beim Anlegen von Bestellungen und beim Auslösen der Rechnungsstellung erforderlich.
Die Schnittstelle gibt 403 mit dem Code plan_limit zurück, bis verlängert wird. Nach einer Wiederherstellung des Kontos aus einer Sicherung werden Schlüssel automatisch ungültig (legen Sie neue an), und wir empfehlen einen vollständigen Neuabgleich statt sich auf updatedSince zu verlassen.
Bereit, Ihr System anzubinden?
Legen Sie ein Konto an, erstellen Sie in der Oberfläche einen Schlüssel und starten Sie mit GET /me.
Konto anlegen