Skip to content

Forms Engine

The Forms Engine is Runnit’s intake and form-building system. Forms are brand-consistent by default, secured by tiered access, and backed by a full submission workflow: routing, custom statuses, approvals, actions, webhooks, and a portal where submitters can check their status.

Forms are a Runnit Studio artifact type, built and listed alongside your pages and widgets.

A form is a single definition covering its fields, branding, security, AI review, workflow, and routing. You build it in the visual editor, and everything you configure is re-checked on the server when a form is submitted: validation, visibility, required fields, computed values, the AI gate, file rules, and routing are all enforced centrally rather than trusted from the browser.

Forms support a wide range of fields:

short text, long text, rich text, number, currency, date, date range, email, phone, url, single select, multi select, checkbox, radio, rating, signature, file, section, hidden, computed, and lookup.

Fields can be shown, required, or disabled based on other answers. Conditions support compound AND/OR logic with operators like equals, not equals, greater/less than, contains, in, is empty, starts with, and ends with, so you can express rules such as “require a PO number only when the request type is external”.

A computed field derives its value from other numeric fields using a simple expression (for example qty * price). Computed values are always recalculated on the server, so they can’t be tampered with from the browser.

A lookup field can pull its options from your data: for example a list of clients. On public and password-protected forms, lookups may only read curated data grants: admin-approved sources with a fixed query, a limited set of allowed fields, and a row cap. This keeps public forms from ever reaching arbitrary data.

Every form has one of three access tiers:

TierWho can submitProtection
InternalSigned-in app usersApp authentication
PasswordAnyone with the link and passwordPassword gate, optional Cloudflare Turnstile
PublicAnyone with the linkCloudflare Turnstile required, plus honeypot and rate limiting

Public and password forms are served at an unguessable, friendly link (a random xxxx-xxxx code) rather than a predictable address.

file fields are validated against the field’s rules (size, extension, MIME type) and your organisation’s upload limit, then stored through Runnit’s standard asset pipeline as a private, un-indexed file. Submissions show uploaded files as links.

When AI review is enabled, the server runs a structured review of each submission and produces findings with a check, severity, message, and suggestion. You choose how strict it is:

  • Soft gate: warns the submitter but lets them continue.
  • Hard gate: blocks submission while a blocking finding remains.

Submitter content is treated as untrusted, fields marked as personal information are redacted before review, and every review is stored for audit.

Submissions aren’t just a status field: they move through an explicit workflow you define:

  • Custom statuses with tones (info, accent, success, danger), an initial status, and terminal statuses.
  • Transitions between statuses that specify who may make them, whether a reason is required, and whether the move counts as an approval.

When a form is submitted, Runnit validates it, runs the AI gate, saves the submission and its answers with an audit trail, resolves who it should be routed to, runs any on-submit actions, and (if the portal is enabled and an email was given) sends a receipt link.

Submissions can be routed to people or roles, with optional conditions: for example, send to a director only when a total exceeds a threshold. Approval policies support sequential or parallel approvers with a quorum.

A transition or submission can trigger actions:

  • Create brief: turns a submission into a Runnit brief.
  • Webhook: sends the submission to an external URL with reliable delivery.
  • Notify: sends an email.
  • Emit event: emits an event into Runnit’s pipeline.

Outbound webhooks are delivered reliably: each delivery is logged, retried with exponential backoff, de-duplicated with idempotency keys, and signed (X-Runnit-Signature) so the receiver can verify it came from Runnit. Operators can replay a delivery from the submissions view.

A submission can be tied to a client organisation, in two ways:

  • Per-client links: generate a short, stable link for a specific client; submissions through it are tagged to that client.
  • Form-level binding: bind a whole form to a single client.

The client is available to the rule engine as a condition, so routing can branch on it (“if client X, route to person Y”). When set, the client flows into any create brief action and is shown on the submission.

Submitters can track their own submissions:

  • A receipt link, handed out at submission, is scoped to that one submission.
  • Viewing all of someone’s submissions requires email verification with a one-time code first, to prevent others from enumerating submissions.

You build forms in the visual editor inside Runnit Studio. It has resizable panels for the AI chat, a live preview with a built-in test run, and a right-hand panel with tabs:

  • Fields: drag-and-drop reordering, add/edit/delete, and an inline inspector.
  • Settings: title, access tier, Turnstile, password, AI co-pilot, and branding accent.
  • Routing: recipients (person or role, with conditions including client) and the approval policy.
  • Share: publish state, the public link, the status page, and per-client links.

You can also edit the form by chatting with the forms agent, which uses the same chat experience as the rest of Runnit Studio. It edits the form for you, validates the changes, and the editor reloads live as it works. A test run exercises the real engine as a dry run, so nothing is saved while you experiment.

The submissions inbox shows status chips and filters, answers rendered with their field labels and formatting (including file links), the client a submission belongs to, recipient names, the workflow actions available, webhook delivery status with replay, and a timeline of everything that happened.