Authentication and authorization
insufficient_scope (403)
insufficient_scope (403)
The key is valid but lacks the scope for this route. The message names the exact
scope needed.Fix: add that scope to the key in Settings, API keys. No new key needed.
Remember read, write and delete are separate grants. See Scopes.
Request problems
invalid_body (400)
invalid_body (400)
The most common refusal on the API. The body had an unknown field, a field of the
wrong type, or a value the endpoint cannot accept. The message names the field.Unknown fields are refused rather than ignored, at every nesting depth. A stray key
inside
images[0] is caught, not silently dropped.Fix: read the field named in the message and check it against the endpoint’s
schema in the reference.malformed_json (400)
malformed_json (400)
The body was not parseable JSON at all: a trailing comma, an unclosed brace, a
single-quoted string.Fix: validate the JSON your client is producing. This is usually string
concatenation where serialisation was intended.
invalid_query (400)
invalid_query (400)
A query parameter was unknown, had an invalid value, or the cursor was rejected.A cursor is rejected if it was tampered with, or if it came from a different
endpoint. See Pagination.Fix: check parameter spelling against the reference, and pass
next_cursor back
exactly as given.invalid_text (400)
invalid_text (400)
A string contained bytes that are not accepted anywhere on this API: control
characters, bidirectional overrides, or invalid UTF-8.These are refused because they render inconsistently and can be used to make a
stored value display as something other than what it is.Fix: send valid UTF-8 text without control characters.
payload_too_large (413)
payload_too_large (413)
The body exceeded 1 MB.Fix: for bulk work, send several smaller requests rather than one large one. For
file content, use the file upload endpoints rather than embedding bytes in JSON.
endpoint_not_found (404) and method_not_allowed (405)
endpoint_not_found (404) and method_not_allowed (405)
The path is not mounted, or the route does not accept that method.Fix: check the path against the reference, including the
/api/v1 prefix. A
405 usually means a POST where the route takes PATCH.Idempotency
idempotency_key_required (400)
idempotency_key_required (400)
A write arrived without an
Idempotency-Key header. It is mandatory on every write.Fix: generate a unique key per logical operation. See Idempotency.idempotency_key_in_progress (409)
idempotency_key_in_progress (409)
Another request with this key is executing right now.Fix: wait briefly and retry with the same key. You will get the first request’s
stored response. This is expected under concurrency and is not an error in your
integration.
idempotency_key_reused (409)
idempotency_key_reused (409)
This key already completed successfully for a different request body.A key is spent by what it did. A prior
4xx does not spend it, so this code means
something was genuinely created under that key already.Fix: use a fresh key. If you see this unexpectedly, your key generation is
probably deriving from something that repeats.State and business rules
invalid_transition (409)
invalid_transition (409)
The record cannot move from its current state to the requested one, such as pausing
a campaign that is not sending.Fix: read the record’s current status first. Retrying will not help until the
state changes.
Conflict codes ending in _taken (409)
Conflict codes ending in _taken (409)
A uniqueness constraint, such as
name_taken, slug_taken or code_taken.Fix: choose a different value. For a slug, append a discriminator rather than
retrying the same one.invalid_currency and currency_not_supported (400)
invalid_currency and currency_not_supported (400)
invalid_currency means the code is not an active ISO 4217 currency.
currency_not_supported means it is real but your store is not configured for it.Fix: for the first, correct the code. For the second, enable the currency in
your store settings. See Money.invalid_amount and invalid_quantity (400)
invalid_amount and invalid_quantity (400)
An amount or quantity was negative, zero where that is not allowed, or beyond the
permitted bound.Fix: amounts are integers in minor units. If you sent
19.99 expecting $19.99,
read Money.Throttling and server errors
rate_limited (429)
rate_limited (429)
You exceeded either the per-family budget of 120 per minute or the global ceiling of
300 per minute.Fix: sleep for
Retry-After seconds, then retry. Your idempotency key is not
consumed by a 429. See Rate limits.internal (500)
internal (500)
Something failed on our side. This is not caused by your request.Fix: retry with exponential backoff. If it persists, contact support with the
x-request-id from the response. See Retries.