Skip to main content
Every non-2xx response from /api/v1 uses one machine-recoverable envelope. The code is stable and machine-readable. documentation_url links to the matching section on this page. field_errors, when present, name the exact field or filter clause at fault.
string
One of the eight stable codes below.
boolean
Whether retrying the same request could succeed. Only rate_limited and internal_error are retriable. Never retry a 4xx validation or auth error unchanged.
integer | null
How long to wait before retrying, when set. A 429 also carries a Retry-After header.
string
A suggested next step that may resolve the problem, when one exists.
string
Echoed in the X-Request-Id response header and our logs. Include it when contacting support.
array
Per-field details: {field, issue, acceptable_values?}. See the issue code catalog.
When a select value is rejected, field_errors[].acceptable_values carries the exact set that would have passed. An agent can use it to fix the payload and retry without a human.

unauthorized

HTTP 401 · is_retriable: false The request carried no API key, an invalid key, or an expired key.
How to fix: send Authorization: Bearer mk_live_... on every request. If the key was valid before, check its expiry in Settings → API keys and mint a replacement. Retrying the same request unchanged will never succeed.

insufficient_scope

HTTP 403 · is_retriable: false The key is valid but does not hold every scope the operation requires. The message names the missing scope(s).
How to fix: issue a key with the named scopes, or (for an OAuth-connected agent) reconnect and grant them on the consent screen. The scope table maps every operation to its scope.

forbidden

HTTP 403 · is_retriable: false The key is valid and scoped, but the operation is disabled. Today that means deletes during the beta.
How to fix: build against create, update, and upsert for now; contact support to discuss enabling destructive actions.

not_found

HTTP 404 · is_retriable: false The resource does not exist in your workspace, or the path itself is unknown.
How to fix: re-resolve the id (GET /v1/products?filter[sku]=...). Ids never change, so a 404 on a previously valid id means the entity was deleted. Note the tenancy rule: an id belonging to another workspace is a uniform 404, indistinguishable from an id that never existed. There is no cross-tenant 403. A 404 on the path itself means the endpoint doesn’t exist; check GET /api/v1/openapi.

validation_failed

HTTP 400 · is_retriable: false The request was understood but rejected. The cause is a malformed body, an unknown attribute key, a bad filter clause, or a value that fails its data type or acceptable values. field_errors names each fault.
How to fix: walk field_errors and correct every entry. All faults are reported at once, not one per request. The issue code catalog below explains each code. For unknown keys, discover the schema with GET /v1/attributes?type=<type>. For rejected select values, use the echoed acceptable_values.

rate_limited

HTTP 429 · is_retriable: true Too many requests. Limits are enforced at the edge during the beta, and no fixed numbers are published.
How to fix: honor the Retry-After header (mirrored in retry_after_seconds) and back off. Reduce round-trips structurally: batch reads with filter[id][in] / filter[sku][in], batch writes with POST /{resource}/batch, and raise limit toward 200 instead of paging in small steps.

conflict

HTTP 409 · is_retriable: false The operation contradicts existing data. Either an upsert matched more than one existing entity (the message carries the matching ids), or a write hit a uniqueness constraint.
How to fix: for upsert conflicts, deduplicate the listed entities (or PATCH the one you mean directly by id) and re-run. Retrying unchanged returns the same conflict.

internal_error

HTTP 500 · is_retriable: true Something failed on our side. The request may or may not have taken effect.
How to fix: retry with exponential backoff. For writes, prefer idempotent forms (upsert, batch with a merge_key) so a retry after an ambiguous failure cannot double-create. If it persists, contact support with the request_id.

Field error issue codes

field_errors[].issue carries a stable code for every fault the query parser, filter validator, and write validator can raise. There is one exception. When a request body fails its structural schema (wrong JSON types, unknown top-level fields), issue carries the human-readable schema message instead of a code.

Query, filter, and sort issues

Write issues