Partner API
Fulfillment partners who don't run a Shopify store connect to LGL through the Partner API — the same program as Shopify-connected partners, delivered as a simple REST API: you pull the orders assigned to you, ship them, and post the tracking back.
Full reference
This page is the orientation. The complete interactive reference — every endpoint, schema, and example — lives at api.livegoodlogistics.com/partner/docs.
Authentication
Contact LGL to receive your API keys, then send one on every request:
bash
curl "https://api.livegoodlogistics.com/partner/manifest?status=new" \
-H "X-API-Key: your_api_key_here"You get two:
| Key | Prefix | What it is |
|---|---|---|
| Sandbox | sp_test_ | A real partner identity pointed at a test location. Same endpoints, same webhooks, same signatures — build against this first. |
| Production | sp_live_ | Your live warehouse. Real customer orders. |
Nothing in the API branches on which key you use, so you write your integration once and swap the key at cutover. Sandbox orders are kept out of invoicing and cancelled automatically after a grace window (12 hours by default), so you can test freely and leave the data behind — the one exception being an order you already fulfilled, which can no longer be cancelled and just stays closed.
The fulfillment workflow
Four endpoints, in order:
| Step | Endpoint | What it does |
|---|---|---|
| 1 | GET /manifest?status=new | List orders assigned to you that no one has claimed |
| 2 | POST /acknowledge | Claim an order so it's yours to fulfill |
| 3 | GET /manifest?status=processing | See everything you've claimed |
| 4 | POST /fulfill | Ship it — post the tracking number and carrier |
Two more for the exceptions:
- Can't fulfill an order at all (out of stock, damage)?
POST /rejectwith a reason — we're alerted immediately and take care of the customer. - Claimed something by mistake?
POST /releasequietly puts it back in the pool.
What the manifest gives you
Each order includes our reference numbers, the destination (name and shipping address — never the customer's email or phone), any gift note, and the line items with SKUs and quantities. The same rules as Shopify-connected partners apply: include the gift message with the package, and never include prices or invoices in the box.
Webhooks — skip the polling
Prefer push? Register your own HTTPS endpoint with your API key — no email to LGL needed:
bash
curl -X PUT "https://api.livegoodlogistics.com/partner/webhook" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"url":"https://your-app.example.com/lgl-webhooks"}'The response carries your signing secret (whsec_…) — shown only once, so store it before you close the terminal. Then prove the endpoint works:
bash
curl -X POST "https://api.livegoodlogistics.com/partner/webhook/test" \
-H "X-API-Key: your_api_key_here"That sends a real webhook.test event and tells you the HTTP status your endpoint returned, so a wrong URL or a failing signature check surfaces now rather than on your first live order.
| Event | When |
|---|---|
order.created | A new order is assigned to you |
order.updated | The shipping address or gift note changed on an unshipped order |
order.cancelled | The order was cancelled — don't ship it |
Every delivery carries X-LGL-Signature (HMAC-SHA256 of the raw body with your signing secret) so you can verify it's really us, and X-LGL-Event-Id, which is stable across retries — dedupe on it. Sign over the raw bytes; re-serializing the JSON changes it and the comparison fails.
Subscribe to a subset by passing events to PUT /webhook — send [] for all of them; omitting the field leaves your current subscription unchanged.
Manage it all yourself: GET /webhook for the current config, POST /webhook/rotate-secret, DELETE /webhook, and GET /webhook/deliveries to see recent attempts and why any of them failed.
Keep the poll as a backstop
Answer 2xx within 10 seconds. We retry up to three times, then stop — so webhooks are the fast path, not a guarantee. Keep a periodic GET /manifest?status=new sweep running; that endpoint is always the source of truth.
Inventory — tell us what you have
Push your stock levels and we'll stop selling what you don't have:
bash
curl -X POST "https://api.livegoodlogistics.com/partner/inventory" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"items":[{"sku":"YOUR-SKU-1","quantity":42},{"sku":"YOUR-SKU-2","quantity":0}]}'quantityis units on hand — an absolute count, not a delta. Send what's on your floor. Don't sendavailable: we derive that by subtracting units already committed to open orders, and sending it in place ofquantityis rejected rather than silently mis-stored.- SKUs you leave out are untouched, so a partial feed is safe.
GET /inventorylists every SKU you're allowed to set, with the numbers we currently believe. LGL decides which products you supply; anything else comes back asnot_stockedrather than being created.- Push whenever stock moves. Hourly is plenty, daily is the floor — after 48 hours of silence we flag it internally, because by then we're selling from a number you last confirmed two days ago.
Good to know
- Poll politely. Every few minutes is plenty — orders don't expire, and claims are exclusive to you once acknowledged.
- Partial shipments are supported. Fulfill the line items that ship now, then call
POST /fulfillagain for the rest. Two things make this safe: every quantity we give you is what is still owed (a line you've fully shipped disappears from the manifest), and a partial shipment keeps your claim — the remainder is never offered to another partner. Thecompletefield in the response tells you whether anything is outstanding. - Tracking does the rest. Once you
POST /fulfill, the tracking number flows to the retailer and their customer automatically. - Getting paid works the same as for every partner: a weekly statement of what you shipped at the agreed cost.
The API is actively evolving — if your integration needs something it doesn't do yet, talk to us: [email protected].
