Errors
Error format
Section titled “Error format”Errors use application/problem+json:
{ "type": "https://docs.luxorr.io/errors#invalid_request", "title": "Invalid request", "status": 400, "code": "invalid_request", "detail": "fullName is required", "errors": [ { "field": "fullName", "code": "required", "message": "fullName is required" } ]}The following table describes the fields:
| Field | Description |
|---|---|
code |
A stable, snake_case code. Use it in your logic. New codes can be added, and existing codes don’t change. |
status |
The HTTP status. |
title |
A short label for the code. |
detail |
A description of this error. Log it, but don’t parse it. |
type |
A link to the code on this page. |
errors |
Validation errors: one entry for each field, each with its own code. |
Some errors add fields:
not_cancellableaddscurrentStatus. If another key or your team created the link, it also addsreason: "created_elsewhere".price_changedaddscoinPrice.gift_not_availableaddsreason.
Validation errors are never 5xx. If you get a 5xx, retry. For a POST call, use the same Idempotency-Key.
Error codes
Section titled “Error codes”invalid_request
Section titled “invalid_request”400. The request is malformed: a required field is missing, the JSON is invalid, a value has the wrong type, an ID in the query or body can’t be read, limit is outside 1 to 100, or the cursor is unknown. errors[] lists each field. Fix the request and send it again. A refusal isn’t stored, so the same Idempotency-Key runs again.
A personal link that breaks one of your account’s settings returns this code too, with every problem in errors[]: for example, a locale that isn’t enabled, or a missing required custom field. For more information, see Personal links.
A store order returns this code for a missing or invalid recipient field, a missing postal code that the country needs, a locale that isn’t enabled, variations that aren’t one of the gift’s combinations, or a missing required custom field. For more information, see Rewards stores.
If an ID in the path is malformed, the API returns 404 not_found, for example for GET /personal-links/not-a-uuid.
payload_too_large
Section titled “payload_too_large”413. The request body is larger than 10 MB. Nothing runs.
idempotency_key_required
Section titled “idempotency_key_required”400. A POST call has no Idempotency-Key header, or the header is blank. For more information, see Idempotency and retries.
idempotency_key_invalid
Section titled “idempotency_key_invalid”400. The Idempotency-Key header is longer than 255 characters. Nothing runs. Send a shorter key, such as a UUID. For more information, see Idempotency and retries.
unsupported_media_type
Section titled “unsupported_media_type”415. The request body isn’t sent as application/json, for example as text/plain or as a form. Nothing runs. Send JSON with Content-Type: application/json.
not_acceptable
Section titled “not_acceptable”406. The Accept header excludes application/json. Nothing runs. Send Accept: application/json, or send no Accept header.
invalid_api_key
Section titled “invalid_api_key”401. The key is missing, malformed, unknown, or revoked, or API access is turned off. Don’t retry.
insufficient_scope
Section titled “insufficient_scope”403. The key doesn’t have the scope that the call needs. Link and campaign calls (/personal-links, /campaigns) need the PERSONAL_LINKS scope. Store calls (/reward-stores, /reward-store-orders) need the REWARD_STORES scope. Your Administrator or Luxorr selects the scopes on the key. GET /me lists the key’s scopes. For more information, see Scopes.
not_found
Section titled “not_found”404. Your key can’t access a record with this ID. A path ID that isn’t a UUID returns the same error.
method_not_allowed
Section titled “method_not_allowed”405. The path exists, but not with this HTTP method.
rate_limited
Section titled “rate_limited”429. This key sent more than 3,000 requests in a minute, or one IP address sent more than 600 image requests in a minute. Wait for the number of seconds in the Retry-After header. For more information, see Rate limits and versioning.
idempotency_key_reused
Section titled “idempotency_key_reused”422. The Idempotency-Key was used before with a different request. Use a new key for a new request.
idempotency_request_in_progress
Section titled “idempotency_request_in_progress”409. A request with this Idempotency-Key is still running. Nothing runs a second time. Retry with the same key and body after a few seconds. You get the first request’s response after it is stored. For more information, see Idempotency and retries.
campaign_not_found
Section titled “campaign_not_found”422. Your key can’t use this campaign. This code is also returned for a brandId on a new link that the campaign doesn’t serve or that your key can’t access.
campaign_not_active
Section titled “campaign_not_active”422. The campaign isn’t active: it is still being prepared, it has completed, or it has passed its expiry date.
reward_store_not_found
Section titled “reward_store_not_found”422. For an order: your key can’t use this store. Read your stores again with GET /reward-stores. For more information, see Rewards stores.
reward_store_not_live
Section titled “reward_store_not_live”422. The store takes no orders: it hasn’t opened yet (SCHEDULED), or it has ended. Show the store as closed, and don’t deduct any coins.
brand_not_found
Section titled “brand_not_found”422. For an order: the brandId isn’t one of the store’s brands, or your key can’t access it. Send the brand that you read the store for.
gift_not_available
Section titled “gift_not_available”422. The gift can’t be ordered for this brand and delivery country. reason is one of NOT_IN_STORE, NOT_PUBLISHED, NOT_USABLE_BY_BRAND, NOT_SOLD_IN_COUNTRY, NOT_AVAILABLE_NOW, or NO_SELECTABLE_COMBINATION. Remove the gift from what the player sees, and read the store again. For more information, see Rewards stores.
out_of_stock
Section titled “out_of_stock”409. The chosen combination of a stocked gift is sold out. Offer another combination or another gift.
price_changed
Section titled “price_changed”409. The order’s coinPrice isn’t the gift’s current price for the delivery country. The response contains the current coinPrice. Show the player the new price and ask again. If the player accepts, send the order with the new price.
not_cancellable
Section titled “not_cancellable”409. Your key can’t cancel the link. If reason is created_elsewhere, your team or another of your keys created the link: a key cancels only the links that it created. Otherwise, the link is CLAIMED or EXPIRED. currentStatus contains the link’s status. If you cancel your own link and it is already CANCELLED, that isn’t an error: the API returns 200 with the link unchanged.
internal_error
Section titled “internal_error”500. A server error. Retry, and for a POST call, use the same Idempotency-Key. If the error continues, contact Luxorr with the time and the request.
Field error codes
Section titled “Field error codes”Each entry in errors[] has its own code:
| Code | Description |
|---|---|
required |
The field is missing or blank, such as fullName or campaignId. |
invalid |
The value is malformed or not allowed. |
too_long |
The value is longer than the field allows. |
not_enabled |
The locale isn’t enabled for your account. Every call that takes a locale returns this code for it. |

