Developers

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 answers 401 INVALID_TOKEN with WWW-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, not 403.
  • 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 pricesByCountry and offers have 4, weights in kg have 3.
  • An order’s currency is its currency field (the one frozen on the order). Product prices are per country and in that country’s currency.
  • Never recompute an order total: copy articles_amount and the other figures as given.

Pagination

Lists are cursor-paginated and return the same envelope:

Response
{
  "data": [
    "…"
  ],
  "nextCursor": "opaque-string-or-null",
  "hasMore": true
}
  • Pass cursor=<nextCursor> to get the next page; stop when hasMore is false.
  • 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 limit with hasMore: 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:

WriteKeyRetry 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

ThingFormat
IdsStrings (UUIDs).
TimestampsISO 8601 in UTC, e.g. 2026-11-02T10:02:11.418Z.
CountriesISO 3166-1 alpha-2, upper case. Must be one of the seller’s countries (GET /me), else 403 COUNTRY_NOT_ALLOWED.
Field namesProduct, store and profile objects use camelCase. The Order object and webhook payloads use snake_case.
Unknown input fieldsDropped silently, except the fields listed as refused on Products.