Skip to content

Core Concepts

FlowForm's data model is designed around composable primitives. Understanding these six concepts covers everything in the system.

Forms

A form is the top-level container. Every form has:

FieldTypeDescription
uuidUUIDPublic identifier used in API calls
namestringHuman-readable name
slugstringURL-friendly identifier, auto-generated from name
descriptiontextOptional description
is_activebooleanOnly active forms appear in the public API
versionintegerIncremented when the form structure changes

Forms own steps, fields, entities, and submissions.

Steps

Steps divide a form into ordered pages. Each step has a step_number that determines its position in the sequence.

FieldTypeDescription
step_numberintegerPosition in the form (1-based)
titlestringStep heading shown to the user
descriptiontextOptional helper text
metaJSONArbitrary metadata (e.g., {"icon": "user"})
validation_rulesJSONStep-level validation configuration
is_visiblebooleanWhether the step is visible

Steps can be reordered. The form model provides a reorderSteps() method that handles the unique constraint on step_number safely.

Fields

Fields are the individual inputs within a step. Each field belongs to exactly one form and one step.

FieldTypeDescription
codestringUnique identifier within the form (e.g., first_name)
labelstringDisplay label
placeholderstringInput placeholder text
descriptiontextHelp text shown below the field
is_requiredbooleanWhether the field must have a value
is_repeatablebooleanWhether multiple values are allowed
default_valuestringPre-filled value
validation_rulesJSONLaravel validation rules as an array
configJSONType-specific configuration
orderintegerDisplay order within the step

The code field is unique per form, making it the stable key for referencing fields across API calls.

Field Types

Field types define what kind of input a field renders. Each type maps to a frontend component.

NameComponentNotes
texttext-inputSingle-line text
emailemail-inputEmail with validation
numbernumber-inputNumeric input
textareatextarea-inputMulti-line text
selectselect-inputDropdown with options
checkboxcheckbox-inputBoolean or multi-select
radioradio-inputSingle choice from options
datedate-inputDate picker
filefile-inputFile upload
headingheading-displayDisplay only, not a data field
paragraphparagraph-displayDisplay only, not a data field

Types marked with is_display: true in their meta are purely visual -- they do not collect data.

Fields of type select, radio, or checkbox can have field options: an ordered list of label/value pairs.

Conditions

Conditions control field visibility and requirement status based on other field values. They enable dynamic forms without custom code.

FieldTypeDescription
field_idFKThe field being controlled
depends_on_field_idFKThe field whose value is evaluated
operatorstringComparison operator (e.g., equals, not_equals, contains)
valuestringThe value to compare against
actionstringWhat happens when the condition is met (show, hide, require)

Example: Show the "Company Name" field only when "Employment Status" equals "employed".

Conditions are evaluated server-side. The /submissions/{uuid}/conditions endpoint returns the computed visibility and requirement state for every field, given the current submission values.

Submissions

A submission represents one user's progress through a form. Submissions track state through a lifecycle:

draft -> completed
FieldTypeDescription
uuidUUIDPublic identifier
form_idFKThe form being filled out
statusstringdraft or completed
current_stepintegerWhich step the user is on (1-based)
metaJSONArbitrary metadata (e.g., user agent, referrer)

Submission Values

Each field value is stored as a separate SubmissionValue record:

FieldTypeDescription
submission_idFKParent submission
field_idFKWhich field this value belongs to
entity_record_idFKOptional link to an entity record
valuestringThe submitted value

Values are upserted -- submitting a value for the same field replaces the previous one.

Entities and Entity Records

Entities model repeatable data groups within a form. Think of them as "sub-tables" -- for example, a "Dependents" entity in an insurance form where the user can add multiple family members.

Entity FieldTypeDescription
namestringInternal identifier
labelstringDisplay label
is_repeatablebooleanWhether multiple records are allowed

Each entity can have many entity records per submission. Entity records can be nested (parent/child) and link to submission values, allowing structured data collection within the flat submission model.

Licensed under CC BY 4.0.