set_layout
Design the form layout
Design Mode: add content blocks between a form's questions and put fields side by side in columns. Use this DIRECTLY (never call get_form first) whenever the user asks to add an image, photo, picture, text/explanation, YouTube/Vimeo video, or divider to the form itself, or wants fields side by side / on one row / in two columns ('put first and last name side by side'). Blocks: { key, type: image|text|video|divider, url (image/video), alt, markdown (text: paragraphs, **bold**, *italic*, [links](https://…)), and a position — before_field: <field key>, or page + placement: top|bottom (default: top of the first page) }. Rows: groups of 2–3 field keys that must sit next to each other on the same page; they always collapse to one column on phones. Each provided list REPLACES the current one ([] clears it; omit a list to leave it unchanged). Validation is self-correcting: a wrong field key lists the existing keys. Everything is validated (https-only assets, safe text subset) and mobile-safe by construction. For a welcome screen before the form starts, use update_form with settings.welcome ({ title, message, buttonLabel, imageUrl }). For colors/fonts/themes use update_form branding.theme; for steps/pages use set_pages.
Blocks anchor to your questions (before a field, or top/bottom of a page) and rows always collapse to one column on phones — every composition stays mobile-safe by construction. Assets are https-only and text uses a safe subset (bold, italic, links). For colors and fonts see design and branding; for steps use set_pages.
| Parameter | Type | Description |
|---|---|---|
| form_id | string | Form id (authenticated). From create_form/list_forms. |
| draft_token | string | Draft token (anonymous drafts, before sign-in). From create_form's draftToken. |
| blocks | array of object | Full block list (replaces the current one; [] removes all blocks) |
| blocks[].key | string | Stable block id, lowercase letters/digits/underscores, e.g. 'intro_photo' |
| blocks[].type | "image" | "text" | "video" | "divider" | |
| blocks[].url | string | image: https image URL · video: a YouTube or Vimeo link |
| blocks[].alt | string | image: accessible description |
| blocks[].markdown | string | text: paragraphs (blank line), **bold**, *italic*, [label](https://…) |
| blocks[].before_field | string | Render immediately before this field key |
| blocks[].page | string | Pin to a page (multistep); omit for the first page |
| blocks[].placement | "top" | "bottom" | Top or bottom of the page when before_field is not set |
| rows | array of object | Full row list (replaces the current one; [] removes all rows) |
| rows[].fields | array of string | 2–3 adjacent field keys sharing one row |
* required