/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.
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).
forbidden
HTTP 403 ·is_retriable: false
The key is valid and scoped, but the operation is disabled. Today that means deletes during the
beta.
not_found
HTTP 404 ·is_retriable: false
The resource does not exist in your workspace, or the path itself is unknown.
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.
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.
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.
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.
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.