Skip to content

Errors

Every app route — everything you call with an app token — reports a failure in one shape:

{
"error": {
"code": "missing_scope",
"message": "This operation requires the write_products scope.",
"scope": "write_products",
"request_id": "0HN7…"
}
}
Field Meaning
code A stable, machine-readable identifier. Branch on this, never on message.
message A human-readable explanation. Its wording can change; do not parse it.
scope Only on missing_scope: the scope the operation needs.
request_id Quote it when you contact support — it finds the request in our logs.

The one exception is the token endpoint, which follows RFC 6749 instead: {"error":"invalid_client","error_description":"…"}. See credentials & tokens.

Some routes also keep their own typed refusal body where the refusal carries detail an envelope cannot — for example the metaobject bulk request-level refusals ({ "code", "error" }) and their per-row results. Those are documented on the route’s page.

Status code Meaning What to do
400 invalid_request The request is malformed or breaks a documented limit. Fix the request. Do not retry unchanged.
400 idempotency_key_required The route requires an Idempotency-Key and none (or a blank one) was sent. Send one. See idempotency.
401 invalid_token Token missing, unknown, expired or revoked, or the installation was removed or the app suspended. Carries WWW-Authenticate: Bearer error="invalid_token". Get a new token once. If that fails too, stop and alert — the installation is gone or disabled.
401 tenant_not_active The store itself is not active. Do not retry. Tell the merchant.
403 wrong_store The token was issued for a different store than the domain you called. Call the store the token belongs to, or exchange credentials on this store’s domain.
403 missing_scope Your installation lacks the scope this operation requires; scope names it. Carries WWW-Authenticate: Bearer error="insufficient_scope". Ask the merchant to grant it.
404 not_found The record does not exist in this store. A record belonging to another store is always 404, never 403. —
409 conflict The request conflicts with the current state of the record. Re-read the record and decide.
409 idempotency_in_progress An idempotent request with this key is still running. Carries Retry-After: 1. Wait, then retry with the same key.
409 idempotency_unreplayable The original request succeeded, but its response was too large to store. Do not retry; the work was done.
413 payload_too_large The body exceeds the route’s size limit. Split the request.
415 unsupported_media_type The Content-Type is not one the route accepts. Send application/json.
422 validation_failed The body is well-formed but a value is refused. Fix the value; message says which.
422 idempotency_key_reuse This Idempotency-Key was already used with a different request. Use a new key for a new request.
429 rate_limited The installation’s request budget is spent. Carries Retry-After. Wait Retry-After seconds. See rate limits.
503 provider_unavailable A service the operation depends on is unavailable. Retry with backoff.
5xx internal_error A platform fault. Internals are never included. Retry with backoff; idempotent writes are safe to retry.

Partial success is normal for batch routes

Section titled “Partial success is normal for batch routes”

Batch routes — bulk product updates and media imports — answer 200 when the request was valid, and report each row separately. A 200 with failed: 3 means three rows did not apply. Always read the per-row status.