Collect booking and attendee details with the Booking API
- Availability
- Beta
- Last verified
- Last verified Sep 28, 2026
Venues can ask questions for each booking or each ticket, for example attendee names, a date of birth or a dietary requirement. Use this guide to show those questions in your checkout and save the answers before payment.
Required questions due before payment must be answered before you complete checkout, even when you use the hosted payment page. If your integration cannot collect them, use the venue’s hosted online shop for the booking instead.
Before you start
- A cart with at least one item and its cart token.
- The Booking API quickstart explains carts and tokens.
Check whether the cart has questions
Read customFieldsCompletion on the cart. When allRequiredComplete is false, required questions are still open. Ask for customFieldsCollectionToken in the same query; you need it to read and answer the questions. Each read creates a new token, so request it only when you start collecting answers, not every time you refresh the cart.
query CartQuestions($id: IdOrNumberOrToken!) {
request(id: $id) {
customFieldsCompletion {
hasCustomFields
allRequiredComplete
}
customFieldsCollectionToken(requiredByStage: BEFORE_PAYMENT)
}
}requiredByStage: BEFORE_PAYMENT includes every question that must be answered before payment. The token is valid for 24 hours; read a new one when it expires.
Read the open questions
query OpenQuestions($token: Token!) {
requestCustomFields(requestId: $token) {
openCustomFields {
customizableId
customizableType
offerableNameTranslated
pricingNameTranslated
customFieldSets {
id
legendTranslated
descTranslated
inputs {
id
labelTranslated
descTranslated
type
required
mapping
options {
value
labelTranslated
}
}
}
}
}
}Each entry in openCustomFields is one set of answers to collect:
customizableType | Asked for |
|---|---|
REQUEST_ITEM | One cart line, once per booking. |
ATTENDANCE | One ticket. Show pricingNameTranslated so the customer knows which ticket they fill in. |
CONTACT | The customer. These questions cannot be answered through the Booking API yet; see below. |
customFieldSets groups the questions under a heading from legendTranslated. Show the inputs in the order returned.
Build the form
Choose the form control from type and send the answer as text:
type | Answer |
|---|---|
TEXT, TEXTAREA | Free text. |
EMAIL | An email address. |
TEL | A phone number, validated for the venue's country. |
DATE | A date as YYYY-MM-DD. For mapping: DATE_OF_BIRTH, it must not be in the future. |
SELECT, RADIO | The value of the chosen option. Show labelTranslated. |
CHECKBOX | With options, the value of the chosen option; without options, a text value. |
FILE, WAIVER | Not supported through the Booking API yet; see below. |
mapping tells you when an answer fills a standard attendee detail such as FIRST_NAME or LAST_NAME; CUSTOM is a question the venue defined.
Save the answers
Send the answers for one entry of openCustomFields at a time, with one item per question group:
mutation SaveAnswers($input: RequestCustomFieldsCollectionSubmitInput!) {
requestCustomFieldsCollectionSubmit(input: $input) {
customFieldsResponses {
id
completionState
}
errors {
key
message
messageTranslated
}
}
}{
"input": {
"requestId": "<customFieldsCollectionToken>",
"customFieldsResponses": [
{
"customizableId": "<customizableId>",
"customizableType": "ATTENDANCE",
"fieldSetId": "<customFieldSets.id>",
"values": [{ "inputId": "<inputs.id>", "value": "Alex" }]
}
]
}
}When the answers are saved, completionState is REQUIREMENTS_MET. Read the open questions again and repeat until openCustomFields is empty, then complete checkout.
When a cart line has several tickets in the same price category, openCustomFields lists them as one entry. Each save fills the next ticket, so read the list again after every save until the entry disappears.
Questions the Booking API cannot answer yet
File uploads (FILE), waivers (WAIVER) and customer questions (CONTACT) cannot be submitted through the Booking API. If any of these are required before payment, this configuration does not support a complete headless checkout: checkout returns custom_fields_incomplete and does not return an invoice or paymentLink.
Use the venue’s hosted online shop for these bookings from the start, so the customer can provide the required details before checkout. Do not complete API checkout expecting a payment link to collect them.
Errors
| Key | Message | 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. The indexes point to the question group and the answer. |
customFieldsResponses | invalid | A required answer is missing, or the answers belong to more than one cart line or ticket. Check the answers and send them again. |
customFieldsResponses | already_completed | These questions are already answered. Read the open questions again. |
Depending on the venue's settings, checkout fails with custom_fields_incomplete while required questions are open. Answer them and complete checkout again.