Überblick
Produkt-, Bestands- und Preisdaten werden über diese API an Bicops gesendet. Bestell- und Finanzdaten werden über dieselbe API abgerufen. Massenanfragen werden aus einer Warteschlange verarbeitet; die Antwort ist 202 mit einer Batch-Kennung (batchId).
Version: /v1. Feldnamen ändern sich nicht. Antwortmeldungen sind auf Englisch; das Feld code ist stabil.
- JSON, UTF-8, ISO-8601 (UTC)
- Jede Antwort enthält den Header X-Request-Id
- Ungültige Datensätze werden abgelehnt, gültige verarbeitet
- Ein Datensatz mit derselben sourceId wird aktualisiert
/v1/me/v1/catalog/products/v1/catalog/stock · /v1/catalog/prices/v1/catalog/products/{sourceId}/v1/catalog/imports → /{batchId}/complete/v1/catalog/products · /v1/catalog/batches/{id} · /v1/logs/requestsAuthentifizierung
Jede Anfrage enthält die Header X-Api-Key und X-Api-Secret. Der Schlüssel wird von Bicops ausgestellt; das Secret wird nur bei der Erstellung angezeigt.
Die Händleridentität ergibt sich aus dem Schlüssel. Im Anfragekörper wird keine Händlerkennung gesendet. Ein Schlüssel greift nur auf das eigene Konto zu. Berechtigungen werden über Scopes definiert (catalog:read, catalog:write, orders:read).
IP-Allowlist und Ablaufdatum können gesetzt werden. Bei der Rotation können zwei Schlüssel aktiv sein.
X-Api-Key: 2c1d5c7e-2a1b-4c1e-9d7a-2b6f0e3c9a11
X-Api-Secret: 4Qb…(base64url, 43 chars)
Content-Type: application/json
X-Request-Id: optional-your-correlation-idVerbindungstest: GET /v1/me. Die Antwort enthält Scopes und Limits des Schlüssels.
Schlüsseltypen
Es gibt zwei Schlüsseltypen mit unterschiedlicher Reichweite. Ein Dienst, der mit dem falschen Typ aufgerufen wird, antwortet mit 403.
Verkäuferschlüssel | Katalog, Bestellungen, Retouren, Rechnungen, Finanzen, Berichte, Batches, Webhooks. An ein Verkäuferkonto gebunden. |
Firmenschlüssel | Kundenkonten, Kontoauszüge, Zahlungsbelege, Verkaufsrechnungen, Vertreterzuordnungen. An eine Unternehmensfiliale gebunden. |
Beide | GET /v1/me, GET /v1/logs/requests, Webhook-Abonnements und GET /v1/events. |
Erste Schritte
1. Verbindungstest
curl -s https://partner.bicops.tr/v1/me \
-H "X-Api-Key: 2c1d5c7e-2a1b-4c1e-9d7a-2b6f0e3c9a11" \
-H "X-Api-Secret: <your-secret>"
2. Produkte übermitteln (bis zu 1.000 Datensätze). Antwort: 202 und batchId.
curl -s -X POST https://partner.bicops.tr/v1/catalog/products \
-H "X-Api-Key: <key>" -H "X-Api-Secret: <secret>" \
-H "Content-Type: application/json" \
-d '{
"items": [{
"sourceId": "SACHS 317 572",
"name": "AMORTISOR ON AUDI A3 / GOLF V",
"brand": "SACHS",
"producerCode": "317 572",
"oemCodes": ["1T0413031CN", "1T0413031CK"],
"equivalentCodes": ["FEBI 106124"],
"price": 3869.60, "currency": "TRY", "pricesIncludeVat": false,
"stock": 12,
"warehouses": [{ "code": "ANK", "stock": 8 }, { "code": "IZM", "stock": 4 }],
"minOrder": 1, "packageAmount": 1, "unit": "AD", "desi": 3.2,
"images": ["https://cdn.example.com/317572.jpg"],
"status": 1
}]
}'HTTP/1.1 202 Accepted
X-Request-Id: 7c0e1c5a-…
{
"batchId": 1042, "status": "queued",
"received": 1, "accepted": 1, "rejected": 0, "warnings": 0,
"chunks": 1, "dryRun": false, "issues": [], "requestId": "7c0e1c5a-…"
}
3. Batch-Datensatz abfragen: Status, Zähler, Zeilenfehler.
curl -s https://partner.bicops.tr/v1/catalog/batches/1042 -H "X-Api-Key: <key>" -H "X-Api-Secret: <secret>"
curl -s https://partner.bicops.tr/v1/catalog/batches/1042/errors.csv -H "X-Api-Key: <key>" -H "X-Api-Secret: <secret>" -o errors.csv
4. Bestand und Preise aktualisieren (bis zu 5.000 Datensätze).
curl -s -X PATCH https://partner.bicops.tr/v1/catalog/stock \
-H "X-Api-Key: <key>" -H "X-Api-Secret: <secret>" -H "Content-Type: application/json" \
-d '{"items":[{"sourceId":"SACHS 317 572","stock":9,"warehouses":[{"code":"ANK","stock":5},{"code":"IZM","stock":4}]}]}'Katalog
POST /v1/catalog/products legt Datensätze anhand der sourceId an oder aktualisiert sie. Nur geänderte Datensätze werden verarbeitet.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
sourceId | string (≤200) | Pflicht. Artikelnummer des Händlers. Bis zu 200 Zeichen. |
name | string (≤4000) | Pflicht für aktive Produkte. |
brand | string (≤200) | Markenname. |
producerCode, previousCode | string (≤200) | Herstellernummer und Vorgängernummer. |
oemCodes[] | string[] (≤200 items, each ≤100) | OEM-Nummern als Array. Nummern werden nicht zusammengefügt. |
equivalentCodes[] | string[] (≤200 items) | Vergleichsnummern („MARKE NUMMER“). |
price, currency, pricesIncludeVat | decimal · string(3) · boolean | Listenpreis. TRY, USD oder EUR. |
stock, warehouses[] | decimal · object[] {code: string, stock: decimal} | Gesamtbestand und Aufteilung je Lager [{code, stock}]. |
minOrder, packageAmount, boxAmount, unit | integer · integer · integer · string(≤16) | Bestellregeln. |
desi, weight | decimal · decimal | Volumengewicht und Gewicht (kg). |
images[] | string[] (URL, ≤10) | Bild-URLs (https). |
status | integer (0 | 1) | 1 aktiv, 0 inaktiv. |
PATCH /v1/catalog/stock und PATCH /v1/catalog/prices aktualisieren nur Bestand und Preise. Verarbeitung in der Prioritätswarteschlange.
Deaktivierung: DELETE /v1/catalog/products/{sourceId} oder POST /v1/catalog/products/deactivate.
GET /v1/catalog/products liefert den Zustand der Datensätze auf Bicops-Seite.
Dateiimport
Vollständige Kataloge werden als NDJSON-Datei gesendet (ein Datensatz pro Zeile). gzip wird empfohlen. Die Datei wird direkt in den Speicher hochgeladen.
- POST /v1/catalog/imports: uploadUrl und batchId abrufen
- Datei per HTTP PUT an uploadUrl hochladen
- POST /v1/catalog/imports/{batchId}/complete: Verarbeitung starten
- GET /v1/catalog/batches/{batchId}: Fortschritt verfolgen
# 1
curl -s -X POST https://partner.bicops.tr/v1/catalog/imports -H "X-Api-Key: <key>" -H "X-Api-Secret: <secret>" \
-H "Content-Type: application/json" -d '{"format":"ndjson","gzip":true}'
# → {"batchId":1043,"uploadUrl":"https://files.bicops.tr/partner-raw/…","expiresInSec":900}
# 2
curl -s -X PUT "<uploadUrl>" -H "Content-Type: application/octet-stream" --data-binary @catalog.ndjson.gz
# 3
curl -s -X POST https://partner.bicops.tr/v1/catalog/imports/1043/complete -H "X-Api-Key: <key>" -H "X-Api-Secret: <secret>"
Dateiformat
- Jede Zeile ist ein eigenständiges JSON-Objekt. Zwischen den Zeilen stehen keine Kommas und keine eckigen Klammern.
- Die Datei ist UTF-8-kodiert, Zeilenende \n. Leere Zeilen werden übersprungen.
- Pflichtfeld ist nur sourceId (Ihr Lagercode). Ein nicht gesendetes Feld behält seinen aktuellen Wert.
- Eine fehlerhafte Zeile wird einzeln abgelehnt, der Rest der Datei wird verarbeitet. Gründe unter GET /v1/catalog/batches/{id}/errors.
- Werden stock und warehouses zusammen gesendet, muss stock der Summe der Lagerbestände entsprechen.
- Produkte, die in der Datei fehlen, werden nicht gelöscht. Zum Deaktivieren das Produkt mit status: 0 senden.
Beispieldatei
{"sourceId":"SACHS 317 572","name":"AMORTISOR ON AUDI A3 / GOLF V","brand":"SACHS","producerCode":"317 572","previousCode":"317 571","oemCodes":["1T0413031CN","1T0413031CK"],"equivalentCodes":["FEBI 106124"],"barcodes":["4054228012345"],"price":3869.6,"currency":"TRY","pricesIncludeVat":false,"stock":12,"warehouses":[{"code":"ANK","stock":8},{"code":"IST","stock":4}],"minOrder":1,"packageAmount":1,"boxAmount":2,"unit":"AD","desi":3.2,"weight":1.25,"images":["https://cdn.satici.com/317572.jpg"],"categoryHint":"Amortisor","vehicleHint":"VW Golf V 2003-2008","status":1}
{"sourceId":"MANN W 712/95","name":"YAG FILTRESI","brand":"MANN","oemCodes":["W 712/95","1109AY"],"price":210.5,"currency":"TRY","stock":0,"status":1}
{"sourceId":"BOSCH 0986495255","name":"FREN BALATASI ON","brand":"BOSCH","oemCodes":["0986495255"],"price":1250,"currency":"TRY","stock":6,"warehouses":[{"code":"IZM","stock":6}],"status":1}
{"sourceId":"SACHS 317 571","status":0}
Beispiel-NDJSON-Datei herunterladen
dryRun=true prüft die Datei ohne Schreibvorgang. Der Erstimport von 1.000.000 Datensätzen dauert etwa 15 Minuten.
Batch-Datensätze
Jede Massenanfrage erzeugt einen Batch-Datensatz. GET /v1/catalog/batches/{id} liefert Status, Zähler und Dauern. /errors liefert Zeilenfehler; /errors.csv dieselbe Liste als CSV.
queued | In Warteschlange |
awaiting_upload | Warten auf Datei-Upload |
processing | In Verarbeitung |
syncing | Katalog und Suchindex werden aktualisiert |
done | Abgeschlossen |
partial | Abgeschlossen, einige Datensätze abgelehnt |
failed | Fehlgeschlagen |
Zähler: received, accepted, rejected, changed. Bei erneuter Übermittlung identischer Daten ist changed = 0.
Endpunkte
Alle Endpunkte liegen unter /v1. Schreibende Endpunkte erfordern den entsprechenden Scope.
Bestellungen
| Endpunkt | Beschreibung |
|---|---|
GET /orders | Bestellliste (status, updatedSince) |
GET /orders/{id} | Bestelldetail |
POST /orders/{id}/approve | Bestellung freigeben |
POST /orders/{id}/status | Status aktualisieren {status} |
POST /orders/{id}/erp-reference | ERP-Referenz speichern {reference} |
GET /orders/{id}/messages | Bestellnachrichten |
GET /orders/{id}/documents | Bestelldokumente |
Versand
| Endpunkt | Beschreibung |
|---|---|
POST /orders/{id}/shipments | Eigene Sendung melden {trackNumber, cargoId?} |
POST /orders/{id}/shipments/create | Sendung mit Bicops-Carrier erstellen |
GET /orders/{id}/shipments/label | Versandlabel (PDF, base64) |
GET /orders/carriers | Carrier-Liste |
Retouren und Stornierungen
| Endpunkt | Beschreibung |
|---|---|
GET /returns | Retourenanfragen |
GET /returns/{id} | Retourendetail |
POST /returns/{id}/decision | Retourenentscheidung {action: approve|reject} |
GET /cancellations | Stornierte Bestellungen |
Rechnungen
| Endpunkt | Beschreibung |
|---|---|
GET /orders/{id}/invoices | Rechnungsdateien der Bestellung |
POST /orders/{id}/invoice | Eigene Rechnung anhängen {fileBase64|fileUrl} |
GET /invoices | Von Bicops an Sie ausgestellte Belege |
Finanzen
| Endpunkt | Beschreibung |
|---|---|
GET /finance/settlements | Abrechnung je Bestellung |
GET /finance/statement | Monatsauszug |
GET /finance/payments | Kartenzahlungen |
Webhooks und Ereignisse
| Endpunkt | Beschreibung |
|---|---|
GET /webhooks | Webhook-Liste |
POST /webhooks | Webhook registrieren {url, events[]} |
DELETE /webhooks/{id} | Webhook deaktivieren |
POST /webhooks/{id}/test | Testereignis senden |
GET /webhooks/deliveries | Zustellprotokoll |
GET /events | Ereigniswarteschlange (cursor) |
Berichte
| Endpunkt | Beschreibung |
|---|---|
GET /reports/sales | Verkaufsbericht (groupBy=day|month|product|brand) |
GET /reports/returns | Retourenquote |
GET /reports/catalog | Katalogzustand |
GET /reports/demand | Nachfrage und ausverkaufte Produkte |
Unternehmen (Filialschlüssel)
| Endpunkt | Beschreibung |
|---|---|
GET /customers | Kundenkonten |
GET /customers/{id}/statement | Kontoauszug und Saldo |
GET /accounting/receipts | Zahlungsquittungen |
GET /accounting/invoices | Verkaufsrechnungen der Filiale |
GET /salesmen | Zuordnung der Vertriebsmitarbeiter |
Fehlercodes
Fehlerantwort: { code, message, details[], requestId }. code ist stabil; message ist eine englische Beschreibung.
{
"code": "VALIDATION_FAILED",
"message": "Request body validation failed",
"details": [{ "field": "items.0.price", "code": "INVALID_FIELD", "message": "price must not be less than 0" }],
"requestId": "7c0e1c5a-…"
}
HTTP-Statuscodes
UNAUTHORIZED (401) | Schlüssel ungültig oder fehlend |
FORBIDDEN_SCOPE (403) | Scope nicht ausreichend |
SELLER_KEY_REQUIRED (403) | Der Dienst benötigt einen Verkäuferschlüssel; es wurde ein Firmenschlüssel verwendet |
CORPORATE_KEY_REQUIRED (403) | Der Dienst benötigt einen Firmenschlüssel; es wurde ein Verkäuferschlüssel verwendet |
SANDBOX_READ_ONLY (403) | Ein Sandbox-Schlüssel kann Bestellungen, Retouren und Rechnungen nicht ändern; Kataloganfragen werden nur geprüft |
IP_NOT_ALLOWED (403) | IP nicht in der Allowlist |
VALIDATION_FAILED (422) | Ungültiges Körperschema |
PAYLOAD_TOO_LARGE (413) | Datensatzlimit überschritten |
QUEUE_BUSY (429) | Limit wartender Batches überschritten; siehe Header Retry-After |
RATE_LIMITED (429) | Anfragerate überschritten |
NOT_FOUND (404) | Datensatz nicht gefunden |
STORAGE_UNAVAILABLE (503) | Speicher vorübergehend nicht verfügbar |
Datensatzcodes (Batch-Fehlerbericht)
SOURCEID_REQUIRED | sourceId ist leer |
NAME_REQUIRED | Name für aktives Produkt fehlt |
PRICE_NEGATIVE, STOCK_NEGATIVE | Negativer oder nicht numerischer Wert |
CURRENCY_INVALID | Währung nicht TRY, USD oder EUR |
STATUS_INVALID | status nicht 0 oder 1 |
UNKNOWN_SOURCEID | Produkt nicht definiert |
INVALID_JSON | Zeile ist kein gültiges JSON |
OEM_TOO_SHORT (Warnung) | Nummer kürzer als drei Zeichen übersprungen |
WAREHOUSE_STOCK_MISMATCH (Warnung) | Lagersumme verwendet |
DUPLICATE_SOURCEID (Warnung) | Letzter Datensatz verwendet |
Limits
- Produkte: 1.000 Datensätze pro Anfrage. Bestand und Preise: 5.000 Datensätze pro Anfrage. Körper: 6 MB.
- Anfragerate: 600 Anfragen pro Minute je Schlüssel. Bei Überschreitung 429.
- Wartende Batches: 10 je Händler. Bei Überschreitung 429.
- Datei: kein Datensatzlimit, bis zu 2 GB (gzip).
- Die Upload-URL ist 15 Minuten gültig.
Anfrageprotokoll
GET /v1/logs/requests liefert die Anfragen der letzten 30 Tage: Endpunkt, Status, Dauer, requestId, batchId.
Referenz
- Swagger UI
- OpenAPI-3-Schema (JSON)
- Postman-Sammlung (alle Endpunkte, Beispielkörper)
- Support: support@bicops.tr. requestId und batchId angeben.