Panoramica
I dati di prodotti, giacenze e prezzi vengono inviati a Bicops tramite questa API. I dati di ordini e finanza vengono recuperati dalla stessa API. Le richieste massive sono elaborate da una coda; la risposta è 202 con un identificativo batch (batchId).
Versione: /v1. I nomi dei campi non cambiano. I messaggi di risposta sono in inglese; il campo code è stabile.
- JSON, UTF-8, ISO-8601 (UTC)
- Ogni risposta include l’header X-Request-Id
- I record non validi sono rifiutati, quelli validi elaborati
- Un record inviato con lo stesso sourceId viene aggiornato
/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/requestsAutenticazione
Ogni richiesta include gli header X-Api-Key e X-Api-Secret. La chiave è emessa da Bicops; il segreto è mostrato solo alla creazione.
L’identità del venditore deriva dalla chiave. Nel corpo non viene inviato alcun identificativo venditore. Una chiave accede solo al proprio account. I permessi sono definiti dagli scope (catalog:read, catalog:write, orders:read).
È possibile impostare una allowlist IP e una data di scadenza. Durante la rotazione due chiavi possono essere attive.
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-idTest di connessione: GET /v1/me. La risposta elenca scope e limiti della chiave.
Tipi di chiave
Esistono due tipi di chiave con ambiti diversi. Un servizio chiamato con il tipo sbagliato restituisce 403.
Chiave venditore | Catalogo, ordini, resi, fatture, finanza, report, batch, webhook. Legata a un account venditore. |
Chiave aziendale | Conti clienti, estratti conto, ricevute di incasso, fatture di vendita, assegnazioni agenti. Legata a una filiale aziendale. |
Entrambe | GET /v1/me, GET /v1/logs/requests, sottoscrizioni webhook e GET /v1/events. |
Primi passi
1. Test di connessione
curl -s https://partner.bicops.tr/v1/me \
-H "X-Api-Key: 2c1d5c7e-2a1b-4c1e-9d7a-2b6f0e3c9a11" \
-H "X-Api-Secret: <your-secret>"
2. Invio dei prodotti (fino a 1.000 record). Risposta: 202 e 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. Interrogazione del record batch: stato, conteggi, errori di riga.
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. Aggiornamento di giacenze e prezzi (fino a 5.000 record).
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}]}]}'Catalogo
POST /v1/catalog/products inserisce o aggiorna i record tramite sourceId. Vengono elaborati solo i record modificati.
Campi
| Campo | Tipo | Descrizione |
|---|---|---|
sourceId | string (≤200) | Obbligatorio. Codice articolo del venditore. Fino a 200 caratteri. |
name | string (≤4000) | Obbligatorio per i prodotti attivi. |
brand | string (≤200) | Nome della marca. |
producerCode, previousCode | string (≤200) | Codice produttore e codice precedente. |
oemCodes[] | string[] (≤200 items, each ≤100) | Codici OEM come array. I codici non vengono concatenati. |
equivalentCodes[] | string[] (≤200 items) | Codici equivalenti ("MARCA CODICE"). |
price, currency, pricesIncludeVat | decimal · string(3) · boolean | Prezzo di listino. TRY, USD o EUR. |
stock, warehouses[] | decimal · object[] {code: string, stock: decimal} | Giacenza totale e ripartizione per magazzino [{code, stock}]. |
minOrder, packageAmount, boxAmount, unit | integer · integer · integer · string(≤16) | Regole d’ordine. |
desi, weight | decimal · decimal | Peso volumetrico e peso (kg). |
images[] | string[] (URL, ≤10) | URL delle immagini (https). |
status | integer (0 | 1) | 1 attivo, 0 inattivo. |
PATCH /v1/catalog/stock e PATCH /v1/catalog/prices aggiornano solo giacenze e prezzi. Elaborati nella coda prioritaria.
Disattivazione: DELETE /v1/catalog/products/{sourceId} o POST /v1/catalog/products/deactivate.
GET /v1/catalog/products restituisce lo stato dei record lato Bicops.
Importazione da file
Il catalogo completo viene inviato come file NDJSON (un record per riga). gzip è consigliato. Il file viene caricato direttamente nello storage.
- POST /v1/catalog/imports: ottenere uploadUrl e batchId
- Caricare il file con HTTP PUT su uploadUrl
- POST /v1/catalog/imports/{batchId}/complete: avvio dell’elaborazione
- GET /v1/catalog/batches/{batchId}: monitoraggio
# 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>"
Formato del file
- Ogni riga è un oggetto JSON autonomo. Tra le righe non ci sono virgole né parentesi quadre.
- Il file è codificato in UTF-8 e le righe terminano con \n. Le righe vuote vengono ignorate.
- L’unico campo obbligatorio è sourceId (il vostro codice di magazzino). Un campo non inviato mantiene il valore attuale.
- Una riga malformata viene rifiutata da sola e il resto del file viene elaborato. I motivi sono in GET /v1/catalog/batches/{id}/errors.
- Se vengono inviati sia stock sia warehouses, stock deve essere uguale alla somma delle giacenze di magazzino.
- I prodotti assenti dal file non vengono eliminati. Per disattivarne uno, inviatelo con status: 0.
File di esempio
{"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}
Scarica il file NDJSON di esempio
dryRun=true valida il file senza scrivere. La prima importazione di 1.000.000 di record richiede circa 15 minuti.
Record batch
Ogni richiesta massiva crea un record batch. GET /v1/catalog/batches/{id} restituisce stato, conteggi e durate. /errors restituisce gli errori di riga; /errors.csv lo stesso elenco in CSV.
queued | In coda |
awaiting_upload | In attesa del caricamento del file |
processing | In elaborazione |
syncing | Aggiornamento di catalogo e indice di ricerca |
done | Completato |
partial | Completato, alcuni record rifiutati |
failed | Fallito |
Conteggi: received, accepted, rejected, changed. Reinviando dati identici, changed = 0.
Endpoint
Tutti gli endpoint sono sotto /v1. Gli endpoint di scrittura richiedono lo scope corrispondente.
Ordini
| Endpoint | Descrizione |
|---|---|
GET /orders | Elenco ordini (status, updatedSince) |
GET /orders/{id} | Dettaglio ordine |
POST /orders/{id}/approve | Approva l’ordine |
POST /orders/{id}/status | Aggiorna stato {status} |
POST /orders/{id}/erp-reference | Salva riferimento ERP {reference} |
GET /orders/{id}/messages | Messaggi ordine |
GET /orders/{id}/documents | Documenti ordine |
Spedizioni
| Endpoint | Descrizione |
|---|---|
POST /orders/{id}/shipments | Registra la tua spedizione {trackNumber, cargoId?} |
POST /orders/{id}/shipments/create | Crea spedizione con corriere Bicops |
GET /orders/{id}/shipments/label | Etichetta spedizione (PDF, base64) |
GET /orders/carriers | Elenco corrieri |
Resi e annullamenti
| Endpoint | Descrizione |
|---|---|
GET /returns | Richieste di reso |
GET /returns/{id} | Dettaglio reso |
POST /returns/{id}/decision | Decisione sul reso {action: approve|reject} |
GET /cancellations | Ordini annullati |
Fatture
| Endpoint | Descrizione |
|---|---|
GET /orders/{id}/invoices | File fattura allegati all’ordine |
POST /orders/{id}/invoice | Allega la tua fattura {fileBase64|fileUrl} |
GET /invoices | Documenti emessi da Bicops a te |
Finanza
| Endpoint | Descrizione |
|---|---|
GET /finance/settlements | Liquidazione per ordine |
GET /finance/statement | Estratto mensile |
GET /finance/payments | Pagamenti con carta |
Webhook ed eventi
| Endpoint | Descrizione |
|---|---|
GET /webhooks | Elenco webhook |
POST /webhooks | Registra webhook {url, events[]} |
DELETE /webhooks/{id} | Disattiva webhook |
POST /webhooks/{id}/test | Invia evento di test |
GET /webhooks/deliveries | Registro consegne |
GET /events | Coda eventi (cursor) |
Report
| Endpoint | Descrizione |
|---|---|
GET /reports/sales | Report vendite (groupBy=day|month|product|brand) |
GET /reports/returns | Tasso di reso |
GET /reports/catalog | Stato del catalogo |
GET /reports/demand | Domanda e prodotti esauriti |
Aziendale (chiave filiale)
| Endpoint | Descrizione |
|---|---|
GET /customers | Anagrafiche clienti |
GET /customers/{id}/statement | Estratto conto e saldo cliente |
GET /accounting/receipts | Ricevute di incasso |
GET /accounting/invoices | Fatture di vendita della filiale |
GET /salesmen | Assegnazioni agenti |
Codici di errore
Risposta di errore: { code, message, details[], requestId }. code è stabile; message è una descrizione in inglese.
{
"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-…"
}
Codici di stato HTTP
UNAUTHORIZED (401) | Chiave non valida o mancante |
FORBIDDEN_SCOPE (403) | Scope insufficiente |
SELLER_KEY_REQUIRED (403) | Il servizio richiede una chiave venditore; è stata usata una chiave aziendale |
CORPORATE_KEY_REQUIRED (403) | Il servizio richiede una chiave aziendale; è stata usata una chiave venditore |
SANDBOX_READ_ONLY (403) | Una chiave sandbox non può modificare ordini, resi o fatture; le richieste di catalogo vengono solo validate |
IP_NOT_ALLOWED (403) | IP non in allowlist |
VALIDATION_FAILED (422) | Schema del corpo non valido |
PAYLOAD_TOO_LARGE (413) | Limite di record superato |
QUEUE_BUSY (429) | Limite di batch in attesa superato; vedere l’header Retry-After |
RATE_LIMITED (429) | Frequenza delle richieste superata |
NOT_FOUND (404) | Record non trovato |
STORAGE_UNAVAILABLE (503) | Storage temporaneamente non disponibile |
Codici di record (report errori batch)
SOURCEID_REQUIRED | sourceId vuoto |
NAME_REQUIRED | Nome mancante per un prodotto attivo |
PRICE_NEGATIVE, STOCK_NEGATIVE | Valore negativo o non numerico |
CURRENCY_INVALID | Valuta diversa da TRY, USD o EUR |
STATUS_INVALID | status diverso da 0 o 1 |
UNKNOWN_SOURCEID | Prodotto non definito |
INVALID_JSON | Riga non è JSON valido |
OEM_TOO_SHORT (avviso) | Codice più corto di tre caratteri saltato |
WAREHOUSE_STOCK_MISMATCH (avviso) | Usato il totale magazzini |
DUPLICATE_SOURCEID (avviso) | Usato l’ultimo record |
Limiti
- Prodotti: 1.000 record per richiesta. Giacenze e prezzi: 5.000 record per richiesta. Corpo: 6 MB.
- Frequenza: 600 richieste al minuto per chiave. Oltre: 429.
- Batch in attesa: 10 per venditore. Oltre: 429.
- File: nessun limite di record, fino a 2 GB (gzip).
- L’URL di caricamento è valido 15 minuti.
Registro richieste
GET /v1/logs/requests restituisce le richieste degli ultimi 30 giorni: endpoint, stato, durata, requestId, batchId.
Riferimento
- Swagger UI
- Schema OpenAPI 3 (JSON)
- Collezione Postman (tutti gli endpoint, corpi di esempio)
- Supporto: support@bicops.tr. Indicare requestId e batchId.