Concepts

Page and submission

A form is a published page (page_type = form) identified by page_id (UUID). Fill creates a submission (child page). Submission values are keyed by field_name.

Field identity

Key Stable? Use
element.id Yes (page node) Bind host widgets
data.field_name Can change if authors rename Voice tools, store.get, save payload
Label Display only Never match or bind on label

After each page.get, resolve element.id → current field_name. store.bind({ elementId }) does that lookup.

FieldStore

One store per fill session. page.get loads fillable elements. User edits, bind, and voice patches merge into the same map.

Fillable element types: form_field, form_field_rating, form_field_score.

Generated UI in v1 implements form_field input types: text, textarea, number, date, boolean, select, multiselect. Layout nodes (headings, columns, media) are skipped. The SDK does not clone page layout.

Generated vs bound

Surface Who draws the control
Generated (FormView) SDK — linear list of primitives
Bound Host — map element.id → existing widget

Do not overlay a second Comprehendly form on host widgets. Unmapped fields still live in the store; render them separately or ignore them on save.

Voice

session_mode Behaviour
silent (default) Mic capture, no spoken assistant
assistant Spoken walkthrough of the same page

Mint with forms.voice.start. Capture runs on the hosted fill embed. Native apps load a WebView of the voice bridge. See Fill with voice.