From order to shipped
One production order, threaded end to end — create, schedule, run, verify, and trace — using only the REST API.
This guide follows a single order all the way through Factory OS: a run of 1,000 × Bottle Cap 28mm for batch M062026-UBH. Every step is a real endpoint, and the whole flow works with manual quantity logging — no connected machines required. Where the IoT add-on changes a step, a callout shows how.
All requests are scoped to a factory slug and authenticated with a Supabase JWT:
export XENTR_TOKEN="<your-supabase-jwt>"
export FACTORY="penang-plant" # your factory slug1. Create the order
An order references a product and a target quantity. The optional batchNumber is your own identifier — it rides along to every downstream record.
curl -X POST https://api.xentr.ai/api/factories/$FACTORY/production-orders \
-H "Authorization: Bearer $XENTR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"productId": "a1b2c3d4-...",
"quantityTarget": 1000,
"batchNumber": "M062026-UBH",
"plannedStart": "2026-04-20T08:00:00Z",
"plannedEnd": "2026-04-20T16:00:00Z"
}'The order is created in draft. Keep the returned id — every step below uses it as $ORDER.
2. Schedule it
Scheduling assigns the order to a machine (or work area) and moves it to scheduled. Use mode: "single" for one machine; methodId selects the routing.
curl -X POST https://api.xentr.ai/api/factories/$FACTORY/production-orders/$ORDER/schedule \
-H "Authorization: Bearer $XENTR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "mode": "single", "machineId": "PRESS-01", "methodId": "..." }'3. Start production
State changes go through one endpoint — /transition with a toState — never by editing a status field. This keeps the audit trail, single-active-order rule, and any quality holds intact.
curl -X POST https://api.xentr.ai/api/factories/$FACTORY/production-orders/$ORDER/transition \
-H "Authorization: Bearer $XENTR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "toState": "in_production" }'4. Log output as it runs
On the lite plan you append production counts by hand as parts come off the press. Each entry adds to the running total.
curl -X POST https://api.xentr.ai/api/factories/$FACTORY/production-orders/$ORDER/log-quantity \
-H "Authorization: Bearer $XENTR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "quantityProduced": 250, "quantityGood": 248, "quantityRejected": 2 }'With the IoT add-on, you skip this step. When a machine is connected — e.g. a FANUC control via the FOCAS collector — the real part count rolls up automatically against the running order, and log-quantity is only used for manual corrections. The manual path above is the default for the lite plan; the API is identical either way.
5. Complete the run
When the target is met, transition to completed. The order moves into the QA queue.
curl -X POST https://api.xentr.ai/api/factories/$FACTORY/production-orders/$ORDER/transition \
-H "Authorization: Bearer $XENTR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "toState": "completed" }'6. Verify quality
A QA reviewer confirms the final good-vs-rejected split and signs the order off. quantityGood + quantityRejected should equal quantityFinal.
curl -X POST https://api.xentr.ai/api/factories/$FACTORY/production-orders/$ORDER/verify \
-H "Authorization: Bearer $XENTR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"quantityFinal": 1000,
"quantityGood": 988,
"quantityRejected": 12,
"notes": "12 rejects, OD oversize. See NCR-2026-0417-001."
}'7. Trace and ship
Every transition the order went through — who moved it, when, and why — is queryable, so the batch carries a complete history from draft to closed.
curl https://api.xentr.ai/api/factories/$FACTORY/production-orders/$ORDER/transitions \
-H "Authorization: Bearer $XENTR_TOKEN"That history, the verified quantities, and the batchNumber are the shippable record — no machine telemetry needed to produce it.