Connecting your warehouse to ThroughlineOps

A guide for warehouses and 3PLs. Works with any provider — no specific platform required.

What ThroughlineOps sends you

When a customer sends an order to your warehouse, ThroughlineOps POSTs a JSON payload to an HTTPS endpoint you provide. Every line item carries the fulfilment SKU (your SKU) plus the original customer SKU for reference.

{
  "order_ref": "TL-2034",
  "customer_po_number": "PO-12345",
  "customer_name": "Acme Retail Ltd",
  "delivery_address": "12 High Street, London, SW1A 1AA",
  "notes": "Leave with neighbour if out",
  "line_items": [
    {
      "line_ref": "TL-2034-1",
      "fulfilment_sku": "WH-SKU-001",
      "customer_sku": "ACME-RED-M",
      "product_name": "Red Widget (Medium)",
      "quantity": 2
    },
    {
      "line_ref": "TL-2034-2",
      "fulfilment_sku": "WH-SKU-002",
      "customer_sku": "ACME-BLU-L",
      "product_name": "Blue Widget (Large)",
      "quantity": 1
    }
  ]
}

If you can't accept API orders, ThroughlineOps also supports receiving orders by email (with a CSV attachment) or a manual CSV export the customer uploads to you — no integration work needed on your side.

What your response can include (optional)

Returning identifiers helps match dispatch updates later. All fields are optional — common alternative field names are auto-detected.

{
  "warehouse_order_id": "WH-100231",
  "warehouse_reference": "REF-100231",
  "status": "accepted"
}
FieldMaps toRequired?
warehouse_order_idWarehouse order IDRecommended
warehouse_referenceWarehouse referenceRecommended
statusWarehouse statusOptional
dispatch_numberDispatch numberOptional
tracking_numberTracking numberOptional
carrierCarrierOptional

Dispatch & tracking webhook

When an order ships, send a POST to the customer's ThroughlineOps webhook with the dispatch details. Match by order_ref or any warehouse reference you returned earlier.

POST https://<your-throughlineops-domain>/api/warehouse/webhook/<connection-id>
x-throughline-warehouse-secret: <this connection's secret>
Content-Type: application/json

{
  "order_ref": "TL-2041",
  "dispatch_number": "DSP-44120",
  "tracking_number": "JD0002233445566",
  "carrier": "DPD",
  "status": "dispatched",
  "dispatched_at": "2026-06-12T14:30:00Z"
}

A status of complete, completed, delivered, despatched, dispatched, fulfilled or shipped marks the whole order as dispatched — matched ignoring case. That costs the stock out and makes the order invoiceable, so send one of these only once the complete order has physically left you. There is no partial-dispatch status: if part of an order has shipped, send the tracking details without one of those status values, and post again when the rest goes.

Common alternative field names (e.g. courier_name, tracking_reference) are auto-detected. If you can't send webhooks, customers can enter dispatch details manually — nothing breaks.

New SKU webhook (optional)

If you allocate the product code, tell us the moment you create it and the customer never has to retype it. Same endpoint, same secret as your dispatch callbacks — an event field is what tells the two apart, so a payload without one behaves exactly as it always has.

POST https://<your-throughlineops-domain>/api/warehouse/webhook/<connection-id>
x-throughline-warehouse-secret: <this connection's secret>
Content-Type: application/json

{
  "event": "sku.created",
  "sku": "7000903",
  "warehouse_product_id": "OPT-100231",
  "description": "Miracle Defence and Oil",
  "barcode": null
}
  • • sku.created for a code we haven't seen raises the request for the customer, waiting only on the barcode.
  • • sku.created for one we have confirms it — no duplicate is raised, so replaying your catalogue is safe.
  • • sku.rejected with a reason shows that reason to the customer word for word.
  • • Include request_number when you have one — it is the surest match, and the only one that works before a code exists.

Authentication options

  • • Orders we send you: Bearer token or API-key header — whatever your API expects.
  • • Webhooks you send us: the secret for that connection, in the x-throughline-warehouse-secret header. The customer gets it when they add you, and it is specific to them — so it can be rotated without affecting anyone else.

Always HTTPS. Secrets are never logged.

Testing the integration

  • 1. The customer adds you in ThroughlineOps under Warehouse / 3PL → Add warehouse connection → Custom API.
  • 2. They run Test connection — a health check against your test endpoint.
  • 3. The first real order is the proof. Only an order exercises the payload — every field name below is an assumption until one goes through.
  • 4. You send a dispatch webhook for that order's reference, and we confirm the fields landed. Anything we could not read is named back to you.

If your field names are different

The names in the table above are matched ignoring case and separators, so CourierName, courier_name and courier name are all the same field to us. If yours is not on the list, send us your API documentation and we will add it — that is a one-line change on our side and it works for every customer at once, so there is nothing for you or them to configure.

When you answer our order POST, anything in your reply we do not recognise is recorded by name — never by value — on the customer's connection log. So a field-name mismatch shows up as a named field we could not read, rather than as an order that quietly never updated.

Want to be supported out of the box?

Send us your API docs at hello@throughlineop.co.uk and we will look at supporting you out of the box. Your customer can ask us too — the same address.