Answer formats
The JSON value each question type takes in the answers object of the Response Submit API, with examples and the checks applied.
answers is an object keyed by question. The key is the question's slug, or its UUID for a question without a slug. The value's shape depends on the question type. This page lists every type.
{
"status": "completed",
"answers": {
"how-likely-are-you-to-recommend-us": 9,
"01a1443e-d8bf-799f-addc-ce90f76e26a1": "i-use-it-regularly"
}
}Get the exact keys and options for your form
Option values, scale ranges, and limits are set per question. Look them up in Distribution → API → View questions, or in the form's OpenAPI document (Distribution → API → Send a response → OpenAPI). The document has a JSON Schema and an example for every question on the live version.
General rules
- Skip a question by leaving it out or sending
null. Required questions are not enforced. - Choice values are option values (for example
fast-delivery), not the labels shown to respondents. - One key per question. Answering the same question by slug and by UUID returns
duplicate_answer. - Unknown keys return
unknown_question. - Screens take no answer. Welcome, thank you, message panel, and exit form keys return
not_answerable. - Deprecated types (annotation, UPI payment) return
unsupported_question_type. - Wrong JSON types return
invalid_type. Extra keys inside an object answer returnunsupported_field.
Scales
| Type | Value | Example |
|---|---|---|
| Rating | Integer from 1 to the number of ratings (default 10) | 4 |
| NPS | Integer from the scale minimum to maximum (default 0–10) | 9 |
| CSAT | Integer from 1 to the scale size (default 5) | 5 |
| Opinion Scale | Integer from the start value through the last step (default 0–10) | 7 |
A value outside the range returns out_of_range.
Choices
| Type | Value | Example |
|---|---|---|
| Yes / No | true or false | true |
| Consent | true or false | true |
| Single Choice | Option value | "i-use-it-regularly" |
| Multiple Choice | Array of option values | ["fast-delivery", "easy-checkout"] |
| Picture Choice | Array of option values; one item when the question allows a single choice | ["blue"] |
| Ranking | Array of option values in rank order, first is rank 1 | ["price", "quality", "speed"] |
| Nested Selection | Array: the path of option values from the top level down to a final choice | ["europe", "germany", "berlin"] |
Checks:
- A value that is not one of the question's options returns
invalid_option. An option listed twice returnsduplicate_option. - Fewer or more selections than the question's minimum or maximum returns
too_few_selectionsortoo_many_selections. A ranking must rank at least the question's minimum number of options. - A nested selection path that stops before an option with no children returns
incomplete_path.
The Other option
When a single choice or multiple choice question has an Other option, it is the question's last option. Its value appears in View questions, for example $Other. To send the respondent's own text, wrap the answer in an object:
{
"answers": {
"how-did-you-hear-about-us": { "value": "$Other", "otherText": "A podcast" },
"what-did-you-like-most": { "values": ["fast-delivery", "$Other"], "otherText": "The packaging" }
}
}Single choice uses value, and multiple choice uses values. Sending otherText without the Other option selected, or on a question with no Other option, returns other_not_allowed. The text must meet the Other field's character limits.
Text and contact fields
| Type | Value | Example |
|---|---|---|
| Short Answer | String | "Jane" |
| Long Text | String | "Tracking updates could be more frequent." |
| String, a valid email address | "jane@example.com" | |
| Website | String, a website address; https:// is assumed when no scheme is given | "https://example.com" |
| Number | Number; whole numbers unless the question allows decimals, and no negatives unless it allows them | 42 |
| Date | "YYYY-MM-DD", or "YYYY-MM-DDTHH:MM" when the question includes time | "2026-01-15" |
| Phone | { "countryCode", "number" }, with optional e164 | see below |
| Address | Object with the address parts that are on for the question | see below |
{
"answers": {
"phone": { "countryCode": "+44", "number": "7700900123" },
"shipping-address": {
"addressLine1": "221B Baker Street",
"addressLine2": "Flat 2",
"city": "London",
"stateProvince": "Greater London",
"postalCode": "NW1 6XE",
"country": "United Kingdom"
}
}
}Checks:
- Text length. Fewer or more characters than the question's minimum or maximum returns
too_shortortoo_long. The minimum is counted after trimming, and an empty string is allowed. - Format. A short answer with a validation pattern must match it. Emails, websites, dates, and phone numbers must be valid. Otherwise the API returns
invalid_format. - Ranges. Numbers and dates outside the question's minimum or maximum return
out_of_range. - Phone.
countryCodelooks like+44.numberholds digits, spaces, brackets, and hyphens.e164is computed when you leave it out. - Address. The parts are
addressLine1,addressLine2,city,stateProvince,postalCode, andcountry. A part that is switched off on the question returnsfield_disabled.
Matrices
| Type | Value | Example |
|---|---|---|
| Rating Matrix | Object: statement value → numeric scale point value | { "ease-of-use": 5, "speed": 4 } |
| Matrix Single | Object: row value → column value | { "mobile-app": "weekly" } |
| Matrix Multiple | Object: row value → array of column values | { "mobile-app": ["ios", "android"] } |
You can leave out rows the respondent did not answer. Unknown rows, statements, or columns return invalid_option. A rating matrix whose scale points are text cannot be sent through the API yet (unsupported_scale).
Files, signatures, and recordings
Upload the file first with Upload File. Then send the fileId it returns.
| Type | Value |
|---|---|
| File Upload | Array of { "fileId" }; one item unless the question allows multiple files |
| Signature | { "mode": "type", "typedName" }, or { "mode": "draw" | "upload", "fileId" } |
| Video / Audio | { "mode": "text", "text" }, or { "mode": "video" | "audio" | "photo", "fileId", "durationSeconds"? } |
{
"answers": {
"attach-your-receipt": [{ "fileId": "c2a7e1f4-5b3d-4a9e-8f61-0d2b7c9e4a18" }],
"sign-here": { "mode": "type", "typedName": "Jane Doe" },
"tell-us-in-a-video": {
"mode": "video",
"fileId": "9b1d4e7a-2c3f-4a5b-8e6d-1f0a9c8b7e65",
"durationSeconds": 42
}
}
}Only the modes that are on for the question are accepted (mode_not_allowed), and the file's type must match the mode. durationSeconds cannot exceed the question's maximum duration. File errors: too_many_files, duplicate_file, file_not_found (unknown, expired after 24 hours, or uploaded for another question), and file_already_used.
Scheduler and Q&A with AI
| Type | Value |
|---|---|
| Scheduler | { "provider", "bookedAt" }; Calendly also needs slotStart and slotEnd, and takes an optional eventId |
| Q&A with AI | Array of { "question", "answer" } pairs, up to the question's maximum (default 20) |
{
"answers": {
"book-a-call": {
"provider": "calendly",
"slotStart": "2026-01-20T10:00:00Z",
"slotEnd": "2026-01-20T10:30:00Z",
"bookedAt": "2026-01-15T09:30:00Z"
},
"interview": [
{ "question": "What did you like most?", "answer": "The hands-on exercises." }
]
}
}provider is the question's provider, google_calendar or calendly. More pairs than a Q&A question allows return too_many_items.
Time spent per question
timeSpentMs is keyed exactly like answers and holds the milliseconds spent on each question. It is optional and never rejects the request. See timeSpentMs for how values are read.
{
"timeSpentMs": {
"how-likely-are-you-to-recommend-us": 4200,
"what-did-you-like-most": 12500
}
}Related
Was this page helpful?
POSTUpload File
Upload a file for a file upload, signature, or video and audio question with POST /v2/admin/forms/{formId}/uploads, then reference its fileId in a response.
POSTCustom formats
Accept the JSON another system already sends, such as a CRM or survey webhook, by mapping its fields onto the Standard body with a custom format.
