Aperçu
Les données de produits, de stock et de prix sont envoyées à Bicops par cette API. Les données de commandes et de finance sont récupérées par la même API. Les requêtes en masse sont traitées depuis une file ; la réponse est 202 avec un identifiant de lot (batchId).
Version : /v1. Les noms de champs ne changent pas. Les messages de réponse sont en anglais ; le champ code est stable.
- JSON, UTF-8, ISO-8601 (UTC)
- Chaque réponse contient l’en-tête X-Request-Id
- Les enregistrements invalides sont rejetés, les valides traités
- Un enregistrement envoyé avec le même sourceId est mis à jour
/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/requestsAuthentification
Chaque requête contient les en-têtes X-Api-Key et X-Api-Secret. La clé est émise par Bicops ; le secret n’est affiché qu’à la création.
L’identité du vendeur est déduite de la clé. Aucun identifiant vendeur n’est envoyé dans le corps. Une clé n’accède qu’à son propre compte. Les droits sont définis par des scopes (catalog:read, catalog:write, orders:read).
Une liste d’IP autorisées et une date d’expiration peuvent être définies. Deux clés peuvent être actives pendant une rotation.
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 de connexion : GET /v1/me. La réponse liste les scopes et limites de la clé.
Types de clé
Il existe deux types de clé avec des portées différentes. Un service appelé avec le mauvais type renvoie 403.
Clé vendeur | Catalogue, commandes, retours, factures, finance, rapports, lots, webhooks. Rattachée à un compte vendeur. |
Clé entreprise | Comptes clients, relevés, reçus d’encaissement, factures de vente, affectations de représentants. Rattachée à une agence de la société. |
Les deux | GET /v1/me, GET /v1/logs/requests, abonnements webhook et GET /v1/events. |
Premiers pas
1. Test de connexion
curl -s https://partner.bicops.tr/v1/me \
-H "X-Api-Key: 2c1d5c7e-2a1b-4c1e-9d7a-2b6f0e3c9a11" \
-H "X-Api-Secret: <your-secret>"
2. Envoi des produits (jusqu’à 1 000 enregistrements). Réponse : 202 et 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. Consultation de l’enregistrement de lot : statut, compteurs, erreurs de ligne.
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. Mise à jour des stocks et des prix (jusqu’à 5 000 enregistrements).
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}]}]}'Catalogue
POST /v1/catalog/products crée ou met à jour les enregistrements via sourceId. Seuls les enregistrements modifiés sont traités.
Champs
| Champ | Type | Description |
|---|---|---|
sourceId | string (≤200) | Obligatoire. Référence du vendeur. 200 caractères max. |
name | string (≤4000) | Obligatoire pour un produit actif. |
brand | string (≤200) | Nom de la marque. |
producerCode, previousCode | string (≤200) | Référence fabricant et référence précédente. |
oemCodes[] | string[] (≤200 items, each ≤100) | Références OEM en tableau. Les références ne sont pas concaténées. |
equivalentCodes[] | string[] (≤200 items) | Références équivalentes (« MARQUE RÉFÉRENCE »). |
price, currency, pricesIncludeVat | decimal · string(3) · boolean | Prix catalogue. TRY, USD ou EUR. |
stock, warehouses[] | decimal · object[] {code: string, stock: decimal} | Stock total et ventilation par entrepôt [{code, stock}]. |
minOrder, packageAmount, boxAmount, unit | integer · integer · integer · string(≤16) | Règles de commande. |
desi, weight | decimal · decimal | Poids volumétrique et poids (kg). |
images[] | string[] (URL, ≤10) | URL des images (https). |
status | integer (0 | 1) | 1 actif, 0 inactif. |
PATCH /v1/catalog/stock et PATCH /v1/catalog/prices ne mettent à jour que les stocks et les prix. Traités dans la file prioritaire.
Désactivation : DELETE /v1/catalog/products/{sourceId} ou POST /v1/catalog/products/deactivate.
GET /v1/catalog/products renvoie l’état des enregistrements côté Bicops.
Import par fichier
Le catalogue complet est envoyé sous forme de fichier NDJSON (un enregistrement par ligne). gzip est recommandé. Le fichier est téléversé directement dans le stockage.
- POST /v1/catalog/imports : obtenir uploadUrl et batchId
- Téléverser le fichier en HTTP PUT vers uploadUrl
- POST /v1/catalog/imports/{batchId}/complete : lancement du traitement
- GET /v1/catalog/batches/{batchId} : suivi
# 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>"
Format du fichier
- Chaque ligne est un objet JSON autonome. Il n’y a ni virgule ni crochet entre les lignes.
- Le fichier est encodé en UTF-8 et les lignes se terminent par \n. Les lignes vides sont ignorées.
- Le seul champ obligatoire est sourceId (votre code de stock). Un champ non transmis conserve sa valeur actuelle.
- Une ligne mal formée est rejetée seule et le reste du fichier est traité. Les motifs figurent dans GET /v1/catalog/batches/{id}/errors.
- Si stock et warehouses sont envoyés ensemble, stock doit être égal à la somme des quantités par dépôt.
- Les produits absents du fichier ne sont pas supprimés. Pour désactiver un produit, envoyez-le avec status: 0.
Fichier d’exemple
{"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}
Télécharger le fichier NDJSON d’exemple
dryRun=true valide le fichier sans écriture. Le premier import de 1 000 000 d’enregistrements prend environ 15 minutes.
Enregistrements de lot
Chaque requête en masse crée un enregistrement de lot. GET /v1/catalog/batches/{id} renvoie statut, compteurs et durées. /errors renvoie les erreurs de ligne ; /errors.csv la même liste en CSV.
queued | En file |
awaiting_upload | En attente du téléversement |
processing | En traitement |
syncing | Mise à jour du catalogue et de l’index de recherche |
done | Terminé |
partial | Terminé, certains enregistrements rejetés |
failed | Échec |
Compteurs : received, accepted, rejected, changed. Le renvoi de données identiques donne changed = 0.
Points d’accès
Tous les points d’accès sont sous /v1. Les écritures exigent le scope correspondant.
Commandes
| Point d’accès | Description |
|---|---|
GET /orders | Liste des commandes (status, updatedSince) |
GET /orders/{id} | Détail de commande |
POST /orders/{id}/approve | Approuver la commande |
POST /orders/{id}/status | Mettre à jour le statut {status} |
POST /orders/{id}/erp-reference | Enregistrer la référence ERP {reference} |
GET /orders/{id}/messages | Messages de commande |
GET /orders/{id}/documents | Documents de commande |
Expédition
| Point d’accès | Description |
|---|---|
POST /orders/{id}/shipments | Déclarer votre expédition {trackNumber, cargoId?} |
POST /orders/{id}/shipments/create | Créer une expédition avec un transporteur Bicops |
GET /orders/{id}/shipments/label | Étiquette d’expédition (PDF, base64) |
GET /orders/carriers | Liste des transporteurs |
Retours et annulations
| Point d’accès | Description |
|---|---|
GET /returns | Demandes de retour |
GET /returns/{id} | Détail du retour |
POST /returns/{id}/decision | Décision de retour {action: approve|reject} |
GET /cancellations | Commandes annulées |
Factures
| Point d’accès | Description |
|---|---|
GET /orders/{id}/invoices | Fichiers de facture liés à la commande |
POST /orders/{id}/invoice | Joindre votre facture {fileBase64|fileUrl} |
GET /invoices | Documents émis par Bicops |
Finance
| Point d’accès | Description |
|---|---|
GET /finance/settlements | Règlement par commande |
GET /finance/statement | Relevé mensuel |
GET /finance/payments | Paiements par carte |
Webhooks et événements
| Point d’accès | Description |
|---|---|
GET /webhooks | Liste des webhooks |
POST /webhooks | Enregistrer un webhook {url, events[]} |
DELETE /webhooks/{id} | Désactiver un webhook |
POST /webhooks/{id}/test | Envoyer un événement de test |
GET /webhooks/deliveries | Journal de livraison |
GET /events | File d’événements (cursor) |
Rapports
| Point d’accès | Description |
|---|---|
GET /reports/sales | Rapport des ventes (groupBy=day|month|product|brand) |
GET /reports/returns | Taux de retour |
GET /reports/catalog | État du catalogue |
GET /reports/demand | Demande et produits en rupture |
Entreprise (clé d’agence)
| Point d’accès | Description |
|---|---|
GET /customers | Comptes clients |
GET /customers/{id}/statement | Relevé et solde client |
GET /accounting/receipts | Reçus d’encaissement |
GET /accounting/invoices | Factures de vente de l’agence |
GET /salesmen | Affectations des commerciaux |
Codes d’erreur
Réponse d’erreur : { code, message, details[], requestId }. code est stable ; message est une description en anglais.
{
"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-…"
}
Codes de statut HTTP
UNAUTHORIZED (401) | Clé invalide ou absente |
FORBIDDEN_SCOPE (403) | Scope insuffisant |
SELLER_KEY_REQUIRED (403) | Le service exige une clé vendeur ; une clé entreprise a été utilisée |
CORPORATE_KEY_REQUIRED (403) | Le service exige une clé entreprise ; une clé vendeur a été utilisée |
SANDBOX_READ_ONLY (403) | Une clé bac à sable ne peut pas modifier les commandes, retours ou factures ; les requêtes catalogue sont seulement validées |
IP_NOT_ALLOWED (403) | IP hors liste autorisée |
VALIDATION_FAILED (422) | Schéma du corps invalide |
PAYLOAD_TOO_LARGE (413) | Limite d’enregistrements dépassée |
QUEUE_BUSY (429) | Limite de lots en attente dépassée ; voir l’en-tête Retry-After |
RATE_LIMITED (429) | Cadence de requêtes dépassée |
NOT_FOUND (404) | Enregistrement introuvable |
STORAGE_UNAVAILABLE (503) | Stockage temporairement indisponible |
Codes d’enregistrement (rapport d’erreurs du lot)
SOURCEID_REQUIRED | sourceId vide |
NAME_REQUIRED | Nom manquant pour un produit actif |
PRICE_NEGATIVE, STOCK_NEGATIVE | Valeur négative ou non numérique |
CURRENCY_INVALID | Devise autre que TRY, USD ou EUR |
STATUS_INVALID | status différent de 0 ou 1 |
UNKNOWN_SOURCEID | Produit non défini |
INVALID_JSON | Ligne JSON non valide |
OEM_TOO_SHORT (avertissement) | Référence de moins de trois caractères ignorée |
WAREHOUSE_STOCK_MISMATCH (avertissement) | Total des entrepôts utilisé |
DUPLICATE_SOURCEID (avertissement) | Dernier enregistrement utilisé |
Limites
- Produits : 1 000 enregistrements par requête. Stocks et prix : 5 000 enregistrements par requête. Corps : 6 Mo.
- Cadence : 600 requêtes par minute et par clé. Au-delà : 429.
- Lots en attente : 10 par vendeur. Au-delà : 429.
- Fichier : sans limite d’enregistrements, 2 Go max. (gzip).
- L’URL de téléversement est valable 15 minutes.
Journal des requêtes
GET /v1/logs/requests renvoie les requêtes des 30 derniers jours : point d’accès, statut, durée, requestId, batchId.
Référence
- Swagger UI
- Schéma OpenAPI 3 (JSON)
- Collection Postman (tous les points d’accès, corps d’exemple)
- Support : support@bicops.tr. Indiquer requestId et batchId.