Bicops Partner APIv1

Integration interface for sellers and corporate partners.

Overview

Product, stock and price data is sent to Bicops through this API. Order and finance data is retrieved through the same API. Bulk requests are processed from a queue; the response is 202 with a batch identifier (batchId).

Version: /v1. Field names do not change. Response messages are in English; the code field is stable.

  • JSON, UTF-8, ISO-8601 (UTC)
  • Every response includes the X-Request-Id header
  • Invalid rows are rejected, valid rows are processed
  • A record sent with the same sourceId is updated
GET /v1/me
POST /v1/catalog/products
PATCH /v1/catalog/stock · /v1/catalog/prices
DELETE /v1/catalog/products/{sourceId}
POST /v1/catalog/imports → /{batchId}/complete
GET /v1/catalog/products · /v1/catalog/batches/{id} · /v1/logs/requests

Authentication

Every request carries the X-Api-Key and X-Api-Secret headers. The key is issued by Bicops; the secret is shown only at creation.

The seller identity comes from the key. No seller identifier is sent in the body. A key accesses only its own account. Permissions are defined by scopes (catalog:read, catalog:write, orders:read).

An IP allowlist and an expiry date can be set. Two keys can be active during 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-id

Connectivity test: GET /v1/me. The response lists the scopes and limits of the key.

Key types

There are two key types with different reach. Calling a service with the wrong type returns 403.

Seller keyCatalog, orders, returns, invoices, finance, reports, batches, webhooks. Bound to a seller account.
Corporate keyCustomer accounts, statements, collection receipts, sales invoices, sales representative assignments. Bound to a company branch.
BothGET /v1/me, GET /v1/logs/requests, webhook subscriptions and GET /v1/events.

Getting started

1. Connectivity test

curl -s https://partner.bicops.tr/v1/me \
  -H "X-Api-Key: 2c1d5c7e-2a1b-4c1e-9d7a-2b6f0e3c9a11" \
  -H "X-Api-Secret: <your-secret>"

2. Submit products (up to 1,000 records). Response: 202 and 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. Query the batch record: status, counts, row errors.

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. Update stock and prices (up to 5,000 records).

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}]}]}'

Catalog

POST /v1/catalog/products inserts or updates records by sourceId. Only changed records are processed.

Fields

FieldTypeDescription
sourceIdstring (≤200)Required. Seller stock code. Up to 200 characters.
namestring (≤4000)Required for active products.
brandstring (≤200)Brand name.
producerCode, previousCodestring (≤200)Manufacturer part number and superseded number.
oemCodes[]string[] (≤200 items, each ≤100)OEM numbers as an array. Numbers are not concatenated.
equivalentCodes[]string[] (≤200 items)Cross-reference numbers ("BRAND NUMBER").
price, currency, pricesIncludeVatdecimal · string(3) · booleanList price. TRY, USD or EUR.
stock, warehouses[]decimal · object[] {code: string, stock: decimal}Total stock and per-warehouse breakdown [{code, stock}].
minOrder, packageAmount, boxAmount, unitinteger · integer · integer · string(≤16)Ordering rules.
desi, weightdecimal · decimalVolumetric weight and weight (kg).
images[]string[] (URL, ≤10)Image URLs (https).
statusinteger (0 | 1)1 active, 0 inactive.

PATCH /v1/catalog/stock and PATCH /v1/catalog/prices update stock and prices only. Processed on the priority queue.

Deactivation: DELETE /v1/catalog/products/{sourceId} or POST /v1/catalog/products/deactivate.

GET /v1/catalog/products returns the state of the records on the Bicops side.

File import

Full catalogs are sent as an NDJSON file (one record per line). gzip is recommended. The file is uploaded directly to storage.

  1. POST /v1/catalog/imports: obtain uploadUrl and batchId
  2. Upload the file with HTTP PUT to uploadUrl
  3. POST /v1/catalog/imports/{batchId}/complete: processing starts
  4. GET /v1/catalog/batches/{batchId}: track progress
# 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>"

File format

  • Each line is a standalone JSON object. There are no commas or square brackets between lines.
  • The file is UTF-8 encoded and lines end with \n. Blank lines are skipped.
  • Only sourceId (your stock code) is required. A field you omit keeps its current value.
  • A malformed line is rejected on its own and the rest of the file is processed. Reasons are listed at GET /v1/catalog/batches/{id}/errors.
  • If stock and warehouses are both sent, stock must equal the sum of the warehouse quantities.
  • Products missing from the file are not deleted. Send that product with status: 0 to deactivate it.

Sample file

{"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}

Download the sample NDJSON file

dryRun=true validates the file without writing. The first import of 1,000,000 records takes about 15 minutes.

Batch records

Every bulk request creates a batch record. GET /v1/catalog/batches/{id} returns status, counts and durations. /errors returns row errors; /errors.csv returns the same list as CSV.

queuedQueued
awaiting_uploadWaiting for file upload
processingProcessing
syncingUpdating catalog and search index
doneCompleted
partialCompleted, some records rejected
failedFailed

Counts: received, accepted, rejected, changed. Resending identical data yields changed = 0.

Endpoints

All endpoints are under /v1. Write endpoints require the corresponding scope.

Orders

EndpointDescription
GET /ordersOrder list (status, updatedSince)
GET /orders/{id}Order detail
POST /orders/{id}/approveApprove the order
POST /orders/{id}/statusUpdate status {status}
POST /orders/{id}/erp-referenceStore ERP reference {reference}
GET /orders/{id}/messagesOrder messages
GET /orders/{id}/documentsOrder documents

Shipping

EndpointDescription
POST /orders/{id}/shipmentsRegister your own shipment {trackNumber, cargoId?}
POST /orders/{id}/shipments/createCreate a shipment with a Bicops carrier
GET /orders/{id}/shipments/labelShipment label (PDF, base64)
GET /orders/carriersCarrier list

Returns and cancellations

EndpointDescription
GET /returnsReturn requests
GET /returns/{id}Return detail
POST /returns/{id}/decisionReturn decision {action: approve|reject}
GET /cancellationsCancelled orders

Invoices

EndpointDescription
GET /orders/{id}/invoicesInvoice files attached to the order
POST /orders/{id}/invoiceAttach your invoice {fileBase64|fileUrl}
GET /invoicesDocuments issued to you by Bicops

Finance

EndpointDescription
GET /finance/settlementsPer-order settlement
GET /finance/statementMonthly statement
GET /finance/paymentsCard payments

Webhooks and events

EndpointDescription
GET /webhooksWebhook list
POST /webhooksRegister a webhook {url, events[]}
DELETE /webhooks/{id}Disable a webhook
POST /webhooks/{id}/testSend a test event
GET /webhooks/deliveriesDelivery log
GET /eventsEvent queue (cursor)

Reports

EndpointDescription
GET /reports/salesSales report (groupBy=day|month|product|brand)
GET /reports/returnsReturn rate
GET /reports/catalogCatalog health
GET /reports/demandDemand and out-of-stock products

Corporate (branch key)

EndpointDescription
GET /customersCustomer accounts
GET /customers/{id}/statementCustomer statement and balance
GET /accounting/receiptsCollection receipts
GET /accounting/invoicesBranch sales invoices
GET /salesmenSales representative assignments

Error codes

Error response: { code, message, details[], requestId }. code is stable; message is an English description.

{
  "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 status codes

UNAUTHORIZED (401)Key invalid or missing
FORBIDDEN_SCOPE (403)Insufficient scope
SELLER_KEY_REQUIRED (403)The service needs a seller key; a corporate key was used
CORPORATE_KEY_REQUIRED (403)The service needs a corporate key; a seller key was used
SANDBOX_READ_ONLY (403)A sandbox key cannot modify orders, returns or invoices; catalog requests are only validated
IP_NOT_ALLOWED (403)IP not in the allowlist
VALIDATION_FAILED (422)Invalid body schema
PAYLOAD_TOO_LARGE (413)Record limit exceeded
QUEUE_BUSY (429)Pending batch limit exceeded; see the Retry-After header
RATE_LIMITED (429)Request rate exceeded
NOT_FOUND (404)Record not found
STORAGE_UNAVAILABLE (503)Storage temporarily unavailable

Record codes (batch error report)

SOURCEID_REQUIREDsourceId is empty
NAME_REQUIREDName missing for an active product
PRICE_NEGATIVE, STOCK_NEGATIVENegative or non-numeric value
CURRENCY_INVALIDCurrency is not TRY, USD or EUR
STATUS_INVALIDstatus is not 0 or 1
UNKNOWN_SOURCEIDProduct not defined
INVALID_JSONLine is not valid JSON
OEM_TOO_SHORT (warning)Number shorter than three characters skipped
WAREHOUSE_STOCK_MISMATCH (warning)Warehouse total used
DUPLICATE_SOURCEID (warning)Last record used

Limits

  • Products: 1,000 records per request. Stock and prices: 5,000 records per request. Body: 6 MB.
  • Request rate: 600 requests per minute per key. 429 when exceeded.
  • Pending batches: 10 per seller. 429 when exceeded.
  • File: no record limit, up to 2 GB (gzip).
  • The upload URL is valid for 15 minutes.

Request log

GET /v1/logs/requests returns the requests of the last 30 days: endpoint, status, duration, requestId, batchId.

Reference