API conventions
Authentication, money as decimal strings, pagination with cursors, idempotency, dates, countries and versioning.
Requests
- Base URL:
https://coliswift.com/api/partner/v1. HTTPS only. - Every request:
Authorization: Bearer <access_token>. A missing, expired or revoked token answers401 INVALID_TOKENwithWWW-Authenticate: Bearer realm="partner"— the reason is never given. - Bodies are JSON:
Content-Type: application/json. - The seller is always the token’s seller. No endpoint takes a seller id; an id belonging to another seller answers
404, not403. - The version is in the path (
/v1).
Money is a decimal string
Every amount, in and out, is a string in major units: "299.00", "89.500". A JSON number is refused on input with 400 VALIDATION_ERROR (Amount must be a decimal string in major units, e.g. "299.00"), because a float has already lost precision before it reaches us. Accepted shape: digits with up to four decimals, never negative (^\d+(\.\d{1,4})?$).
- Output scale is the stored column’s: order amounts and adoption prices have 2 decimals, product prices in
pricesByCountryandoffershave 4, weights in kg have 3. - An order’s currency is its
currencyfield (the one frozen on the order). Product prices are per country and in that country’s currency. - Never recompute an order total: copy
articles_amountand the other figures as given.
Pagination
Lists are cursor-paginated and return the same envelope:
{
"data": [
"…"
],
"nextCursor": "opaque-string-or-null",
"hasMore": true
}- Pass
cursor=<nextCursor>to get the next page; stop whenhasMoreisfalse. - Cursors are opaque — do not build or parse them.
limit: products and orders default to 100, at most 200; the COD Drop catalogue defaults to 50, at most 100. A larger value is clamped, not refused.- Lists that filter out rows after reading (the COD Drop catalogue drops your own products) can return a page shorter than
limitwithhasMore: true— keep following the cursor.
Incremental sync
GET /products takes an optional updatedSince and GET /orders a required updatedSince (ISO 8601). Use them as a nightly safety net behind webhooks, not as a polling loop.
Idempotency
There is no Idempotency-Key header. The two writes that matter are idempotent by their natural key:
| Write | Key | Retry answers |
|---|---|---|
POST /orders | (seller, your app, externalId) | 200 with the existing order and "duplicate": true (a new order answers 201). |
POST /cod-drop/adoptions | (seller, productId) | 200 with the adoption and "duplicate": true; per-country prices sent with the retry are applied. |
POST /products is not idempotent: a second product with the same reference is refused. PUT writes are naturally repeatable.
Formats
| Thing | Format |
|---|---|
| Ids | Strings (UUIDs). |
| Timestamps | ISO 8601 in UTC, e.g. 2026-11-02T10:02:11.418Z. |
| Countries | ISO 3166-1 alpha-2, upper case. Must be one of the seller’s countries (GET /me), else 403 COUNTRY_NOT_ALLOWED. |
| Field names | Product, store and profile objects use camelCase. The Order object and webhook payloads use snake_case. |
| Unknown input fields | Dropped silently, except the fields listed as refused on Products. |

