Skip to content

Every failed request on the OLET API returns the same JSON shape: {"error": {"code": "...", "message": "...", "fields": [...]}}. fields only appears when the problem is about specific request fields. Branch your code on code, and show message to a person if you need to.

Terminal window
curl https://api.oletapp.com/your-store/v1/products/does-not-exist \
-H "Authorization: Bearer olet_live_YOUR_API_KEY"
const res = await fetch(url, { headers })
if (!res.ok) {
const { error } = await res.json()
console.error(error.code, error.message)
}

A validation failure adds fields, a list of {field, message} pairs naming exactly what was wrong:

{
"error": {
"code": "VALIDATION_FAILED",
"message": "Check the highlighted fields and try again.",
"fields": [
{
"field": "cursor",
"message": "This cursor is invalid. Pass back the exact next_cursor value from a previous response, never one you construct yourself."
}
]
}
}

Every code below is also listed in the ErrorEnvelope schema of the OpenAPI spec.

Code Status What to do
UNAUTHORIZED 401 Your credential is missing, malformed, unknown, revoked, or has gone idle past 90 days. Check the Authorization header and, for an idle credential, create a new one.
VALIDATION_FAILED 400 The request body, a query parameter (including cursor) or the Idempotency-Key header failed validation. Read fields and fix each one. A nested field is named with dots, such as lines.2.
NOT_FOUND 404 The resource does not exist, is deleted, or belongs to a different store. An id that is not a valid UUID, or a path that is not part of the API, answers the same way. Double-check the id.
CONFLICT 409 The write collided with an existing value or a rule, such as a SKU already in use, a duplicate brand or tag name, or deleting something that is still in use. Change the request and retry.
UNPROCESSABLE 422 The request referenced something that could not be found, exceeded a cap (for example more than 10 codes on one product), or otherwise could not be carried out as written.
RATE_LIMITED 429 You went over a rate limit, or too many product image imports were already running. See rate limits and slow down.
IDEMPOTENCY_IN_PROGRESS 409 A request with the same Idempotency-Key is still being processed. Wait and retry.
IDEMPOTENCY_KEY_REUSED 422 You reused an Idempotency-Key with a different request body. Use a new key per logical operation.
INTERNAL 500 Something went wrong on our side. Safe to retry after a short delay.
INSUFFICIENT_SCOPE 403 Your API key or OAuth connection lacks the scope this endpoint needs. See authentication for the scope table.
PLAN_REQUIRED, PLAN_USERS_EXCEEDED, PRODUCT_LIMIT_REACHED 402 Your store’s current plan does not include API access (it needs the Growth plan), or a plan limit was reached, such as the product limit on a product create. Ask whoever manages billing to review the plan.
RETAILER_CANCELLED, RETAILER_SUSPENDED, RETAILER_NOT_FOUND 403 The store cannot currently take API calls because of its account status. Check the store’s status in the back office.
RETAILER_PAUSED, TRIAL_DECISION_REQUIRED 402 The store’s owner needs to act in Settings › Billing (resume the store, or choose a plan) before API calls resume.
STALE_VERSION 409 The version (or expected_version) you sent with a product update no longer matches the product. Reload it and try your change again.
NOT_STOCK_TRACKED, REASON_DIRECTION_MISMATCH, INSUFFICIENT_STOCK 422 An inventory rule refused the request, for example adjusting stock on a product that does not track it. Read message for the specific reason.
REASON_NOT_ALLOWED 422 The stock adjustment reason_id is a system reason or is turned off. Pick a reason that is enabled and is not a system reason.
OUTLET_DELETED 422 A stock write named an outlet that has been deleted. Nothing is written.
IMAGE_FETCH_FAILED 422 The image_url you supplied could not be downloaded. The product write itself succeeded, and the response carries the saved product in data next to the error. Check that the URL is public and reachable.

Treat message as the source of truth for exactly what happened, and always check it alongside code.

No. POST /oauth/token answers in the standard OAuth shape, {"error": "invalid_grant", "error_description": "..."}, because OAuth clients expect it. See authentication. Every other call returns the envelope above.

See rate limits for what happens after too many requests, or the full API reference for status codes on a specific endpoint.