Skip to content

Embed a model-bound public form in a page

A form block has two completely different behaviours, and source.form_id is the switch between them. Without it the block renders its own children as a direct model-bound form and posts to the records route. With it the block renders a stored form instead: the field set, validation and submit all come from that form, and the block’s children are never rendered.

Create the form first and state its access explicitly. settings.access takes "public" for an anonymous visitor or "authenticated" for a signed-in application user. A form created with empty settings is refused, so there is no accidental anonymous surface; choose the value rather than letting it default.

Then put a form block on the page carrying only source.form_id. At render the page fetches the form’s field definitions from GET /api/v1/public/app/{app_slug}/forms/{form_id}/render and submits to POST /api/v1/public/app/{app_slug}/forms/{form_id}/submit with the body {"data": {...}}. Both routes are keyed by the application slug and the form id, so an embedded form works on a published page with no application API key in the browser.

The submit answers {success, form_id, record_id, redirect, record}. record contains {id, data} with persisted values, including rule computations, for non-credential fields listed on the form. Fields outside the form and credential hashes are excluded. A caller needing other fields must read them through its normal authorized read surface.

The actor is not a reason to choose between this shape and a direct model-bound create. A signed-in application user is the rule actor in both. An embedded form submit stamps the validated application user as submitted_by. A direct create from the same signed-in page goes through the consumer records route, POST /api/v1/public/apps/{application_id}/models/{model_id}/records, and stamps that same user as creator. An anonymous submit of a "public" form carries the anonymous actor id 00000000-0000-0000-0000-000000000000, never the application owner’s. The owner appears only behind an application API key. Such a create is a "builder" actor and its rule log is triggered by the owner. A rule that reads actor.id refuses it. Choose the embedded shape for the stored form’s field set, validation and explicit access.