Internal Forms

Last updated 25 May 2026

An entity-bound form open inside a contact profile, and a virtual form pinned to the top-nav of Flexie

A form is Internal when its Form type was set to "Internal" at creation. The sub-flavour is decided by its record type:

Both share the same builder, fields, and settings; they differ in where they appear and what the workflow listener gets.

Entity-bound internal forms

What they are

A form attached to a specific record type. When your team is looking at, say, a Contact's profile, they can open this form to fill in some structured information about that contact. The submission is stored against that contact, and the workflow that fires can read both:

Where the form appears

Open the form's Settings to decide where it surfaces:

Setting Effect
Show on profile Adds a button or panel to the record's profile so the form is available from there (default: on).
Show in top navigation Adds a quick-launcher entry to the top bar so a user can open the form from anywhere, but it will still need a record to attach to.
Show in dialer Adds the form to the dialer panel, useful for call-logging forms.
Icon The icon shown next to the form's name in those menus (a Font Awesome class such as far fa-plus-square).

You can tick any combination.

Prefill, values pulled from the record

The form pre-fills any field whose key matches a field on the record. So a form with a field keyed email opened against a contact whose email is john@example.com will start with that email already in the box. The user can edit it before submitting.

This is automatic, no configuration needed. It works because the field's key (set in the field's per-field settings) is matched against the record's field aliases. If you want a prefill, give the field the same key as the record's field alias (which you can find in the relevant Custom Fields page, e.g. /contact-fields).

Access control

By default an internal form is visible to everyone who can use Flexie. To restrict it, set Form access in the form's Settings. You can grant access by any combination of:

A user must match at least one entry to see the form.

What the workflow listener gets

The listener key is form.internal_submit, and the submission's data lands under __data.internal_form_submission:

{{ __data.internal_form_submission.data['First Name'] }}
{{ __data.internal_form_submission.data['Notes'] }}

{{ __data.internal_form_submission.date_added }}
{{ __data.internal_form_submission.__submitted_from_user_id }}
{{ __data.internal_form_submission.__submitted_from_user_full_name }}

Notice:

Because the workflow runs on the record the form was opened against, you also have all of that record's fields at the top level (e.g. {{ id }}, {{ email }}). See Reading records for the rule.

Virtual internal forms

What they are

A form not tied to any one record, surfaced in the top navigation or dialer as a quick action your whole team can run from anywhere. There's no profile to attach the submission to; the submission stands alone.

Use it for things like:

Where it appears

Same Settings options as entity-bound forms (Show in top navigation, Show in dialer), except there's no profile to "Show on profile", because there's no record type.

What the workflow listener gets

The listener key is virtual_workflow.internal_virtual_entity_submit, and the submission's data lands under __data.internal_form_submission:

{{ __data.internal_form_submission.data['First Name'] }}
{{ __data.internal_form_submission.__submitted_from_user_id }}
{{ __data.internal_form_submission.__submitted_from_user_full_name }}

Notice, compared to the entity-bound listener:

The two listeners side by side

Entity-bound (form.internal_submit) Virtual (virtual_workflow.internal_virtual_entity_submit)
Workflow record type The record's type (Lead, Contact, …) __virtual
__data root internal_form_submission internal_form_submission
Field values under …data. …data.
Submitter user id …__submitted_from_user_id …__submitted_from_user_id
Submitter user name …__submitted_from_user_full_name …__submitted_from_user_full_name
date_added Yes No
Current record fields available top-level Yes, fields of the record the form opened against No, there is no record

If you build internal forms regularly, this table is worth bookmarking.

Pushing a form to a user from a workflow (the "trigger internal form" action)

A workflow can send a form to a user mid-flow and pause for them to fill it in. This is the Trigger Internal Form action.

Example flow:

  1. Trigger: a new high-value lead is assigned.
  2. Step 1: Trigger Internal Form "Qualification Questions", routed to the lead's owner.
  3. Step 2: once they submit, branch on the answers and continue.

The action accepts:

The action is immediate, it doesn't queue. The form appears for the chosen user in their interface, and the workflow's next step runs once the user submits.

This is covered in Forms in workflows.

Tips and pitfalls

Next steps