Docs menu

Reference

REST API

Orders

Read orders with their lines and history, and move them on from new to acknowledged, dispatched and completed.

Buyers place orders in their trade portal. TradeCatalog doesn’t take payment: you invoice as usual. Use the API to pull orders into your ERP or accounts system and to keep their status up to date.

Order statusesLink to this section#

StatusMeaningCan move to
newJust placedacknowledged, cancelled
acknowledgedYou’ve seen it and it’s being pickeddispatched, cancelled
dispatchedOn its waycompleted
completedDonenothing
cancelledCancelled, with a reasonnothing

List ordersLink to this section#

GET/api/v1/orders

Orders newest first. The list covers the 200 most recent orders that match your filters. To pick up new orders, poll with status=new.

NameTypeRequiredDescription
statusstringnoOne of the statuses above.
customerstringnoCustomer id or account code.
limitintegerno1 to 100. Default 100.
offsetintegernoRows to skip. Default 0.
bash
curl "https://tradecatalog.app/api/v1/orders?status=new" \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const res = await fetch('https://tradecatalog.app/api/v1/orders?status=new', {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: orders } = await res.json()
json
{
  "data": [
    {
      "id": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
      "reference": "SO-000142",
      "status": "new",
      "total": 31460,
      "currency": "GBP",
      "poNumber": "PO-88231",
      "createdAt": "2026-09-27T07:48:12.000Z",
      "customer": "Oakfield Joinery"
    }
  ],
  "nextOffset": null
}
FieldTypeDescription
idstringOrder id.
referencestringOrder number buyers see, like SO-000142.
statusstringSee statuses.
totalintegerOrder total before tax, in minor units of currency.
currencystringFixed when the order was placed.
poNumberstring or nullThe buyer’s purchase order number.
createdAtstringWhen it was placed.
customerstringCustomer name. Get the account code from GET /orders/{id}.

Get one orderLink to this section#

GET/api/v1/orders/{id}

The order with its lines and status history.

NameInTypeRequiredDescription
idpathstringyesOrder id.
bash
curl https://tradecatalog.app/api/v1/orders/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const res = await fetch(`https://tradecatalog.app/api/v1/orders/${orderId}`, {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: order } = await res.json()
json
{
  "data": {
    "id": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
    "customerAccountId": "7d2e4f0a-1b3c-4d5e-8f90-a1b2c3d4e5f6",
    "placedBy": "Fq3L0cZ7tN1pW9aYx2Rk",
    "reference": "SO-000142",
    "poNumber": "PO-88231",
    "notes": "Deliver to the Hebden Road site, gate 2.",
    "status": "new",
    "cancelReason": null,
    "currency": "GBP",
    "total": 31460,
    "createdAt": "2026-09-27T07:48:12.000Z",
    "updatedAt": "2026-09-27T07:48:12.000Z",
    "customer": { "name": "Oakfield Joinery", "accountCode": "OAK01" },
    "lines": [
      {
        "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
        "orderId": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
        "productId": "3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c",
        "sku": "HX-8510",
        "name": "Hex bolt M10 x 50 zinc",
        "unitLabel": "Box of 100",
        "qty": 20,
        "unitPrice": 1573,
        "listPrice": 1850,
        "priceLabel": "Brand discount −15%",
        "lineTotal": 31460
      }
    ],
    "events": [
      {
        "status": "new",
        "note": null,
        "createdAt": "2026-09-27T07:48:12.000Z",
        "actor": "Sam Patel"
      }
    ]
  }
}
FieldDescription
customerAccountIdThe customer’s id.
placedById of the buyer who placed it.
notesThe buyer’s delivery or order notes.
cancelReasonWhy it was cancelled, if it was.
linesWhat was ordered at what price. A snapshot: later price changes never alter it. productId is null if the product has since been deleted.
lines[].priceLabelThe rule that set the price, as on Prices.
eventsStatus history, oldest first. actor is the person’s name, or null.

Move an order onLink to this section#

PATCH/api/v1/orders/{id}write key

Changes an order’s status. Returns the updated order in the same shape as GET /orders/{id}.

  • Only the moves in the status table are allowed. Anything else is 400 invalid_request.
  • Cancelling needs a note, which is shown to the buyer as the reason.
  • The buyer who placed the order gets an email each time, with the note if you send one.
  • The change is recorded in the order’s history against the owner who made the key.
NameInTypeRequiredDescription
idpathstringyesOrder id.
statusbodystringyesThe new status.
notebodystringnoUp to 1,000 characters. Required when cancelling.
bash
curl -X PATCH https://tradecatalog.app/api/v1/orders/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "dispatched", "note": "DPD tracking 1554 2210 0931" }'
js
const res = await fetch(`https://tradecatalog.app/api/v1/orders/${orderId}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ status: 'acknowledged' }),
})
const { data: order } = await res.json()
StatusCodeWhen
400invalid_requestThe move isn’t allowed, e.g. “An order that is received can’t be marked completed”, or cancelling without a note.
403insufficient_scopeThe key is read-only.
404not_foundNo such order in this workspace.

Retrying a PATCH that already succeeded returns 400 invalid_request, because the order has moved on. Check the order’s status before treating that as a failure.

Not availableLink to this section#

The API can’t place orders for a buyer, or change an order’s lines, quantities or prices. Buyers place orders in their trade portal; changes to an order are agreed with the customer and invoiced in your own system.