Build public or authenticated forms that route submissions into entities, jobs, or both.
Forms
Forms are FastYoke's typed ingress layer. They collect data from anyone (or anyone you've authenticated), validate against a schema the builder owns, and feed submissions into your workflow via declarative actions.
What's covered
- Tutorials — guided 101 → 201 → 301 path that builds one Patient Intake form across every feature.
- Recipes — quick, isolated single-task pages.
- Tier entitlements — what each tier unlocks for the Forms surface.
- Anti-abuse — Turnstile, honeypot, daily caps, rate limit.
- Embed forms — drop a form into any page via the SDK.
- HTTP ingestion API — server-to-server submission.
- Invites (Mint) — named, revocable invite links.
- Vanity PDF filenames — readable filenames for submission PDFs.
Forms Builder
Pages, sections, field types, routing, themes, attachments.
Recipes
Short, isolated single-task pages for experienced builders.
Tutorials
Guided 101 → 201 → 301 path that builds one clinic Patient Intake form across every Forms Builder feature.
Embed forms on your own site
Drop a single script tag into any page to render a FastYoke form inline, with theme overrides and origin allowlists.
HTTP ingestion API
Server-to-server submission of form data via REST. Authenticate with a tenant API token, post a JSON payload, get a submission ID back.
Anti-abuse for public forms
Turnstile challenges, honeypots, daily caps, and per-IP rate limits keep public form submissions clean without a CAPTCHA wall.
Form invites (Mint)
Issue named, revocable invite links to public forms. The Mint endpoint produces a URL anyone can submit; revoked invites return 410.
Vanity PDF filenames
Generate human-readable filenames for submission PDFs using a pattern of slugs, submission IDs, field values, and dates.
Forms tier entitlements
What each tier unlocks for the Forms surface — active form count, daily submission ceiling, anti-abuse posture, PDF rendering, badge visibility.
Why forms are a first-class surface
Most platforms bolt forms on top of their entity model. FastYoke
treats forms as a separate quarantine zone: submissions land in
form-scoped tables with no FK path into entity_records. Promotion
to an entity is an explicit FSM action (PROMOTE_FORM_TO_ENTITY),
which means:
- A malformed submission can't poison your entity data.
- Files attached to a submission aren't silently copied into
entity_files— the promoter has to opt in per field. - The audit trail stays clean: every entity write has a named transition behind it.
Forms v2 at a glance
Forms run on the v2 schema:
- Multi-page — a form is a list of
pages, each owning a subset offields. Page navigation is linear by default. - Conditional routing — per-page JSONLogic rules can skip, branch, or short-circuit the stepper.
- File uploads — 20 MiB cap per attachment, scanned in three layers (MIME magic → VirusTotal → LLM content check). The submit handler claims attachments atomically at the same transaction as the submission INSERT.
- Themes — every form inherits the tenant's brand tokens; per-form overrides can pin a different theme or (when the feature flag is on) inject sanitized custom CSS.
- Entity field picker — author a form by importing annotated entity fields in one click; labels, requiredness, and enum options carry over.
Wire shape
Stored definitions are JSON. The renderer + validator share the same zod-backed contract on both sides of the wire. Old v1 rows are read-shimmed into v2 on every read, and every write emits v2, so you never have to migrate by hand.
Public submission API
Anonymous (token-keyed) submissions go through:
GET /api/v1/public/forms/:token # fetch the form schema
POST /api/v1/public/forms/:token/submit # submit a payload
The token is what the admin shell shows you when you publish a form
— the form's slug stays admin-side and is never exposed publicly.
Submit body is { "payload_json": { /* keyed by field key */ } }.
The success response is:
{
"submission_id": "01HXY…",
"form_definition_id": "01HXX…",
"definition_version": 7,
"processing_state": "received",
"submitted_at": "2026-05-03T18:14:22Z",
"pdf_download_url": "https://tenant.fly.dev/api/v1/public/attachments/…?sig=…&exp=…"
}
pdf_download_url is a 15-minute HMAC-signed URL pointing at the
PDF that was rendered for this submission. It's omitted when:
- the form has no PDF template attached, or
- the per-form
pdf_on_submitflag is off, or - the render attempt failed (the submission itself still succeeded — render failures don't block ingestion).
A --template nextjs consumer app scaffolded with the
fy CLI renders the
download URL as a one-tap "Download your signed copy" link
when present.
PDF templates
Forms can carry a PDF template that gets rendered with each submission. Two kinds:
- AcroForm — start from an existing fillable PDF; FastYoke fills the form fields from your form payload, embeds signature images as native PDF widgets, and flattens the result.
- Overlay — start from any PDF; place value/signature regions on the page coordinates you choose. Multi-page overlays and per-submission signatures are supported.
Both paths are deterministic: the same payload_json re-renders to
a byte-identical PDF. Templates are configured per form in the
admin shell's Forms Builder.
Form submissions emit form.submitted outbound webhooks;
see Webhooks → Managing subscriptions
for the subscription model and REST surface.