Skip to navigation

Place an order

View as Markdown

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 reference, unique per account: letters, digits and _ - : ~, up to 100 characters. Read the order back by it with GET /v1/orders/merchant/{merchant_order_id}.
  • 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_idintegerRequired
The numeric item id.
quantitydoubleOptional

Integer count for key items (default 1); decimal amount for top-up items (required); omit for service items.

merchant_order_idstringOptionalformat: "^[A-Za-z0-9_:~-]+$"<=100 characters

Your reference id, unique per account (optional): letters, digits and _ - : ~. Read the order back by it with GET /v1/orders/merchant/{merchant_order_id}.

fieldsmap from strings to stringsOptional

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.

pricedoubleOptional>=0

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.

idstringOptionalformat: "uuid"
The order id.
itemintegerOptional
Numeric item id.
item_namestringOptional
item_product_typeenumOptional
Allowed values:
quantitydoubleOptional
delivered_quantityintegerOptional

Units delivered so far (relevant for key items / partials).

pricedoubleOptional
Amount charged, in major currency units.
refund_amountdoubleOptional

Amount refunded for undelivered units (partial / failed).

fieldsmap from strings to stringsOptional

The submitted input fields (choice values shown as their display name).

statusenumOptional

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.

errorstringOptional

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_messagestringOptional

Human-readable text for error; empty whenever error is empty.

codeslist of stringsOptional

Delivered key/code strings (key items only).

merchant_order_idstringOptional
sourceenumOptional
Allowed values:
created_byobject or nullOptional

Who placed the order. For an order placed through the API, the API key that placed it — id is the key’s id and email is empty — since a key belongs to the account, not to a person. For an order placed in the dashboard, the person and their address.

created_atdatetimeOptional
completed_atdatetime or nullOptional

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.

webhookobject or nullOptional

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