# Extra customer data Some activities in the Musement catalog require extra customer data—additional mandatory information that the cart customer (aka *lead booker*) needs to provide. This data is activity-specific and may include details like phone numbers, dietary restrictions, or other custom questions defined by the activity provider. ## Retrieving the extra customer data schema While each activity provides a preview of extra customer data at `/activities/{activityUuid}/extra-customer-data/schema`, the requested info may change for cart items. The definitive extra customer data appears in the same endpoint used for getting [lead booker information](/api/booking-flow/customer/lead-booker): ```bash curl -X GET '{baseUrl}/carts/{cartUuid}/customer/schema' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' ``` The response returns a [JSON schema](https://json-schema.org/) describing all required customer fields. When activities require extra customer data, it appears in a dedicated `extra_customer_data` property: ```json { "title": "cart_customer_guest", "type": "object", "properties": { "firstname": { "type": "string", "title": "firstname", "propertyOrder": 1 }, "lastname": { "type": "string", "title": "lastname", "propertyOrder": 2 }, "email": { "type": "string", "title": "email", "format": "email", "propertyOrder": 3 }, "musement_newsletter": { "enum": ["NO", "YES"], "enum_titles": ["NO", "YES"], "type": "string", "title": "musement_newsletter", "propertyOrder": 4 }, "allow_profiling": { "enum": ["YES", "NO"], "enum_titles": ["YES", "NO"], "type": "string", "title": "allow_profiling", "propertyOrder": 5 }, "thirdparty_newsletter": { "enum": ["YES", "NO"], "enum_titles": ["YES", "NO"], "type": "string", "title": "thirdparty_newsletter", "propertyOrder": 6 }, "events_related_newsletter": { "enum": ["YES", "NO"], "enum_titles": ["YES", "NO"], "type": "string", "title": "events_related_newsletter", "propertyOrder": 7 }, "city": { "type": "string", "title": "city", "propertyOrder": 8 }, "address": { "type": "string", "title": "address", "propertyOrder": 9 }, "zipcode": { "type": "string", "title": "zipcode", "propertyOrder": 10 }, "tax_id": { "type": "string", "title": "tax_id", "propertyOrder": 11 }, "extra_customer_data": { "title": "extra_customer_data", "type": "object", "properties": { "1714c6a7-2046-11e7-9cc9-06a7e332783f": { "title": "1714c6a7-2046-11e7-9cc9-06a7e332783f", "type": "object", "properties": { "phone_number": { "type": "string", "title": "Phone number", "propertyOrder": 1 } }, "required": ["phone_number"], "propertyOrder": 1 } }, "required": ["1714c6a7-2046-11e7-9cc9-06a7e332783f"], "propertyOrder": 12 } }, "required": [ "firstname", "lastname", "email", "musement_newsletter", "allow_profiling", "thirdparty_newsletter", "events_related_newsletter", "extra_customer_data" ] } ``` > Field names like `phone_number` in the examples above are activity-specific and configured by the activity provider or integration partner. They are not fixed API fields — the actual fields returned in the schema depend entirely on the activity's configuration. ## Schema structure The `extra_customer_data` property is organized by activity UUID. Each activity group contains the specific questions for that product: | Level | Description | | --- | --- | | `extra_customer_data` | Root object containing all activity-specific data | | `extra_customer_data.{activityUuid}` | Object containing fields for a specific activity | | `extra_customer_data.{activityUuid}.{fieldName}` | Individual field with its type and constraints | ## Extended field types Extra customer data fields can be one of the following types, each mapped to a corresponding JSON Schema type: | Extended Field Type | JSON Schema Type | Additional Properties | | --- | --- | --- | | `text` | `string` | `attr.min`, `attr.max`, `attr.min_max_length_units` | | `paragraph` | `string` | `attr.min`, `attr.max`, `attr.min_max_length_units` | | `number` | `number` | `attr.min`, `attr.max`, `attr.units`, `attr.integer_only` | | `radio` | `string` | `enum`, `enum_titles` | | `checkboxes` | `array` | `items.enum`, `uniqueItems: true` | | `dropdown` | `string` | `enum`, `enum_titles`, `attr.include_blank_option` | | `date` | `string` | `format: date` | | `time` | `string` | — | ### Text fields with constraints Text fields may include length constraints in characters or words: ```json { "passenger_name": { "type": "string", "title": "Passenger Name", "attr": { "min": 2, "max": 100, "min_max_length_units": "characters" }, "propertyOrder": 1 } } ``` ### Number fields with constraints Number fields may include min/max value constraints and units: ```json { "group_size": { "type": "number", "title": "Group Size", "attr": { "min": 1, "max": 10, "units": "Person", "integer_only": true }, "propertyOrder": 1 } } ``` ### Choice fields (radio, dropdown) Single-selection choice fields use `enum` for available options: ```json { "meal_preference": { "type": "string", "title": "Meal Preference", "enum": ["Vegetarian", "Non-Vegetarian", "Vegan"], "enum_titles": ["Vegetarian", "Non-Vegetarian", "Vegan"], "propertyOrder": 1 } } ``` Dropdown fields may include a blank option: ```json { "country": { "type": "string", "title": "Country", "enum": ["USA", "UK", "Germany"], "enum_titles": ["USA", "UK", "Germany"], "attr": { "include_blank_option": true }, "propertyOrder": 1 } } ``` ### Multiple selection fields (checkboxes) Checkbox fields allow multiple selections: ```json { "allergies": { "type": "array", "title": "Allergies", "uniqueItems": true, "items": { "enum": ["Nuts", "Dairy", "Gluten", "Shellfish"] }, "propertyOrder": 1 } } ``` ### Date fields Date fields use the `date` format: ```json { "birth_date": { "type": "string", "title": "Date of Birth", "format": "date", "propertyOrder": 1 } } ``` ### Fields with descriptions Fields may include a description for additional context: ```json { "emergency_contact": { "type": "string", "title": "Emergency Contact", "attr": { "description": "Please provide a phone number we can reach in case of emergency" }, "propertyOrder": 1 } } ``` ## Submitting extra customer data The extra customer data can be submitted to the cart via the `/carts/{cartUuid}/customer` endpoint, either together with the lead booker information or separately: ```bash curl -X PUT '{baseUrl}/carts/{cartUuid}/customer' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "extra_customer_data": { "1714c6a7-2046-11e7-9cc9-06a7e332783f": { "phone_number": "1234567890" } } }' ``` ### Multiple activities When multiple activities in the cart require extra customer data, include data for all relevant activities in the request: ```bash curl -X PUT '{baseUrl}/carts/{cartUuid}/customer' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "extra_customer_data": { "1714c6a7-2046-11e7-9cc9-06a7e332783f": { "phone_number": "1234567890" }, "165fcd4d-2046-11e7-9cc9-06a7e332783f": { "go_kart_color": "red" } } }' ``` ### Combined with lead booker data You can submit extra customer data together with lead booker information in a single request: ```bash curl -X PUT '{baseUrl}/carts/{cartUuid}/customer' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "firstname": "John", "lastname": "Doe", "email": "john.doe@example.com", "musement_newsletter": "NO", "allow_profiling": "NO", "thirdparty_newsletter": "NO", "events_related_newsletter": "NO", "extra_customer_data": { "1714c6a7-2046-11e7-9cc9-06a7e332783f": { "phone_number": "1234567890", "meal_preference": "Vegetarian" } } }' ``` ### Checkbox field submission For checkbox fields (multiple selection), submit an array of selected values: ```bash curl -X PUT '{baseUrl}/carts/{cartUuid}/customer' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "extra_customer_data": { "1714c6a7-2046-11e7-9cc9-06a7e332783f": { "allergies": ["Nuts", "Dairy"] } } }' ``` ## Error handling | HTTP Status | Error Code | Description | | --- | --- | --- | | 400 | — | Validation error. The submitted data does not match the schema requirements. | | 403 | — | Access denied. You don't have permission to access this cart. | | 404 | 1400 | Cart not found. The specified cart UUID does not exist. | ### Validation error example When submitted data fails validation: ```json { "code": 400, "message": "Validation Failed", "errors": { "children": { "extra_customer_data": { "children": { "1714c6a7-2046-11e7-9cc9-06a7e332783f": { "children": { "phone_number": { "errors": ["This value should not be blank."] } } } } } } } } ``` ### Cart not found example ```json { "code": 1400, "message": "Cart with uuid c5006703-79f2-4fb8-bb6d-f292b8b09eed not found" } ``` ## Important notes * Only cart items with status `TICKETS_AVAILABLE` are considered when building the extra customer data schema. Unavailable tickets do not contribute to the schema. * Extra customer data is grouped by activity UUID, not by cart item. If multiple cart items belong to the same activity, they share the same extra customer data group. * Custom questions from integration partners take precedence over extended fields configured in the database. * Field labels may be localized based on the request's locale information when translations are available. * The schema endpoint response is not cached and always reflects the current cart state.