Guides

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.

Validation error
{
  "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

StatusCodeRecovery
400bad_requestCorrect the request syntax or required headers. Do not retry unchanged input.
401unauthenticatedAdd, replace, or correctly format the bearer key.
403forbiddenCheck token abilities, store membership, and staff permissions.
404resource_not_foundVerify the path, resource ID, and the slug in X-STORE. Cross-store resources intentionally look missing.
409conflictRetrieve the resource again and check whether your change still makes sense.
410endpoint_goneMigrate to the replacement named by the deprecated OpenAPI operation.
422validation_failedCorrect every field in errors; do not retry the same payload.
429rate_limit_exceededWait for Retry-After, then retry with exponential backoff and jitter.
5xxapi_errorRetry 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.

On this page