Get order status
Read one print order back by its X3D- code: where it is in the queue, whether it is paid, and the carrier tracking number once the parcel is handed over.
This endpoint answers one question: where is order X3D-…? It returns the current stage, whether the order is paid, what was ordered, and the tracking number once there is one. It is the endpoint you poll after a submit.
/api/print/orders/{code}API keyRead one print order belonging to the calling account.
codestringrequired- The public order code from the submit response: X3D- followed by six uppercase characters. Matched exactly and case-sensitively — a lowercased code returns 404. The alphabet excludes 0, 1, I, L and O, so those characters never appear in a real code.
Request#
curl https://x3dstudios.com/api/print/orders/X3D-K7M2QP \
-H "Authorization: Bearer $X3D_API_KEY"Response#
{
"code": "X3D-K7M2QP",
"status": "SHIPPED",
"statusLabel": "Shipped",
"paid": true,
"fileName": "bracket.stl",
"material": "pla",
"color": "Black",
"quality": "standard",
"quantity": 2,
"estimatedCost": 12.04,
"currency": "USD",
"tracking": { "number": "9400111899223197428490", "carrier": "usps" },
"shipTo": { "name": "Ada Lovelace", "city": "Austin", "state": "TX", "country": "US" },
"email": "[email protected]",
"notifyEmails": ["[email protected]"],
"createdAt": "2026-09-02T14:11:07.220Z",
"updatedAt": "2026-09-05T09:41:52.006Z"
}codestringoptional- The order code, echoed back.
statusstringoptional- Machine-readable stage. Branch on this, not on statusLabel.
statusLabelstringoptional- The same stage in words, safe to show a customer. Falls back to the raw status if we ever add a stage before this table catches up.
paidbooleanoptional- Whether money has been taken. false means the order is waiting at PENDING_PAYMENT.
fileNamestringoptional- The file name as submitted.
materialstringoptional- Material key as ordered: pla, petg, abs, asa or tpu.
colorstringoptional- Colour as ordered. "Default" when none was sent, meaning our choice of a stock spool, priced at the material rate.
qualitystringoptional- standard or premium.
quantitynumberoptional- Units ordered.
estimatedCostnumberoptional- Total in USD: print plus postage, plus the $25 second-AMS fee on a sliced plate of five or more filaments. This is the amount charged.
currencystringoptional- Always "USD".
trackingobject | nulloptional- null until the parcel is handed over. Then { number, carrier }, where carrier can itself be null if it was not recorded.
shipToobjectoptional- name, city, state, country only. The street and postal code are deliberately not returned.
emailstringoptional- The order's main contact, the first address sent with the order. It gets every order email.
notifyEmailsstring[]optional- The other addresses that get a copy of every order email: the confirmation, printed, shipped with tracking, and delivered. An empty array when there are none. Set them when you submit; see /docs/api/submit-order.
createdAtstringoptional- ISO 8601 timestamp of submission.
updatedAtstringoptional- ISO 8601 timestamp of the last change. Use it to detect movement between polls.
Status values#
| status | statusLabel | What it means |
|---|---|---|
| PENDING_PAYMENT | Awaiting payment | The order exists but no money has been taken. Nothing is printed until it is paid. |
| RECEIVED | Received — in review | Paid and waiting for an operator to look at it. |
| ACCEPTED | Accepted — queued to print | Checked and queued. It has not started on a machine yet. |
| PRINTING | Printing | On a printer now. |
| PRINTED | Printed — preparing to ship | Off the plate, being checked and packed. Set automatically when the last farm print job for the order completes, or by an operator. |
| SHIPPED | Shipped | Handed to the carrier. tracking is populated at this point. |
| DELIVERED | Delivered | The carrier reported delivery, read by our daily carrier check, or an operator marked it. Terminal. |
| CANCELLED | Cancelled | Stopped before completion. Terminal. |
| REJECTED | Rejected | We could not print it — geometry, material or plate problems. Terminal. |
Polling#
Poll every five minutes while an order is in flight, and stop at a terminal status. There is nothing to gain from a tighter loop: the fastest stage change happens when the card clears, and everything after that moves on the timescale of a print.
const TERMINAL = new Set(["DELIVERED", "CANCELLED", "REJECTED"]);
async function waitForTracking(code) {
for (;;) {
const res = await fetch(`https://x3dstudios.com/api/print/orders/${code}`, {
headers: { Authorization: `Bearer ${process.env.X3D_API_KEY}` },
});
if (!res.ok) throw new Error(`${res.status} ${(await res.json()).error}`);
const order = await res.json();
if (order.tracking) return order.tracking;
if (TERMINAL.has(order.status)) return null;
await new Promise((r) => setTimeout(r, 5 * 60 * 1000));
}
}| Status | error | When |
|---|---|---|
| 401 | Invalid or missing API key. | No key, an unrecognised key, or a token that is not an x3d_live_ key. |
| 404 | Order not found. | No order with that code, or it belongs to another account. The two cases are indistinguishable on purpose. |
Questions
How often should I poll?
Every five minutes is plenty, and every fifteen is fine once the order is PRINTING — a print runs for hours. Stop polling at DELIVERED, CANCELLED or REJECTED, which do not change again.
Why do I get 404 for an order I know exists?
Either the code belongs to a different account, or the case is wrong. Codes are uppercase and matched exactly, so x3d-k7m2qp does not find X3D-K7M2QP. An order that belongs to somebody else returns the same 404, so the endpoint never confirms that a code exists.
When does the tracking number appear?
When an operator ships the parcel and records the number, which is normally the same moment status becomes SHIPPED. Before that, tracking is null. Everyone on the order is emailed the number at the same moment.