REST API / Orders
REST API / Orders
Orders
Note
reseller_* fields are what's actually charged/refunded (wholesale + shipping). reseller_reference_* fields are a snapshot of your own selling price, for your records only — never charged or refunded.On items,
reseller_reference_price_source is "computed" (auto markup) or "manual" (overridden at creation). Pass retail_unit_price to set a line's price yourself — pricing below wholesale returns a non-blocking warnings array, and the order still goes through.Order status lifecycle
pendingOrder received, awaiting supplier confirmation.confirmedSupplier has confirmed the order.processingOrder is being picked and packed.shippedOrder dispatched. Tracking info available.deliveredDelivery confirmed. Returns now possible.cancelledOrder cancelled. Stock restocked.refundedRefund processed after return approval.partially_cancelledSome items were cancelled and the rest still stand. See the order's cancellations for which ones.partially_refundedPart of the order's value has been refunded. The order itself is not cancelled.Retrying safely
Creating an order is the only call that takes a payment, so it is the only one where a network timeout is genuinely ambiguous — the order may or may not exist. Give every attempt an external_ref and that ambiguity goes away.
Send a reference you chose
Either external_ref in the body or the Idempotency-Key header — they are the same field. Any string up to 200 characters, unique within your account.
If the call times out, just send it again
Byte for byte, same reference. If the first attempt never landed you get a normal 201. If it did, you get 409 — never a second order and never a second charge.
Read the order out of the 409
The conflict carries existing_order with the id, order number, status and payment status of the order you already have. Nothing more to look up.
Or find it later by reference
GET /v1/orders?external_ref=... returns it at any time, which is the way back if you lost the response entirely.
Warning
/v1/ordersList orders
Returns paginated orders with optional filtering by status, supplier, and date range.
Query parameters
pageinteger1limitinteger100statusstringpendingconfirmedprocessingshippeddeliveredcancelledrefundedpartially_cancelledpartially_refundedsupplier_iduuidfrom_datestringto_datestringexternal_refstringResponse
{
"data": [
{
"id": "ord-001",
"order_number": 42,
"status": "pending",
"currency": "GBP",
"reseller_total": 48.96,
"reseller_reference_total": 60.96,
"ship_name": "John Smith",
"ship_city": "London",
"ship_postcode": "SW1A 1AA",
"created_at": "2025-06-24T09:00:00.000Z",
"suppliers": {
"id": "sup-001",
"company_name": "EcoThreads Ltd"
}
}
],
"meta": {
"page": 1,
"page_size": 100,
"total": 1,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
}/v1/orders/{id}Get order
Returns full order detail including all line items, shipping address, tracking info, and supplier contact.
Path parameters
iduuidResponse
{
"data": {
"id": "ord-001",
"order_number": 42,
"status": "shipped",
"currency": "GBP",
"reseller_subtotal": 44.97,
"reseller_shipping": 3.99,
"reseller_total": 48.96,
"reseller_reference_subtotal": 56.97,
"reseller_reference_total": 60.96,
"carrier": "Royal Mail",
"tracking_number": "AB123456789GB",
"tracking_url": "https://track.royalmail.com/AB123456789GB",
"shipped_at": "2025-06-25T14:00:00.000Z",
"ship_name": "John Smith",
"ship_line1": "10 Downing Street",
"ship_city": "London",
"ship_postcode": "SW1A 2AA",
"ship_country": "GB",
"created_at": "2025-06-24T09:00:00.000Z",
"order_items": [
{
"id": "item-001",
"product_name": "Organic Cotton T-Shirt",
"variant_name": "Medium / White",
"sku": "ECO-SHIRT-M-WHT",
"quantity": 3,
"reseller_unit_price": 14.99,
"reseller_subtotal": 44.97,
"reseller_reference_unit_price": 18.99,
"reseller_reference_subtotal": 56.97,
"reseller_reference_list_unit_price": 18.99,
"reseller_reference_price_source": "computed"
}
]
}
}/v1/ordersCreate order
Places a new order with a supplier. Shipping cost is calculated automatically based on the delivery postcode and order weight. Stock is decremented immediately. Each item may optionally include retail_unit_price to override your own reference/selling price for that line (e.g. a one-off discount to your end customer) — this only affects the informational reseller_reference_* fields and never the wholesale amount actually charged. If any line's retail_unit_price is set below your wholesale cost, the response includes a non-blocking warnings array. This is the one endpoint that takes a payment, so send an `external_ref` (or the equivalent `Idempotency-Key` header) on every call. It makes the request safe to retry: a second attempt carrying a reference you have already used cannot create a second order or take a second payment.
Headers
Idempotency-KeystringBody fields
external_refstringRequest body
{
"supplier_id": "5f50e19c-09a0-4b45-8a96-4a9b53a97641",
"items": [
{
"product_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"variant_id": "var-001",
"quantity": 3,
"retail_unit_price": 17.99
}
],
"ship_name": "John Smith",
"ship_line1": "10 Downing Street",
"ship_line2": null,
"ship_city": "London",
"ship_postcode": "SW1A 2AA",
"ship_country": "GB",
"ship_email": "john@example.com",
"ship_phone": "07911123456",
"external_ref": "my-shop-order-9001",
"reseller_note": "Please pack carefully"
}Response
{
"data": {
"order_id": "ord-001",
"order_number": 42,
"status": "pending",
"reseller_total": 48.96,
"reseller_reference_total": 60.96,
"currency": "GBP",
"warnings": [
"One or more items are priced below your wholesale cost."
]
}
}Error responses
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"status": 400,
"details": [
{
"field": "ship_name",
"message": "required"
}
]
}
}{
"error": {
"code": "FORBIDDEN",
"message": "This supplier is not currently accepting orders",
"status": 403
}
}{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "No payment card on file. Add a card in your Feed API dashboard (Settings → Payment) before placing orders.",
"status": 402
}
}{
"error": {
"code": "CONFLICT",
"message": "An order with this external_ref has already been submitted",
"status": 409,
"existing_order": {
"id": "ord-001",
"order_number": 42,
"status": "confirmed",
"payment_status": "paid",
"created_at": "2025-06-24T09:00:00.000Z"
}
}
}/v1/orders/{id}/cancelCancel order
Cancels an order. Only orders with status `pending` or `confirmed` can be cancelled. Stock is restocked automatically.
Path parameters
iduuidResponse
{
"data": {
"order_id": "ord-001",
"status": "cancelled"
}
}Error responses
{
"error": {
"code": "CONFLICT",
"message": "Order cannot be cancelled in status: shipped",
"status": 409
}
}/v1/orders/{id}/returnsList returns
Returns all return requests for an order.
Path parameters
iduuidResponse
{
"data": [
{
"id": "ret-001",
"status": "requested",
"reseller_note": "Item arrived damaged",
"created_at": "2025-06-26T12:00:00.000Z",
"order_return_items": [
{
"id": "ritem-001",
"order_item_id": "item-001",
"quantity": 1,
"reason": "damaged_in_shipping"
}
]
}
]
}/v1/orders/{id}/returnsRequest return
Submits a return request for a delivered order. Only one active return per order is allowed.
Path parameters
iduuidRequest body
{
"items": [
{
"order_item_id": "item-001",
"quantity": 1,
"reason": "damaged_in_shipping",
"reason_note": "Box was crushed on arrival",
"restock": false
}
],
"reseller_note": "Customer reported damage immediately on delivery."
}Response
{
"data": {
"return_id": "ret-001",
"order_id": "ord-001",
"status": "requested"
}
}Error responses
{
"error": {
"code": "CONFLICT",
"message": "Returns can only be requested for delivered orders",
"status": 409
}
}/v1/orders/{id}/status-historyStatus history
Returns the full chronological status change log for an order.
Path parameters
iduuidResponse
{
"data": [
{
"id": "log-001",
"from_status": null,
"to_status": "pending",
"note": "Order created",
"created_at": "2025-06-24T09:00:00.000Z"
},
{
"id": "log-002",
"from_status": "pending",
"to_status": "confirmed",
"note": null,
"created_at": "2025-06-24T11:00:00.000Z"
}
]
}/v1/orders/{id}/shipmentsList shipments
Returns every shipment for an order. An order can have more than one shipment — the flat `carrier`/`tracking_number` fields on the order itself only ever reflect a single shipment, so use this endpoint whenever an order might be split across multiple parcels.
Path parameters
iduuidResponse
{
"data": [
{
"id": "ship-001",
"carrier": "Royal Mail",
"tracking_number": "AB123456789GB",
"tracking_url": "https://track.royalmail.com/AB123456789GB",
"status": "delivered",
"shipped_at": "2025-06-25T14:00:00.000Z",
"delivered_at": "2025-06-27T10:00:00.000Z",
"created_at": "2025-06-25T13:00:00.000Z",
"order_shipment_items": [
{
"id": "shitem-001",
"order_item_id": "item-001",
"quantity": 2
}
]
},
{
"id": "ship-002",
"carrier": "DPD",
"tracking_number": "DPD98765",
"tracking_url": "https://track.dpd.co.uk/DPD98765",
"status": "in_transit",
"shipped_at": "2025-06-26T09:00:00.000Z",
"delivered_at": null,
"created_at": "2025-06-26T08:30:00.000Z",
"order_shipment_items": [
{
"id": "shitem-002",
"order_item_id": "item-002",
"quantity": 1
}
]
}
]
}/v1/orders/{id}/cancellationsList item cancellations
Individual items cancelled from an order without cancelling the order itself — the detail behind a `partially_cancelled` status and behind the `order.items_cancelled` webhook. Only approved cancellations are returned; a pending or rejected request is not something your catalogue should act on. Ordered oldest first, and a plain array rather than a paginated list.
Path parameters
iduuidResponse
{
"data": [
{
"id": "oic-001",
"order_item_id": "item-001",
"quantity": 2,
"reason": "Out of stock at the supplier",
"status": "approved",
"initiated_by": "supplier_initiated",
"created_at": "2025-06-25T11:20:00.000Z"
}
]
}Error responses
{
"error": {
"code": "NOT_FOUND",
"message": "Order not found",
"status": 404
}
}