Skip to content

API errors

The SeatLayer API error body, every public error code grouped by area with its HTTP status, and which errors are safe to retry.

Updated View as Markdown

Every error from the SeatLayer API has the same shape: a JSON object whose first key, error, is a stable machine code. Branch on error (and code when present), never on message.

The error body

404 responsejson
{
  "error": "not_found"
}
409 response with detailjson
{
  "error": "order_edit_in_progress",
  "code": "order_edit_in_progress",
  "retryable": true,
  "conflicts": [{ "label": "A-12", "status": "blocked" }]
}
Field Always present Meaning
error Yes Stable machine code, never a sentence
code No A more specific reason when error is a broad class, such as error: "forbidden" with code: "missing_manage_capability". Often equal to error
message No Human-readable text for logs and operators. It can change; do not parse it
retryable No true when the same request can succeed later without changes
retryAfterSeconds No Seconds to wait, on rate limits and maintenance
requestId No Sent in the body on 500 and 503. Every response also carries an X-Request-ID header

Routes add their own detail fields next to these, for example conflicts, issues, maxBytes, or currentUpdatedAt. Treat unknown fields as extra information, not as a different error.

The OpenAPI document lists the exact error codes each operation can return. This page groups them so you can write one handler.

Status codes

Status Meaning Retry
400 The request is missing a required field or is malformed No. Fix the request
401 No valid credential No. Check the key
402 Not enough credits to create inventory No. Buy credits first
403 The credential cannot do this, or the resource is in the other mode No
404 The resource does not exist for this account and mode No
409 The current state does not allow the change Only when retryable: true
413 Body or upload too large No
415 Unsupported file type No
422 The request is well formed but a value is invalid No
429 Rate limited Yes, after Retry-After
500 Unexpected server error Reads: yes. Writes: see below
502 A payment provider step needs a retry Yes, with the same Idempotency-Key
503 Temporarily unavailable or in maintenance Yes, after Retry-After

Codes by area

Authentication and access

Status error / code When
401 unauthorized / bad_key Missing, revoked, or malformed sk_… secret key
401 unauthorized / bad_manage_session, manage_session_expired Event manage token is invalid or expired
403 mode_mismatch A test key used on a live resource, or the reverse
403 forbidden / missing_manage_capability The manage token lacks the capability, such as event:block
403 forbidden / event_scope_mismatch The manage token belongs to another event
403 forbidden The dashboard role cannot make this change
403 channel_access_denied The seats belong to a sales channel this caller cannot use
403 module_not_enabled The feature is not turned on for your account, for example Seasons or Event Configurations

Validation

Status Examples
400 name_required, chartId_required, selections_required, holdId_required, qty_required, labels_required, labels_and_holdId_required, bookingRef_required, hold_or_labels_and_bookingRef_required, objects_required, rules_required, releaseAt_required, blockRef_required, invalid_zone, invalid_cursor, empty_body, nothing_to_update
413 chart_too_large, image_too_large, payload_too_large
415 unsupported_image
422 invalid_request, invalid_selection, invalid_chart, invalid_currency, invalid_timezone, invalid_listing_id, invalid_availability_rule, unknown_zone, image_dimensions_unsupported

Events and charts

Status error When
402 insufficient_credits Creating or copying a live event, switching one to live, or adding Season performances, while the credit balance is 0 or below. The body also carries message (a sentence you can show) and balance, the current balance. Live events already on sale keep selling
404 not_found, chart_not_found, chart_unavailable Unknown event or chart
409 event_exists The workspace already has an event with this slug
409 event_not_mutable, invalid_sales_transition, sales_revision_conflict The event’s sales state does not allow the change
409 performance_group_locked, season_event_locked The event belongs to an active Performance Group or Season
409 seats_would_vanish Updating the chart would leave out or change seats that are sold, held or blocked
409 event_configuration_bound Unbind the Event Configuration before changing the chart
422 chart_not_published, invalid_event_inventory, inventory_limit_exceeded The chart cannot become event inventory

Holds, booking, and inventory

Status error When
402 credit_limit_reached New live sales are stopped because the credit balance reached the account’s limit below zero. The body carries message, balance and floor. Holds already taken still book; topping up resumes sales at once
404 hold_not_found The hold id is unknown
409 conflict One or more seats are not available. conflicts lists each label and its status. Nothing in the request was applied
409 event_closed Sales are closed or outside the sales window. A buyer whose sale is paused by the account’s credit limit gets this too, with paused: true and message
409 hold_not_active The hold expired or was released before booking
409 cannot_extend The hold is gone, expired, or at its extension limit
409 booking_mismatch unbook named a bookingRef that does not own the seats
409 not_booked Resale listing named a seat that is not booked
409 resale_unsupported_on_seatlayer_checkout Resale on a Hosted Ticketing event or ticketed seat
409 order_edit_in_progress An order edit is changing these seats. Sent with retryable: true
409 legacy_hold_requires_restart The hold predates the current format; start a new hold
422 hold_quantity_exceeded More seats than the hold limit allows

Idempotency

Status error When
400 invalid_idempotency_key The key is not 1 to 128 characters of A-Z a-z 0-9 . _ : -
400 idempotency_not_supported_for_operation This operation does not accept Idempotency-Key
400 idempotency_key_required Season order refunds and cancels need a key
409 idempotency_conflict The key was used before with a different request
409 idempotency_in_progress The first call with this key is still running. Retry after Retry-After

See idempotency and conflicts.

Seasons and Performance Groups

Status Examples
409 not_a_draft, revision_mismatch, not_active, sales_open, sales_not_ended, plan_not_published, invalid_transition, lifecycle_transition_pending, amendment_in_flight, payment_in_progress, book_operation_mismatch, booking_not_cancellable, hosted_order_use_refund, group_not_draft, group_not_active, member_set_mismatch
422 invalid_notify_customers: notifyCustomers on a date change is not true or false. See Email the date’s customers
502 refund_recovery_required: retry with the same Idempotency-Key
503 channel_state_unavailable, participant_unavailable, recovery_pending, lifecycle_unavailable
503 season_busy: the season had too many holds at once, or part of it did not answer in time. Nothing was written. Send the same request again after Retry-After (2 seconds). See when a hold can’t finish

Long Season and Performance Group operations can answer 202 Accepted with Location and Retry-After. That is progress, not an error: poll the Location until the state is terminal.

Season seats

Season seats are the seats a season sets aside on every date. While they are set aside, some changes would make them wrong, and a few changes aren’t possible in block mode yet. Both are refused, and nothing changes.

Status Code When
409 season_block_not_enabled Season seats aren’t turned on for this season (inventoryMode: "block")
409 season_block_packages Turning season seats on, or setting them aside, on a season with more than one package
409 season_block_on_sale Turning season seats on once the season’s sales have opened
409 season_block_exists inventoryMode: "per_hold" once seats are set aside, or once the season sells from its block
422 invalid_inventory_mode inventoryMode is neither block nor per_hold
409 block_exists The season already has its block
409 block_not_ready Releasing before the season sells from its block, or opening sales while season seats are on and it doesn’t sell from its block yet
409 season_not_draft_or_active Setting seats aside on a closed or archived season
422 block_selection_empty No priced seat is left after the seats kept for single tickets
422 seat_not_in_block A seat named in a release isn’t a season seat
409 season_block_set_aside Seats are set aside and block mode isn’t on yet. Refused: adding or removing a date, another package, a package pricing other categories, publishing one package on its own (use publishSeason), and date amendments other than a new time. Set the seats aside again after the change.
409 season_inventory_locked A change block mode doesn’t do yet. The body’s action names it: date_changes (adding or removing a package’s date), amendments (a postpone, a replacement or a cancel exception), holder_cancel (cancelling a booking), date_cancel (taking one date back from an order), returns (returning or reclaiming a date’s seats) or recovery (emergency recovery).
409 date_leave_in_progress The date is already being taken off sale another way
409 season_block_one_package Before Publish, seats are set aside for one package, and this draft has more than one. Add the others after Publish
409 plan_not_published Setting seats aside on an active season that has no published package
409 season_block_undoing Season seats are still being given back after an undo. Set them aside again in a moment
409 release_mismatch This Idempotency-Key already started a different release
422 chart_unavailable The season’s chart can’t be read, so no seat can be set aside
422 dates_missing The package has no dates to sell
503 season_busy, season_not_configured A shard or the season object did not answer. Send the same set-aside or release again with the same Idempotency-Key: it runs once. For retrieveSeasonBlock, read again
202 block_date_leave_pending Not an error. A block season’s date cancel or past date is still leaving a shard. It finishes by itself: send the same request again after Retry-After to read how it ended.

Old SDK versions surface these through their generic API error, with code.

Webhooks

Status error When
403 forbidden Only an admin can change subscriptions
404 not_found Unknown subscription
422 invalid_url, invalid_events, invalid_mode, invalid_environment The endpoint must be public HTTPS and events must be known names

Service-wide

Status error When
400 invalid_request The request holds characters that cannot be stored, such as a NUL byte. Do not retry it unchanged
404 not_found No such route
429 rate_limited See rate limits
500 internal_error Unexpected failure. Quote requestId to support
503 temporarily_unavailable A temporary server condition; safe to retry. Sent with retryable: true and Retry-After: 1
503 maintenance_mode Writes are paused. Reads still work. The body has retryAfterSeconds, resumesAt, and message

Which errors to retry

  • Reads (GET): retry on connection errors, 408, 429, and 5xx, with backoff. An event’s report, objects, log, and seat history answer 503 with code: event_temporarily_unavailable and Retry-After: 1 while the event’s inventory restarts; repeat the read after that delay.
  • Writes with Idempotency-Key: retry on the same failures with the same key. The first result is replayed, so nothing happens twice.
  • Writes without idempotency: holds, blocks, and most inventory changes. Retry 429 after Retry-After, because it did nothing. A 503 whose code is event_temporarily_unavailable means the event’s inventory did not answer in time, and the change may still have been made. Before you repeat a hold, block, extend, or best-available call, read the hold or the seats. After a timeout or 500, also read the current state before trying again.
  • Book: on a 503 with retryable: true, wait for Retry-After and send the same book request once more, with the same bookingRef. One reference cannot make a second sale, so this repeat is always safe. If it answers 503 again, keep the order as payment in progress and retry it from your queue.
  • 409 with retryable: true: wait briefly and send the same request.
  • Every other 4xx: do not retry unchanged. Fix the request, pick other seats, or show the conflict to the operator.

A booking call keyed by one bookingRef is safe to repeat: the same reference cannot create a second sale. Releasing a hold is safe to repeat too: it only frees seats still held under that holdId. See idempotency and conflicts.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close