What to do
- Branch on the HTTP status and error.code, not the human-readable error.message.
- A 401 requires valid authentication; 403 requires access or plan changes; 409 requires checking the conflicting operation or resource version.
Access denied and retries
- 401
- 401 does not always mean the token has expired. If it has expired, obtain a new token and retry the read at most once. If obtaining a token returns 401, check the key and stop automatic attempts.
- 403
- For 403, check permissions, IP restrictions and the plan. Obtaining a new token does not restore revoked access.
Retry policy
- Use bounded retries with backoff and jitter for transient failures.
- Respect Retry-After when supplied.
- If a write times out, its result may be unknown: keep the same Idempotency-Key and unchanged request when retrying that logical operation.
- The catalog below explains every published error code.
422 / 409
- For prices, an invalid currency format or amount precision returns 422 request.validation_failed.
- A valid currency code that differs from the selected price list returns 409 resource.version_conflict.
- Check the context and versions before retrying.
Error catalog
400request.malformedThe request cannot be parsed.
- What to do
- Check JSON syntax, URL encoding and the structure of the request.
- Retry policy
- Retry after correcting the request.
{
"error": {
"code": "request.malformed",
"fields": null,
"message": "The request could not be read."
},
"meta": {
"request_id": "example-request"
}
}
401authentication.invalid_credentialsThe API key or access token is invalid, expired or revoked.
- What to do
- Check the store URL and credential. Obtain a fresh token with an active API key.
- Retry policy
- Retry after correcting authentication; avoid repeated invalid token requests.
{
"error": {
"code": "authentication.invalid_credentials",
"fields": null,
"message": "The credentials are invalid."
},
"meta": {
"request_id": "example-request"
}
}
401authentication.requiredThe required Authorization header is missing or its scheme is incorrect.
- What to do
- Use ApiKey when requesting a token and Bearer for resource operations.
- Retry policy
- Retry after supplying the correct header.
{
"error": {
"code": "authentication.required",
"fields": null,
"message": "Authentication is required."
},
"meta": {
"request_id": "example-request"
}
}
403authorization.client_ip_unverifiedThe service could not establish a trusted client IP address.
- What to do
- Ask the store operator to check the ingress path. Do not insert forwarding headers yourself.
- Retry policy
- Retry after the trusted connection path is restored.
{
"error": {
"code": "authorization.client_ip_unverified",
"fields": null,
"message": "The client IP address could not be verified."
},
"meta": {
"request_id": "example-request"
}
}
403authorization.ip_not_allowedThe source IP address is outside the key's allowed address list.
- What to do
- Use an approved source address or ask an authorized administrator to edit the key's IP list.
- Retry policy
- Retry only after the address is allowed.
{
"error": {
"code": "authorization.ip_not_allowed",
"fields": null,
"message": "Access from this IP address is not allowed."
},
"meta": {
"request_id": "example-request"
}
}
403authorization.scope_deniedThe key does not have an effective permission required for this operation.
- What to do
- Check the operation's required and conditional permissions, key grants and issuer access.
- Retry policy
- Retry after an authorized administrator grants the required access.
{
"error": {
"code": "authorization.scope_denied",
"fields": null,
"message": "The required permission has not been granted."
},
"meta": {
"request_id": "example-request"
}
}
403entitlements.api_disabledAPI access is disabled for this store.
- What to do
- Ask the store owner to check the active plan and API availability.
- Retry policy
- Do not retry until API access is enabled.
{
"error": {
"code": "entitlements.api_disabled",
"fields": null,
"message": "API access is disabled for this store."
},
"meta": {
"request_id": "example-request"
}
}
403entitlements.limit_exceededThe change would exceed a limit of the current plan.
- What to do
- Check the applicable resource limit and adjust the intended change or plan.
- Retry policy
- Retry after resolving the limit; use a new idempotency key if the request changes.
{
"error": {
"code": "entitlements.limit_exceeded",
"fields": null,
"message": "The operation exceeds a plan limit."
},
"meta": {
"request_id": "example-request"
}
}
403entitlements.operation_disabledThe current plan does not include this operation.
- What to do
- Check the minimum plan shown for the operation.
- Retry policy
- Retry after the plan allows the operation and the key has the required permissions.
{
"error": {
"code": "entitlements.operation_disabled",
"fields": null,
"message": "The current plan does not allow this operation."
},
"meta": {
"request_id": "example-request"
}
}
403entitlements.resource_blockedA plan limit blocks this particular resource.
- What to do
- Ask the owner to resolve the resource's plan restriction.
- Retry policy
- Do not repeat the same request while the resource remains blocked.
{
"error": {
"code": "entitlements.resource_blocked",
"fields": null,
"message": "A plan limit blocks access to this resource."
},
"meta": {
"request_id": "example-request"
}
}
404resource.not_foundThe resource is absent, deleted or not available under the supplied identifier.
- What to do
- Check the store, resource path and identifier. Use identifiers returned by this store.
- Retry policy
- Retry only after correcting the target or confirming that it exists.
{
"error": {
"code": "resource.not_found",
"fields": null,
"message": "The resource was not found."
},
"meta": {
"request_id": "example-request"
}
}
405request.method_not_allowedThe endpoint does not support this HTTP method.
- What to do
- Use the documented method; the Allow header identifies the supported methods.
- Retry policy
- Do not retry the unsupported method.
{
"error": {
"code": "request.method_not_allowed",
"fields": null,
"message": "This method is not supported for this resource."
},
"meta": {
"request_id": "example-request"
}
}
409idempotency.key_reusedThis idempotency key belongs to a different request.
- What to do
- Find the original operation. Use a new key only for an intentionally new logical operation.
- Retry policy
- Do not retry a changed payload with the conflicting key.
{
"error": {
"code": "idempotency.key_reused",
"fields": null,
"message": "This idempotency key was used with a different request."
},
"meta": {
"request_id": "example-request"
}
}
409resource.already_existsA unique value conflicts with an existing resource.
- What to do
- Read the existing resource and decide whether to use it or choose a different unique value.
- Retry policy
- Do not repeat the same conflicting creation.
{
"error": {
"code": "resource.already_exists",
"fields": null,
"message": "A resource with these unique values already exists."
},
"meta": {
"request_id": "example-request"
}
}
409resource.in_useOther resources still depend on this resource.
- What to do
- Review the dependencies and remove or change them through supported operations before deleting.
- Retry policy
- Retry after resolving dependencies.
{
"error": {
"code": "resource.in_use",
"fields": null,
"message": "The resource is still in use."
},
"meta": {
"request_id": "example-request"
}
}
409resource.state_conflictThe current business state prevents this change.
- What to do
- Read the current state and choose a valid business transition.
- Retry policy
- Do not automatically force or repeatedly submit the conflicting change.
{
"error": {
"code": "resource.state_conflict",
"fields": null,
"message": "The current resource state does not allow this operation."
},
"meta": {
"request_id": "example-request"
}
}
409resource.version_conflictAnother write changed the resource after the version you read.
- What to do
- Read the latest state, reconcile your change and submit the new expected_version.
- Retry policy
- Use a new idempotency key for the revised operation; do not blindly overwrite.
{
"error": {
"code": "resource.version_conflict",
"fields": null,
"message": "The resource version has changed."
},
"meta": {
"request_id": "example-request"
}
}
413request.too_largeThe request exceeds the size limit.
- What to do
- Reduce the payload or split the work into supported individual operations.
- Retry policy
- Retry smaller, valid operations with their own idempotency keys.
{
"error": {
"code": "request.too_large",
"fields": null,
"message": "The request exceeds the size limit."
},
"meta": {
"request_id": "example-request"
}
}
415request.unsupported_media_typeThe media type or content encoding is unsupported.
- What to do
- For JSON writes, use Content-Type: application/json and a supported uncompressed body.
- Retry policy
- Retry after correcting the media type or encoding.
{
"error": {
"code": "request.unsupported_media_type",
"fields": null,
"message": "The request media type or encoding is not supported."
},
"meta": {
"request_id": "example-request"
}
}
422request.validation_failedOne or more fields or parameters fail validation.
- What to do
- Inspect error.fields, then check required fields, nullability, identifiers and allowed values.
- Retry policy
- Retry a corrected request; a changed write is a new logical operation.
{
"error": {
"code": "request.validation_failed",
"fields": null,
"message": "Some request parameters are invalid."
},
"meta": {
"request_id": "example-request"
}
}
429capacity.queue_fullThe short API queue is full; the request has not started execution.
- What to do
- Queue requests and respect the Retry-After response header.
- Retry policy
- Wait at least Retry-After seconds and add jitter. Preserve the original key and payload when retrying a write.
{
"error": {
"code": "capacity.queue_full",
"fields": null,
"message": "The API is busy. Please retry shortly."
},
"meta": {
"request_id": "example-request"
}
}
429capacity.wait_timeoutThe API queue wait expired; the request has not started execution.
- What to do
- Queue requests and respect the Retry-After response header.
- Retry policy
- Wait at least Retry-After seconds and add jitter. Preserve the original key and payload when retrying a write.
{
"error": {
"code": "capacity.wait_timeout",
"fields": null,
"message": "The API could not start this request in time. Please retry shortly."
},
"meta": {
"request_id": "example-request"
}
}
429rate_limit.exceededThe request rate exceeds the applicable limit.
- What to do
- Queue requests and respect the Retry-After response header.
- Retry policy
- Wait at least Retry-After seconds and add jitter. Preserve the original key and payload when retrying a write.
{
"error": {
"code": "rate_limit.exceeded",
"fields": null,
"message": "The request rate limit has been exceeded."
},
"meta": {
"request_id": "example-request"
}
}
500internal.errorAn unexpected service error occurred.
- What to do
- Record the request identifier and contact the operator if the error persists; exclude credentials from logs.
- Retry policy
- Use bounded backoff. For a write, retain the original idempotency key and unchanged payload.
{
"error": {
"code": "internal.error",
"fields": null,
"message": "An unexpected error occurred."
},
"meta": {
"request_id": "example-request"
}
}
502gateway.bad_responseThe gateway did not receive a valid API response.
- What to do
- Keep the request identifier. A failed response does not prove that a write was not applied.
- Retry policy
- Use bounded backoff; repeat the same logical write with its original Idempotency-Key and payload.
{
"error": {
"code": "gateway.bad_response",
"fields": null,
"message": "The API gateway could not obtain a valid response."
},
"meta": {
"request_id": "example-request"
}
}
504gateway.timeoutThe gateway timed out while awaiting the API.
- What to do
- Keep the request identifier and treat the write outcome as unknown.
- Retry policy
- Use bounded backoff; reuse the original idempotency key and unchanged payload for a write.
{
"error": {
"code": "gateway.timeout",
"fields": null,
"message": "The API gateway timed out."
},
"meta": {
"request_id": "example-request"
}
}