Booking API error codes
- Last verified
- Last verified Oct 3, 2026
This reference lists the errors your application is most likely to meet when it builds a cart and completes checkout with the Booking API, and how to react to each one.
How errors are reported
The Booking API reports problems in two places.
| Where | When | What to do |
|---|---|---|
Top-level errors of the response | Validation failed before execution, or a field failed during execution. | Fix the request. For a token of the wrong kind, send the correct cart or invoice token. See the token recovery guidance below. |
errors in the mutation result | The operation ran and was rejected, for example because a time slot is sold out. | Branch on message, show messageTranslated, and let the customer correct the input. |
Schema validation and variable coercion errors prevent execution. Errors raised during execution can accompany partial data: another mutation field may already have succeeded and saved changes. Top-level errors do not prove that no write occurred. Inspect the returned data and each error's path, and read the cart and any invoice before repeating writes.
Each mutation error has three fields:
| Field | Content |
|---|---|
key | The input the error refers to, as a path such as requestItems.0.pricings.0.quantity. Indexes count from 0. |
message | A machine-readable code such as invalid. Use it to decide how your application reacts. |
messageTranslated | Text in the Accept-Language language for customers. For codes without a specific text it is generic, such as "Invalid value"; you can show your own text for those. |
Do not branch on messageTranslated: its wording can change. The messages and messagesTranslated lists are deprecated.
Top-level errors about invalid variables repeat the submitted value in extensions.value, which can be a cart or invoice token. Do not log or forward error bodies unfiltered.
Top-level errors
| Message contains | Cause | What to do |
|---|---|---|
Not authorized | The cart or invoice token is invalid or has expired. | For an unusable or expired cart token, start a new cart. For an invoice, use a valid token for that same invoice. |
expected: Request | A token of the wrong kind was sent, for example an invoice token as the cart token. | Send the cart token. |
was provided invalid value | A variable does not match its input type. | Check the variables against the reference. |
was provided invalid value, with single top level field in extensions.problems | The request uses a cart or invoice token and selects more than one top-level field. | Send each top-level field in its own request. |
doesn't exist on type | The query selects a field that the Booking API does not offer. | Remove the field or check the reference. |
Adding and changing cart lines
These errors come from requestItemCreate, requestItemUpdate and requestItemDiscard, and from lines sent with requestUpdate. Keys start with requestItems.0 even when you add a single line.
| Key | Message | Cause | What to do |
|---|---|---|---|
requestItems.0.pricings.0.quantity | sum_less_than_or_equal_to | Not enough places are left for the requested quantity. | Lower the quantity or let the customer choose another date or slot. |
requestItems.0.pricings.0.quantity | greater_than_or_equal_to, less_than_or_equal_to | The quantity is outside the price category's minimum or maximum number of people. | Adjust the quantity. |
requestItems.0.offerableSpan | required, invalid | An event template or admission line has no time slot, or the slot does not exist. | Send a span returned by the time slot query. |
requestItems.0.offerableId | invalid | The offer does not exist or is not published. | Reload the offers. |
requestItems.0.offerableId | exclusively_booked | Another customer has booked the whole event exclusively. | Let the customer choose another event. |
resourceRequirements | no_available_resources | Staff or rooms needed for the booking are not available at that time. | Let the customer choose another time. |
requestId | invalid | The cart does not exist or its reservation expired. | Start a new cart. |
requestId | not_editable | The order was canceled or can no longer be changed, for example after it was paid. | Start a new cart for further purchases. |
checkoutHold | expired | The checkout hold ended and KORONA Event canceled the cart. | Start a new cart. |
id | locked | Checkout is running for this cart at the same moment. | Wait briefly and read the cart before trying again. |
Customer data
These errors come from requestUpdate.
| Key | Message | Cause | What to do |
|---|---|---|---|
contact.email | blank | The email address is missing. | Ask for an email address. |
contact.email | invalid_address | The email address is not valid. | Ask the customer to correct it. |
id | payment_exists | A payment for this cart is in progress. | Do not change the cart. Follow the payment on the invoice. |
id | already_canceled | The cart was canceled. | Start a new cart. |
Codes
These errors come from requestApplyCode and requestRemoveCode.
| Key | Message | Cause | What to do |
|---|---|---|---|
code | invalid | The code is unknown, expired, used up, has no remaining value, is already applied, or does not apply to the cart. When removing, the code is not applied to the cart. | Tell the customer the code cannot be used. |
code | already_redeemed | A promotion code has reached its redemption limit. | Tell the customer the code cannot be used. |
requestItem | blank | The voucher must be redeemed for a product. The result lists the choices in followUpProducts. | Let the customer choose a product and apply the code again with requestItem. |
requestId | not_editable | The order can no longer be changed. | Start a new cart. |
Booking and attendee questions
These errors come from requestCustomFieldsCollectionSubmit.
| Key | Message | Cause | What to do |
|---|---|---|---|
customFieldsResponses.0.values.0.value | invalid | The answer does not match the question's type, for example an invalid email address or an unknown option. | Ask the customer to correct the answer. |
customFieldsResponses | invalid | A required answer is missing, or the answers belong to more than one cart line or ticket. | Send every required answer for one cart line or ticket at a time. |
customFieldsResponses | already_completed | The questions are already answered. | Read the open questions again. |
Checkout
These errors come from requestPaymentInitiate, requestReserve and requestRequest. The latter two report the same codes for legal documents, early-start consent, checkoutPolicy and the checkout hold. For input validation errors, correct the input before trying again. An expired checkout hold cancels the cart. With id:locked, another checkout may still finish and change the cart; wait and read the cart and any invoice before deciding whether checkout is still needed.
| Key | Message | Cause | What to do |
|---|---|---|---|
contact | blank | The cart has no customer. | Add the customer with requestUpdate first. |
legalDocumentAcceptances | missing_required | A required legal document was not accepted. | Show the document and send its acceptance. |
legalDocumentAcceptances.0.legalDocumentVersion | invalid | The accepted version is not the current one. The document changed after it was shown. | Reload the documents, show them again and send the new publishedAt. |
legalDocumentAcceptances.0.legalDocumentId | invalid | The document does not exist. | Reload the documents. |
withdrawalEarlyStartConsent | missing_required | A cart line needs the customer's consent to start before the withdrawal period ends. | Ask for the consent and send it with accepted: true. |
withdrawalEarlyStartConsent | invalid | requestItemIds does not list exactly the lines that need consent. | Send the ids of every line with requiresWithdrawalEarlyStartConsent. |
id | custom_fields_incomplete | Required booking or attendee details are missing. | Send the customer to the hosted pages that collect them, or collect them before checkout. |
checkoutPolicy | TARGET_STATE_CONFLICT, PAYMENT_METHOD_CONFLICT | The cart mixes offers that cannot be checked out together. | Split the cart. |
checkoutHold | expired | The checkout hold ended and the cart was canceled. | Start a new cart. |
id | locked | Another checkout request for this cart is running. | Wait and read the cart and any invoice before deciding whether checkout is still needed. |
Expired checkout holds
Send exactly one of requestId (the cart token) or invoiceToken to requestCancelExpiredCheckoutHold. If an anonymous caller omits both, the response has a top-level Not authenticated error. Send one of the tokens and retry.
The mutation can return these payload errors:
| Key | Message | Cause | What to do |
|---|---|---|---|
checkoutHold | not_expired | The hold is still running. | Wait until secondsRemaining reaches zero. |
id | invalid | Both requestId and invoiceToken were sent. | Send exactly one of them. |
id | blank | An authenticated caller omitted both requestId and invoiceToken. | Send exactly one of them. |
Traffic limits and retries
When traffic limits are enforced, KORONA Event counts HTTP requests and executed root fields separately. Aliases, multiple root fields and batches spend the same budgets as separate executions. Login, password reset, account creation, uploads and payment attempts have stricter budgets. Bulk uploads count each file. Requests may share a budget through their network, authenticated account or API credential. Splitting a batch or changing an operation name does not reset a budget.
Work limits also account for the server-calculated cost of a validated query and requests still in progress. A batch includes the cost of its operations. Email-triggering actions and expensive operations, such as calendar expansion, bulk changes, rendering and export initiation, have separate budgets. An email-trigger attempt is not confirmation that an email was delivered.
If a work limit rejects a request, reduce unnecessary selected fields, date ranges or bulk input sizes and limit parallel requests. Wait for the indicated retry delay before retrying. Keep payment-status polling bounded and reuse completed results. A concurrency slot becomes available when work finishes; a disconnected client does not prove that a payment or mutation stopped, so inspect its current state before retrying.
| Response | Meaning | Safe recovery |
|---|---|---|
HTTP 429, error code RATE_LIMITED | The HTTP request was rejected before GraphQL execution. | Wait at least the number of seconds in Retry-After before retrying. |
HTTP 503, error code RATE_LIMIT_UNAVAILABLE | The request could not be admitted safely and no GraphQL field ran. | Wait for Retry-After before retrying. |
HTTP 200, top-level error with extensions.code: RATE_LIMITED | The field identified by path was rejected before its resolver ran. Other fields may have succeeded. | Wait for extensions.retryAfter seconds. Inspect data and each error's path; retry only the rejected work. |
HTTP 200, top-level error with extensions.code: RATE_LIMIT_UNAVAILABLE | A sensitive field could not be admitted safely. Other fields may have succeeded. | Wait for extensions.retryAfter seconds and inspect the current cart, invoice or payment before deciding which work is still needed. |
Use a bounded retry policy with a small random delay after the indicated wait. Avoid immediately retrying a whole mutation or batch: earlier fields may already have saved changes or initiated payment. Keep the same idempotency key when retrying a logical payment attempt that supports one. Payment-status polling spends the ordinary root-field budget, rather than the stricter payment-attempt budget.
A cost or concurrency rejection can return these GraphQL errors without a path, before any field in the affected operation runs. Check every batch result separately; another operation may have completed.
General codes
Other inputs use these general codes.
| Message | Meaning |
|---|---|
blank, required | A required value is missing. |
invalid | The value is not allowed or does not exist. |
taken | The value must be unique and is already used. |
greater_than_or_equal_to, less_than_or_equal_to | The value is below the minimum or above the maximum. |