Skip to main content
An order moves through a small, stable set of public statuses. Every read of an order — GET /v1/orders/{id}, GET /v1/orders, and the POST /v1/orders response — reports one of these five words. They are deliberately narrower than our internal fulfillment states, so your integration never depends on an internal detail that could change.

The five statuses

A terminal status never changes again — stop polling once you see one. The only exception is that a completed order can later become refunded if it is refunded by support.

How an order progresses

A sandbox order (placed with a test key) is fulfilled synchronously: it is born completed with deterministic fake codes, so you can exercise the full read-and-reveal flow without waiting.

Example

A completed order read with a test key, copied from a real call:

Webhook events

Subscribe a webhook and we deliver a signed event when an order reaches a notable state:
A failed order emits no webhook, and neither do pending or processing. A subscriber that never polls will wait forever for an order that failed: to detect a failure, poll the order until it reaches a terminal status. More generally, webhook delivery is at-least-once and best-effort — treat a webhook as a fast signal, never the sole source of truth, and reconcile by polling.
The success event is named order.fulfilled, while the status you read is completed: the two name the same outcome from two vocabularies (events and statuses). There is no order.completed event and no fulfilled status.

Internal states, for reference

Our fulfillment engine uses a longer set of states internally. You never receive these, but the table maps them to the public status you do receive, so a value seen in a support conversation is unambiguous: