Push sales lines (bulk)
const url = 'https://api.europlaybook.com/v1/sales';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"lines":[{"channel":"webshop","external_id":"order-1001-line-1","quantity":2,"ship_from_country":"NL","ship_to_country":"BE","sku":"TEA-001","sold_on":"2026-10-01"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.europlaybook.com/v1/sales \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "lines": [ { "channel": "webshop", "external_id": "order-1001-line-1", "quantity": 2, "ship_from_country": "NL", "ship_to_country": "BE", "sku": "TEA-001", "sold_on": "2026-10-01" } ] }'Up to 1000 lines per call, idempotent on external_id per account: a line sent again with the
same values is unchanged, with new values it is updated. Lines a closed or filed period covers are
returned in held and not stored. No personal data: unknown fields are refused.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Up to 1000 lines per call.
One sales (or return) line. No personal data: no names, addresses or e-mails.
object
Your unique id for this line; sending it again updates the line.
Your SKU; matched to a product.
Sale (or return) date.
Units (positive; use kind=return for returns).
ISO 3166-1 alpha-2.
ISO 3166-1 alpha-2.
Responses
Section titled “Responses”OK
object
New lines.
Lines whose values changed.
Lines sent before with the same values.
External_ids not stored because a closed or filed period covers them (reopen it first).
SKUs without a product (stored; map or create the product).
Example generated
{ "created": 1, "updated": 1, "unchanged": 1, "held": [ "example" ], "unknown_skus": [ "example" ]}Bad Request
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }}Unauthorized
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }}Forbidden
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }}Not Found
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }}Conflict
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }}Unprocessable Content
object
What went wrong, in English, for people and logs.
Stable machine-readable error code; translate and branch on this.
Per-field problems (pydantic format: loc, msg, type).
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }, "errors": []}Too Many Requests
object
Example
{ "detail": "This API key lacks the scope catalogue:write", "code": "insufficient_scope", "params": { "required_scope": "catalogue:write" }}