Skip to content

Feature guides

How the newer parts of the platform work through the API. Scopes are the ones the request needs.

Results triage

Give every response a status (new, in_review, approved, rejected, done), an assignee and tags without touching its answers. GET /forms/{id}/triage (submission:read) returns the state of triaged responses and who can be assigned; PATCH /submissions/{id}/triage and POST /submissions/bulk-triage (up to 500, form:write) change it. Corrections to an answer are separate: POST /submissions/{id}/edits keeps the original and .../edits/{editId}/revert brings it back. Saved views of filters are under /forms/{id}/views.

Spam and captcha

POST /submissions/{id}/spam files a response as spam; POST /submissions/{id}/restore moves it back and fires the completion events, webhooks and notifications at that moment. settings.minCompletionMs files implausibly fast completions as spam automatically. A workspace stores its own Turnstile or hCaptcha keys with PUT /captcha (workspace:manage, secret write-only); the deployment-wide CAPTCHA_* variables are the fallback, and the form turns it on with settings.captcha.

POST /forms/{id}/share-links (analytics:read) makes a signed, revocable, read-only link to a results page. Mode aggregate shows charts only; mode respondents also lists individual answers for the fieldIds you choose and needs submission:export. Sensitive, file and signature questions are refused. The url is a bearer capability: set expiresInDays and a password, and revoke with DELETE /share-links/{linkId}.

Version history and restore

bash
GET  /forms/{id}/version-history              # versions, draft changes, undoable restores
GET  /forms/{id}/versions/compare?from=3&to=draft
POST /forms/{id}/versions/3/restore           # replaces the DRAFT; the old draft is snapshotted first
POST /forms/{id}/restores/{snapshotId}/undo   # once per snapshot

A restore never changes the live form. Review the draft, then publish. Needs form:write.

Invitations

POST /forms/{id}/invitations creates up to 500 links, each reusable or single-use (singleUse), optionally emailed to the address you give. Attributes you attach are available to logic as the respondent condition source. Each token and link appears once in the response; only a hash is stored. Revoke with DELETE /forms/{id}/invitations/{invitationId}.

With settings.respondentEdit.enabled the respondent gets a signed link (valid expiresDays, default 30) to change their answers. GET and PUT /public/forms/{slug}/edit serve it. Validation is the same as a first submit and every change stays in the response's edit history.

Email and phone verification

Set verify: true on an email or phone field. The form calls POST /public/forms/{slug}/verify with action: send and then check; codes last 10 minutes and allow 5 attempts. The proof from check goes back with the submission. SMS needs SMS_PROVIDER=twilio with Twilio credentials and has not been verified against Twilio.

Input masks, recording and address lookup

File uploads accept up to 250 MB per file on local disk storage. With S3 multipart storage configured (S3_BUCKET and keys) maxSizeMb can be set up to 5120 (5 GB): the browser uploads in 8 MB parts straight to the bucket. Files above 256 MB are not loaded into memory, so they are not re-encoded or hashed, and they are refused when a virus scanner is configured.

mask on short_text and phone uses 9 for a digit, a for a letter and * for either. record on file_upload lets people record video or audio in the browser. autocomplete on address proxies suggestions through ADDRESS_PROVIDER (google or mapbox) so the key never reaches the browser; without a provider the form keeps its manual fields.

Coupons, quotes and checkout recovery

POST /public/forms/{slug}/coupon answers only { valid }. POST .../quote returns the server-side order summary. After a provider redirect, poll GET /public/payments/{submissionId}; a lapsed checkout is recovered with POST .../checkout, which never creates a second charge for a paid order.

Data sources

POST /data-sources (integration:manage) defines a server-side lookup against Airtable, Google Sheets or Notion. Choice fields can load their options from it (GET /public/forms/{slug}/choices/{fieldId}, with origin telling live, cache, stale, fallback or unavailable), and a key lookup can prefill from one record. Only columns you expose are returned.

Approvals and e-signature

Workflows can pause for approval. GET /approvals lists them, approvers decide in the app or from a personal one-time emailed link, and resend and cancel need integration:manage. POST /signing sends a document to up to 10 signers with a hash-chained audit trail that GET /signing/{id}/verify recomputes. FormFlow makes no compliance or certification claim for signatures; whether they are legally sufficient depends on your jurisdiction and use.

Integration health

GET /integrations/health shows each connection's last success, failing step and retry state. POST /integrations/connections/{id}/test runs a read-only check (providers that cannot be checked without sending data answer unchecked). POST /integrations/executions/{id}/replay reruns the failed steps once per failure state and warns about steps whose target cannot de-duplicate.

Targeting and experiments

GET /public/targeting?workspace=... serves the enabled trigger rules and audiences of published forms. It contains no answers. A/B tests (patch or whole-form versions, multivariate, question-level) are created in the app because a version can carry custom code, and are also available through the API, the SDK and MCP: list and read results, start, stop, declare a winner, and report downstream conversions with POST /experiments/{id}/conversions (form:write). An experiment verdict says when the sample is too small; do not call a winner from it. See A/B testing onboarding with PostHog.

New theme and field options

WhereOption
themequestionSize xs (16-20px titles), choiceStyle tile, customFonts, logoPlacement top_right, background fit, position and imageOpacity
image_choicecardStyle tile, cardSize, badgePlacement
mediaframe, fit, ratio, scrim, textTone, size, vignette
welcomehideTitle, inlineFirst, align, mediaPosition, lockup
settingsnavStyle, sidePanel, header, i18n, offline, kiosk, softCap, blocks, quotas, notifications.rules
logicset_value, disable_field, enable_field actions; lead_score and score condition sources