Forms and survey questions
A Smart Schedule's definition includes two separate question collections:
| Collection | Purpose | Used by |
|---|---|---|
matchingForm | Drives host routing — answers determine which hosts are eligible | /availability (required), /scheduled-meetings (required, echoed) |
surveyQuestions | Informational pre-booking questions | /scheduled-meetings (optional) |
Both are captured on the schedule definition and submitted with answers at booking time. Only the matching form influences which host is offered.
MatchingForm
The intake form whose responses drive routing. Submit answers as formValues on /availability and /scheduled-meetings.
The MatchingForm schema
Fields
fields list
The form's questions, in display order. Each is a MatchingFormField.
{
"fields": [
{
"key": "region",
"label": "Region",
"type": "select",
"options": ["NA-East", "NA-West", "EMEA"],
"required": true
}
]
}MatchingFormField
A single question on the matching form.
Fields
| Attribute | Type | Description |
|---|---|---|
key | string | Stable identifier for this question. Use this as the key when submitting answers on formValues. |
label | string | The question text to display to the end-user. |
type | string | The field's shape. One of text, long-text, select, multi-select, email, phone, number, date. |
options | list | Present only when type is select or multi-select. An array of allowed values (strings). |
required | boolean | Whether an answer must be provided. |
Submitting form values
formValues on /availability and /scheduled-meetings is a map keyed by MatchingFormField.key, not an array of objects.
Single-value fields
Multi-select fields
For a multi-select field, pass an array of the selected option values:
The server accepts either a scalar or a one-element array for a select field — both round-trip cleanly.
Validation
Validation runs at both /availability (against the schedule's field definitions) and /scheduled-meetings (against both the field definitions and the values that were used to issue the slot token). Failures return 422 form-validation with a fieldErrors[] array naming each offending field key.
Unknown keys are rejected rather than silently dropped.
{
"formValues": {
"region": "NA-East",
"companySize": "51-200"
}
}{
"formValues": {
"useCases": ["Lead routing", "Demo scheduling"]
}
}SurveyQuestions
Informational pre-booking questions. Not used for routing. Captured on the meeting record, included in the confirmation email and calendar event body, and delivered in the post-booking webhook payload.
The SurveyQuestions schema
Returned as a flat list on the schedule:
Fields
| Attribute | Type | Description |
|---|---|---|
key | string | Identifier used when submitting the answer on /scheduled-meetings. |
label | string | The question text to display. |
type | string | Always long-text in v1 — the underlying data model stores questions with only text and a required flag, so a narrower type would be invented rather than reported. |
required | boolean | Whether an answer must be provided to complete booking. |
Survey questions are keyed by text
The key field is derived from the question text because the underlying data model does not currently persist a stable identifier for survey questions. Consequences a partner has to know about:
- Renaming a question changes its
key. A caller that hardcodes keys will start sending values under a key the schedule no longer offers, and the booking will fail with422. labelandkeyare effectively the same string.- Reordering questions does not change their keys — reordering was rejected as an alternative because it would silently rebind stored answers to different questions.
A persisted per-question id is a known follow-up; this page will be updated when it lands.
{
"surveyQuestions": [
{
"key": "whatBrings",
"label": "What brings you here today?",
"type": "long-text",
"required": false
},
{
"key": "howDidYouHear",
"label": "How did you hear about us?",
"type": "long-text",
"required": false
}
]
}Submitting survey answers
surveyResponses on /scheduled-meetings is a map keyed by the survey question's key, not an array:
Because key is derived from question text, this is equivalent to keying by the question text itself.
Unknown keys are rejected with 422. Required questions that receive no answer are also 422, reported once per missing question in the response's fieldErrors[] array.
{
"surveyResponses": {
"whatBrings": "Pipeline visibility",
"howDidYouHear": "Referral from a colleague"
}
}