Orders API

Read and create orders against your account. The API surfaces sample and bulk fulfilment requests, including those created through the customer portal, those received from connected sales channels (Shopify, Etsy, WooCommerce), and those submitted directly via this endpoint.

Base URL: https://developer.allthe.com/api/v1 Required scopes: orders:read, orders:write

Endpoints

| Method | Path | Scope | Status | | ------ | ---------------------------- | -------------- | ----------------- | | GET | /orders | orders:read | Stable | | GET | /orders/{id} | orders:read | Stable | | POST | /orders | orders:write | Stable | | POST | /orders/estimate | orders:read | Stable | | POST | /orders/{id}/cancel | orders:write | Stable |


List orders

GET /orders

| Name | Type | Description | | -------- | ------- | ------------------------------------------------------------------ | | status | string | Filter: pending, confirmed, in_production, dispatched, delivered, cancelled. | | limit | integer | Page size, 1–100. Default 25. | | cursor | string | Order id from previous next_cursor. |

curl "https://developer.allthe.com/api/v1/orders?status=in_production&limit=10" \
  -H "Authorization: Bearer pat_live_..."
{
  "data": [
    {
      "id": "ckor1...",
      "reference": "SMP-00421",
      "type": "sample",
      "status": "in_production",
      "items": [
        { "blank_variant_sku": "G6400-BLK-M", "qty": 5 }
      ],
      "notes": "Photo-shoot samples",
      "created_at": "2026-04-18T09:00:00.000Z",
      "updated_at": "2026-04-19T11:22:03.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Fetch an order

GET /orders/{id}

Returns a single order in the same shape as the list data[]. 404 not_found if it does not exist or belongs to another account.



Create an order

POST /orders

Submits a fulfilment request for an existing customer product in your catalogue. Each product_id must be one of your CustomerProducts, and each variant_sku must match a variant configured on that product. Created orders start in pending and are picked up by ops for production routing.

Required scope: orders:write

| Field | Type | Required | Description | | -------------------- | ------- | -------- | --------------------------------------------------------------------------- | | type | string | No | sample or bulk. Defaults to bulk. | | items[].product_id | string | Yes | Customer product id (from GET /products). | | items[].variant_sku| string | Yes | A blank_variant_sku returned on the product's variants[]. | | items[].quantity | integer | Yes | 1 – 10,000. | | items[].name | string | No | Override line label. Falls back to the product name. | | items[].colour | string | No | Display label, recorded against the line. | | items[].size | string | No | Display label, recorded against the line. | | shipping_address | object | Yes | contact_name, line1, city, postcode, country_code (ISO 3166-1 alpha-2). Optional: company_name, line2, county, phone. | | billing_address | object | No | Same shape. Defaults to shipping_address. | | items[].print_jobs | array | No | { area, method } pairs decorated on the line — billed per pair, and what production prints. Send every area you want printed (see below). Send [] for a deliberately undecorated blank. | | items[].decoration | object | No | Attach artwork or personalisation to the line — see Artwork & decoration. Exactly one of areas (fixed artwork) or personalisation. | | external_reference | string | No | Your own order id — recorded against the line items. | | notes | string | No | Free-text note for ops, max 1000 chars. |

Where a line's artwork comes from

There are two ways to decorate a line, and they resolve in this order:

  1. decoration on the item — artwork supplied as URLs with this order. Use it for one-off or per-order artwork. See Artwork & decoration.
  2. The product's stored designs — if you omit decoration, a line carrying a product_id is decorated from the designs saved on that customer product. This is the normal path for a product you built via POST /products or in the portal: store the artwork once, order it many times.

In both cases print_jobs decides what the line is billed for and what production enumerates as areas to print.

Send print_jobs explicitly whenever the line is decorated. If you omit it on a product with stored designs, the line is billed for a single area — which is wrong for a multi-area product, and leaves the billed areas out of step with the artwork attached. List every area you want printed.

curl -X POST "https://developer.allthe.com/api/v1/orders" \
  -H "Authorization: Bearer pat_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "sample",
    "items": [
      { "product_id": "ckor1abc...", "variant_sku": "G6400-BLK-M", "quantity": 1 }
    ],
    "shipping_address": {
      "contact_name": "Jane Doe",
      "line1": "12 Example Street",
      "city": "London",
      "postcode": "SW1A 1AA",
      "country_code": "GB"
    },
    "external_reference": "po-2026-0042",
    "notes": "Photoshoot sample"
  }'

201 Created returns the order in the standard shape:

{
  "id": "ckor2...",
  "reference": "API-SMP-XYZ12AB34",
  "type": "sample",
  "status": "pending",
  "items": { "lineItems": [...], "shippingAddress": {...} },
  "notes": "Photoshoot sample",
  "created_at": "2026-05-09T10:00:00.000Z",
  "updated_at": "2026-05-09T10:00:00.000Z"
}

Errors

| Status | Code | Reason | | ------ | ------------------- | --------------------------------------------------------------- | | 400 | invalid_request | Body is not valid JSON. | | 401 | unauthorized | Missing / invalid bearer token. | | 403 | insufficient_scope| Token is missing orders:write. | | 404 | not_found | A product_id is unknown or belongs to another account. | | 422 | validation_failed | Body shape invalid, or a variant_sku is not on its product. |


Decorating a line

Add print-ready artwork or buyer personalisation to any line with a decoration block. Every URL is fetched, validated and processed server-side into the canonical print shape — you never upload file bytes to us. See Artwork & decoration for the full reference, validation rules and examples.


Estimate an order

POST /orders/estimate

Prices a basket without creating or charging anything. Takes the same body as POST /orders and runs the same pricing path, so the total it returns is the amount you would be charged. Requires only orders:read.

curl -X POST "https://developer.allthe.com/api/v1/orders/estimate" \
  -H "Authorization: Bearer pat_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "sample",
    "items": [{ "product_id": "cmnc8...", "variant_sku": "YP023BKBK", "quantity": 1,
                "print_jobs": [{ "area": "Front", "method": "DTF" }] }],
    "shipping_address": { "contact_name": "Ada Lovelace", "line1": "12 Example Street",
                          "city": "London", "postcode": "SW1A 1AA", "country_code": "GB" }
  }'
{
  "currency": "GBP",
  "lines": [
    { "variant_sku": "YP023BKBK", "quantity": 1, "unit_price": 10.24, "line_price": 10.24,
      "print_jobs": [{ "area": "Front", "method": "DTF" }] }
  ],
  "subtotal": 10.24,
  "setup_total": 0,
  "shipping_cost": 3.08,
  "shipping_service": "Royal Mail 48",
  "vat_amount": 2.66,
  "duty_amount": 0,
  "total": 15.98,
  "estimate": true,
  "notice": "Prices, stock and shipping rates can change between estimating and ordering. Nothing is reserved."
}

shipping_options lists the other services available to that destination, so you can present a choice before committing.

Nothing is reserved. An estimate is a quote at a moment in time — stock, prices and shipping rates can all move before you place the order. A basket that cannot be made returns 409 out_of_stock with an oversold list rather than a price for something undeliverable.


Roadmap

  • Stock reservation at create time. Today, stock is checked when ops promote the order to production.
  • Shipping quote lock-in. Use POST /shipping/rates for an estimate today; lock-in on order create is on the roadmap.

Cancellation and webhooks have both shipped — see Cancel an order below and Webhooks.


Cancel an order

POST /orders/{id}/cancel

You have one hour from placing an order to cancel it, in full, automatically.

That hour is not arbitrary: it is exactly how long an order stays invisible to print partners. Inside it nothing has been cut, printed or paid out, so cancelling costs nothing and the money goes straight back. After it, the work has been released for production and cancelling becomes a support conversation.

Accepts either the order id or its reference.

curl -X POST "https://developer.allthe.com/api/v1/orders/ORD-XYZ12AB34/cancel" \
  -H "Authorization: Bearer pat_live_..."
{
  "id": "ckor2...",
  "reference": "ORD-XYZ12AB34",
  "status": "cancelled",
  "cancelled": true,
  "refunded_gbp": 24.50,
  "pending_manual_refund": [],
  "cancellable_until": "2026-09-27T16:05:11.000Z"
}

| Field | Meaning | | --- | --- | | refunded_gbp | Credited straight back to your allthe balance. | | pending_manual_refund | Payments we will not reverse automatically — a card or direct-debit charge is an external money movement, so it is refunded by hand. Non-empty means money is still owed to you; contact support. | | cancellable_until | When the window closed (or closes). |

Cancelling twice is safe. An already-cancelled order returns 200 with already_cancelled: true, so a retry after a dropped response is not an error.

Errors

| Status | Code | Reason | | ------ | ---- | ------ | | 404 | not_found | Unknown order, or it belongs to another account. | | 409 | cancellation_window_closed | Past the hour. The body carries placed_at and cancellable_until. | | 409 | conflict | Already dispatched or delivered. | | 502 | refund_failed | The refund did not go through, so the order was not cancelled. Safe to retry. |

The refund runs before the cancellation on purpose: if it fails, nothing has changed and you can try again. The reverse order could leave you with a cancelled order you had still paid for.