Responses
Responses are the submissions to a form. They’re nested under a form (/v1/forms/{formId}/responses)
and require the responses:read scope.
Polling for new responses
Section titled “Polling for new responses”To poll for new responses, save the newest startedAt you’ve seen and pass it as since on your
next run — don’t reuse the cursor for that. Cursors walk a fixed snapshot; since fetches what’s
new.
A response ID only resolves under the form it belongs to — fetching it under a different form returns
404 not_found.
Response fields
Section titled “Response fields”| Field | Type | Notes |
|---|---|---|
id | string | Opaque response ID — safe to store, but don’t parse it. Not a UUID. |
completed | boolean | true if the respondent finished the form. |
startedAt | string | ISO-8601 UTC time the response began. |
timeTakenSeconds | integer | null | Seconds spent; null while a response is still partial. |
countryCode | string | null | Two-letter country code, if known. |
contactId | UUID | null | The linked CRM contact, if the respondent is identified. |
answers | array | One entry per answered question (see below). |
Answer value shapes
Section titled “Answer value shapes”Each entry in answers is one question, keyed by its integer questionId (matching the question
id from a form read):
{ "questionId": 7441598, "values": [ /* one or more values */ ] }values holds one entry per selected option / sub-field. A value is a union — only the fields
relevant to the answer are populated, the rest are null:
| Field | Populated for | Example |
|---|---|---|
optionId | Choice selections | "d820082d-..." — the chosen option’s UUID |
label | Choice / scale answers | "Dashboard", or a scale point like "8" |
text | Free-text answers | "More integrations please" |
number | Numeric / scored answers | 4 (also carries the numeric value behind a scale point) |
date | Date answers | "2026-07-01" |
Because it’s a union, read defensively: a single-choice answer has optionId + label (+ a
number if the option is scored); a text answer has only text; an unanswered question is simply
absent from answers (empty answers are omitted, not returned as blank values).