Skip to main content
Every error returns the same JSON shape:
Note the field is detail, not message. Match on code — it is stable and safe to branch on. detail is human-readable and may be reworded without notice.
Some errors carry extra fields alongside code and detail. price_moved includes the current total, item_unavailable may include unavailable_ids and unknown_ids, a per-key rate_limit_exceeded includes bucket, limit_per_min and retry_after_sec, too_many_streams includes max_connections and retry_after_sec, unsupported_game includes supported_app_ids, price_drift includes current_total_usd and min_total_usd, and price_below_market includes market_usd and floor_usd. Ignore unknown fields rather than rejecting the body.

Authentication

Rate limits

Reading market data

Buying

An order that was accepted and fails later is not an HTTP error. It ends failed or cancelled, the money comes back in refund, and fail_reason, fail_side and fail_message say why. Every code and what to do about it is listed under why an order failed.

P2P listing

Instant sell

The full list is in the Instant Sell guide.

Webhooks

MCP server

Not available through the API


Retry rules

The distinction that matters is whether money moved.

Safe to retry

429 (after Retry-After), price_updating, market_unavailable, concurrent_update, held_balance_blocked (once the hold clears). Respect the returned error code and keep the same order identifier.

Do not retry unchanged

400, 401, 403, invalid_webhook_url, unsupported_item. The request is wrong; repeating it produces the same error and, on auth failures, an IP ban.

Decide, then retry

price_moved and item_unavailable. The market changed under you. Re-read the listing, apply your own pricing rule, and issue a new order with a new idempotency key.

Check before retrying

order_failed, upstream_timeout, idempotency_in_progress, and any timeout on POST. Call GET /v1/orders/info with your custom_id first — the order may already exist.
A lost purchase response leaves the outcome unknown. Successful responses are cached for up to 24 hours. Once the cache expires, the same identifier can start another purchase. Keep the original order pending until you reconcile it.