X3DStudios

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.

GET/api/print/orders/{code}API key

Read one print order belonging to the calling account.

Path parameter
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.
Same key, own orders only
Authenticate with the same x3d_live_ key you submitted with, as Authorization: Bearer or x-api-key. A code that belongs to another account returns 404 rather than 403, so nothing about it leaks.

Request#

curl https://x3dstudios.com/api/print/orders/X3D-K7M2QP \
  -H "Authorization: Bearer $X3D_API_KEY"

Response#

200
{
  "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"
}
Response fields
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#

statusstatusLabelWhat it means
PENDING_PAYMENTAwaiting paymentThe order exists but no money has been taken. Nothing is printed until it is paid.
RECEIVEDReceived — in reviewPaid and waiting for an operator to look at it.
ACCEPTEDAccepted — queued to printChecked and queued. It has not started on a machine yet.
PRINTINGPrintingOn a printer now.
PRINTEDPrinted — preparing to shipOff the plate, being checked and packed. Set automatically when the last farm print job for the order completes, or by an operator.
SHIPPEDShippedHanded to the carrier. tracking is populated at this point.
DELIVEREDDeliveredThe carrier reported delivery, read by our daily carrier check, or an operator marked it. Terminal.
CANCELLEDCancelledStopped before completion. Terminal.
REJECTEDRejectedWe could not print it — geometry, material or plate problems. Terminal.
Every status the endpoint can return, with the label shown alongside it.
Treat the order as intended, not guaranteed
The normal path is PENDING_PAYMENT → RECEIVED → ACCEPTED → PRINTING → PRINTED → SHIPPED → DELIVERED, with CANCELLED and REJECTED as exits. Nothing in the system enforces that ordering, so an operator correcting a mistake can move an order backwards. Handle any status at any poll rather than assuming monotonic progress.

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.

Poll until the parcel ships
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));
  }
}
StatuserrorWhen
401Invalid or missing API key.No key, an unrecognised key, or a token that is not an x3d_live_ key.
404Order not found.No order with that code, or it belongs to another account. The two cases are indistinguishable on purpose.
A link you can give your own customer
The submit response also returns statusUrl — /print/order/{code}. That page needs no login and shows the same stages in plain language, so you can forward it instead of building your own status screen.

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.

Related guides