Forms
A form is a Shout survey, quiz or poll. The API lets you list forms, read a form’s full structure, and create new forms with any of the 19 supported question types in a single call.
Reading requires the forms:read scope; creating requires forms:write.
How a form is shaped
Section titled “How a form is shaped”GET /v1/forms/{id} returns the form with its pages, and each page with its questions:
- Question
textis stored as HTML (that’s how the builder saves it). - Page and question
ids are integers; the formidis a UUID. statusis"active"(live/collecting) or"inactive"(closed). Trashed forms are never returned.- Use the question
ids to match answers when reading responses.
Creating a form
Section titled “Creating a form”POST /v1/forms creates a whole form — title, optional description/workspace, and its questions — in
one atomic call. On success you get 201 Created, a Location: /v1/forms/{id} header, and the created
form in the same shape as a read.
Provide questions either as a flat questions array (single-page shorthand) or as pages,
each with its own questions. If both are given, pages wins.
Common question fields
Section titled “Common question fields”Every question object takes these, regardless of type:
| Field | Type | Notes |
|---|---|---|
type | string | One of the type identifiers in the table below. Required. |
text | string | The question text (simple HTML allowed). |
required | boolean | Whether an answer is mandatory. Default false. |
friendlyId | string | Optional uppercase snake_case id to reference the question in formulas. |
Supported question types
Section titled “Supported question types”19 types are supported. The type identifier is the value you send (and, for most types, the value
you get back on read).
type | What it is | Key fields |
|---|---|---|
choose_one | Single choice (radio) | options (≥2), otherText |
dropdown | Single choice as a dropdown | options (≥2), otherText |
choose_any | Multiple choice (checkboxes) | options (≥2), otherText, minSelections, maxSelections |
multi_dropdown | Multiple choice as a dropdown | options (≥2), otherText, minSelections, maxSelections |
likert | Opinion scale, shown as buttons | scales ([{text, opposingText}]), scaleStart, scaleEnd |
likert_slider | Opinion scale, shown as a slider | scales, scaleStart, scaleEnd |
nps | Net Promoter Score, 0–10 | (no extra fields) |
binary | Yes/No, True/False | trueLabel, falseLabel, icon |
star_rating | Star rating | maxStars (default 5, max 10) |
textbox | Free-text input | rows, inputLimitation |
matrix | Rows rated against a shared scale | rowHeadings (≥1), columnHeadings, lastColumnIsNotWeighted |
ranking | Drag-and-drop ordering | rankOptions |
contact_details | Contact detail fields | contactFields ([{field, label, visible}]) |
date | Single date | datePlaceholder, collectTime |
date_range | A from/to date range | startDatePlaceholder, endDatePlaceholder, collectTime |
numeric | Numeric value | (created with default numeric formatting) |
file_upload | One or more upload slots | fileUploadSlots (labels, ≥1) |
signature | Signature capture | (no extra fields) |
payment | Stripe payment | amount (smallest currency unit, e.g. 1000 = $10.00), currency (ISO 4217), formula |
Field details:
options— a JSON array of label strings. Choice questions need at least 2.otherText— set it to add a free-text “other” option; omit for none.scales— one or more{ "text": "...", "opposingText": "..." }pairs (both ends required), e.g.{"text": "Very poor", "opposingText": "Excellent"}.icon(binary) —thumbs(default),tick_cross, orfaces.contactFields[].field— one of:first_name,last_name,company,address_line_1,address_line_2,city,state,zip_code,country,email,phone_number.labelis optional;visibledefaults tofalse, so set it totruefor fields you want shown.inputLimitation(textbox) — restricts accepted input, e.g.EmailorTelephone. Default is unrestricted.
Limits: a form may contain at most 200 questions.
Create errors
Section titled “Create errors”| Status | When |
|---|---|
400 invalid_request | Missing title, an unknown type, an unknown enum value (icon/contact field), or a structurally invalid question (e.g. fewer than 2 options). The message names the problem. |
422 unprocessable_entity | The form couldn’t be assigned an owner (no billable user on the tenant). |
Workspaces
Section titled “Workspaces”Forms can be filed under a workspace. GET /v1/workspaces lists them (requires forms:read).
Workspaces are small by nature, so the list is returned unpaginated. Use a workspace id when
filtering forms (workspace_id) or when creating a form (workspaceId).