Errors return JSON in the following shape. Treat the HTTP status and error.code as the contract; display messages can change.
{
"error": {
"code": "invalid_request",
"message": "Items must reconcile to the order amount."
}
}- HTTP 400
invalid_request · invalid_idempotency_key · invalid_return_url · unregistered_return_url - Correct the fields, idempotency header or registered return URL before retrying.
- HTTP 401
unauthorized - Check the complete key, mode, expiry and revocation status. The tenant and product must also be active.
- HTTP 403
forbidden - Check orders_read / orders_write permission and any configured merchant IP restrictions.
- HTTP 404
not_found - Check the resource ID, merchant and environment. Other-merchant resources are intentionally indistinguishable from missing ones.
- HTTP 409
idempotency_conflict - The reference or key was used with different contents. Keep the original request for a retry; use a new reference for a different order.
- HTTP 413 / 431
body_too_large · headers_too_large - Reduce payload size. Request bodies are limited to 64 KiB; combined header values to 16 KiB.
- HTTP 429
rate_limited - Honor Retry-After (currently 60 seconds), then retry with backoff and the same idempotency key.
- HTTP 503
unavailable - Retry temporary failures with bounded exponential backoff and jitter. Preserve the same request and idempotency key.
Current merchant API limits are 120 requests per minute per IP and 300 authenticated requests per minute per tenant and mode. Respect Retry-After rather than polling rapidly.
All endpoints reject unexpected query parameters. Send JSON for POST requests. Monetary values are integer cents; timestamps are UTC. A replacement session requires milliseconds even though order creation also accepts timestamps without them.