Errors and retries
Understand what went wrong, what to fix, and when to try again.
Start with the HTTP status to decide what to do next, then read the error body
for details. API errors use the same JSON structure. Validation errors also
include an errors object listing every field that needs fixing.
{
"type": "validation_error",
"code": "validation_failed",
"message": "The selected product variant id is invalid.",
"status": 422,
"param": "product_variant_id",
"request_id": "01992a65-e064-71ba-b38f-902b7966a6be",
"docs_url": "https://sell.app/docs/api/errors#validation-failed",
"errors": {
"product_variant_id": [
"The selected product variant id is invalid."
]
}
}Use type to group errors and code to choose a specific handling path in your
code. Read message for an explanation, but do not depend on its exact wording.
param names the first invalid field for a validation error and is otherwise
null. Keep request_id when asking support to investigate.
Recovery by status
| Status | Code | Recovery |
|---|---|---|
400 | bad_request | Correct the request syntax or required headers. Do not retry unchanged input. |
401 | unauthenticated | Add, replace, or correctly format the bearer key. |
403 | forbidden | Check token abilities, store membership, and staff permissions. |
404 | resource_not_found | Verify the path, resource ID, and the slug in X-STORE. Cross-store resources intentionally look missing. |
409 | conflict | Retrieve the resource again and check whether your change still makes sense. |
410 | endpoint_gone | Migrate to the replacement named by the deprecated OpenAPI operation. |
422 | validation_failed | Correct every field in errors; do not retry the same payload. |
429 | rate_limit_exceeded | Wait for Retry-After, then retry with exponential backoff and jitter. |
5xx | api_error | Retry reads and idempotent writes within a finite budget. Retain the request ID. |
bad_request
The server could not understand the request. A common cause is omitting a header required by that route.
unauthenticated
The bearer key is missing, malformed, revoked, or unknown.
forbidden
The key is valid, but its abilities or the account's store permissions do not authorize the operation.
resource_not_found
The route or resource was not found in the selected store. A resource belonging to another store also looks missing; this keeps that store's information private.
conflict
The request conflicts with the resource's current state. Retrieve it again and make the change only if it is still allowed.
endpoint_gone
The operation was retired. Read x-sellapp-replacement from its OpenAPI entry
or follow the legacy v1 migration map.
validation_failed
Inspect errors, fix the named fields, and send a new request. Reusing an
idempotency key with different input is also reported as validation failure by
the operations that support keys.
rate_limit_exceeded
The caller exceeded the API's minute window. See Rate limits.
api_error
SellApp could not complete the operation. Log the request ID. Retry only if the method is safe or the write uses documented idempotency.
Retry example
When a retry is safe, wait longer between attempts (exponential backoff) and choose a random delay within that window (full jitter). This keeps all your workers from retrying at the same instant:
delay = random(0, min(30 seconds, 0.5 seconds × 2^attempt))Honor Retry-After when it is present. Stop after a bounded number of attempts
or elapsed time, and include the final request_id in your error report.