Place an order
Places an order for an item and charges your balance. Returns `201`
immediately with `status: "pending"`; the final result arrives via
your webhook and is readable from `GET /v1/orders/{id}`.
### Request fields
- **`item_id`** (required) — the numeric item id.
- **`quantity`** — required for **top-up** items (a decimal amount) and
for **key** items (an integer count, defaults to `1`); **omit for
service** items (always `1`). Must be within the item's
min/max range.
- **`merchant_order_id`** (optional) — your own idempotency/reference
string, unique per account.
- **`fields`** — required for **top-up** and **service** items only,
keyed by the item's field names. Send a **text** field's value as a
string; send a **choice** field's value as the **numeric choice id**.
Key items take no `fields`.
- **`price`** (optional) — the order **total** you expect to be charged.
When sent, a price that no longer matches is rejected with
`400 price_mismatch` (carrying `actual_price`) instead of charging a
different amount. Omit it to be charged at the current price.
Discover an item's `item_id`, product type, quantity bounds and field
definitions from your catalog snapshot (see the **Catalog** guide).
Authentication
AuthorizationBearer
Bearer authentication of the form Bearer <token>, where token is your auth token.
Request
This endpoint expects an object.
item_id
The numeric item id.
quantity
Integer count for **key** items (default `1`); decimal amount for
**top-up** items (required); omit for **service** items.
merchant_order_id
Your reference id, unique per account (optional).
fields
Item input fields (top-up / service only), keyed by field name.
Each value is a string — a text value, or a choice field's id.
price
Optional price guard: the **order total** you expect to be charged
(same units as the response's `price`, max 2 decimals, already
multiplied by `quantity`). When sent, the order is **rejected**
with `400 price_mismatch` — creating and charging nothing — unless
it equals the amount actually charged. Omit it to be charged at the
current price.
Response
Order accepted; fulfillment is in progress.
id
The order id.
item
Numeric item id.
item_name
item_product_type
quantity
delivered_quantity
Units delivered so far (relevant for key items / partials).
price
Amount charged, in major currency units.
refund_amount
Amount refunded for undelivered units (partial / failed).
fields
The submitted input fields (choice values shown as their display name).
status
The order's current state. Three are non-terminal (it will still move) and three are
terminal (it never changes again):
* `pending` — accepted and charged; fulfillment has not started. Non-terminal.
* `processing` — fulfillment is running at the provider. Non-terminal.
* `need_client_code` — PAUSED awaiting a confirmation code the provider sent to your
end customer. Polling stops until you submit it with
`POST /v1/orders/{id}/client-code`, after which the order returns to `processing`.
Only login-method top-ups reach this state, and it is the only status that needs
anything from you. Non-terminal.
* `completed` — every unit delivered (`codes`, `delivered_quantity`). Terminal.
* `partial` — some units delivered, the rest refunded (`refund_amount`,
`delivered_quantity`; `error` is usually empty here). Terminal.
* `failed` — nothing delivered, charge fully refunded (`error`, `error_message`).
Terminal.
An order never returns to `pending` and never moves between terminal statuses;
`need_client_code` -> `processing` is the only backwards transition, and only because
you submitted a code.
error
Stable machine error code (e.g. `OUT_OF_STOCK`, `NOT_ENOUGH_STOCK`, `INVALID_FIELDS`, `INSUFFICIENT_BALANCE`, `ORDER_TIMEOUT`); empty otherwise. Always populated when `status` is `failed`. On `partial` it is usually EMPTY — an ordinary short delivery carries no error code, and only a `partial` that ran out of time reports one (`ORDER_TIMEOUT`), so do not rely on it to explain every shortfall; compare `delivered_quantity` against `quantity` instead. See the Errors guide for the full list of order error codes.
error_message
Human-readable text for `error`; empty whenever `error` is empty.
codes
Delivered key/code strings (key items only).
merchant_order_id
source
created_by
created_at
completed_at
When the order was fully delivered. Set ONLY when `status` is `completed`; stays `null` on `partial` and `failed` even though those are terminal. Test `status` — not this field — to decide whether an order has settled.
webhook
Delivery status of the outbound order-result webhook. Present only for API-placed orders (`source: "api"`) that have a webhook URL configured; `null` for dashboard orders or when no webhook is set. Lets you see whether the terminal event reached your endpoint. See the Webhooks guide.
Errors
400
Bad Request Error
401
Unauthorized Error