Skip to content

Errors

Errors use HTTP status codes and a consistent JSON body, so a client can branch on the code and show the message.

Error body

422 Unprocessable Entity
json
{
  "error": {
    "code": "validation_failed",
    "message": "Product is invalid",
    "details": {
      "fieldErrors": {
        "sku": "SKU may only contain letters, digits, '.', '_' and '-' (no spaces or slashes) and must start with a letter or digit",
        "attributes.volume_ml": "Must be a whole number",
        "translations.ar.name": "Name must be at most 500 characters"
      }
    },
    "requestId": "req_7Qm2cX5fGa1b9KpZ"
  }
}
  • code is stable and machine-readable; message is human-readable and may change.
  • details.fieldErrors maps dotted field paths (images.0.url, prices.SAR, attributes.color) to messages. Root-level problems use _root.
  • requestId (also the X-Request-Id header) identifies the request in our logs — include it when you contact support.

Status codes

StatusCodeWhen
400bad_requestThe request could not be understood.
401unauthorizedNo API key, or the key is invalid, expired or revoked.
403forbiddenThe key lacks a scope the endpoint needs (the message names it).
404not_foundThe record does not exist — or belongs to another workspace.
409conflictDuplicate SKU or code, a stale expectedVersion, or a paused channel.
409idempotency_in_progressA request with the same Idempotency-Key is still running.
412precondition_failedIf-Match did not match the product's current version.
413payload_too_largeThe body is larger than the endpoint accepts.
422validation_failedThe input is invalid; see details.fieldErrors.
422idempotency_key_reusedThe Idempotency-Key was already used for a different request.
429rate_limitedToo many requests; wait Retry-After seconds.
500internal_errorSomething failed on our side. Retry later; quote the requestId.

Partial success

POST /products/bulk never fails as a whole because of bad items: it answers 200 with one result per item, and failed items carry their own error object with the same code, message and fieldErrors. Background jobs (imports, exports, publishing) report row errors on the job (errors, errorCount) instead of in the HTTP response.

Retrying

  • Retry 429 after the Retry-After delay, and 500/502/503/504 with exponential backoff.
  • Do not retry 4xx errors other than 409 idempotency_in_progress and 429 — fix the request instead.
  • Make retried POSTs safe with an Idempotency-Key header, or use naturally idempotent calls (PUT by SKU, bulk upserts).