# Storefront layout (/ai/reference/storefront/storefront-layout)

Toolset `storefront_layout`, 18 tools.

## Actions [#actions]

### `theme_block_add` [#theme_block_add]

Add one block to a section or under another block.

Add one block (settings, token style, conditions) to a section or under parent_block_id; depth &lt;= 5. For element trees use theme_element_insert.

- Action key: `theme_block.add`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Parent section id |
| `type` | string | yes | Block type to add |
| `after_block_id` | string |  | Place it right after this element of the same parent and slot |
| `before_block_id` | string |  | Place it right before this element of the same parent and slot. Omit both to add it last |
| `settings` | map of any value |  | The new setting values, keyed by the setting ids the section or block type declares, e.g. &#123;"heading":"Summer sale","subheading":"Up to 40% off everything"&#125;. Text values are written in locale. An update changes exactly the ids given here; without settings it saves nothing. |
| `style` | map of any value |  | Token style: &#123; layout, spacing, size, media, typography, color, border, effects, hover, background, motion, dividers, visibility &#125;. Groups and tokens per type from theme_section_type_get. Every group is a nested object and every side or corner its own key: a field path such as spacing.padding.top is written &#123; "spacing": &#123; "padding": &#123; "top": "xl" &#125; &#125; &#125;, never as a dotted key and never padding: "xl". background holds media only (image, video, poster, fit, position, attachment, overlay, overlayOpacity); a background colour is color.background, and where the type declares a colour setting the colour is that setting, written in settings. Examples per group: spacing &#123;"padding":&#123;"top":"2xl","right":"lg","bottom":"2xl","left":"lg"&#125;,"margin":&#123;"bottom":"xl"&#125;&#125;; layout &#123;"direction":"row","justify":"between","align":"center","gap":"md"&#125;; size &#123;"maxWidth":"content","minHeight":"half-screen"&#125;; typography &#123;"size":"h2","weight":"semibold","align":"center"&#125;; color &#123;"text":"foreground","background":"muted"&#125;; border &#123;"width":"thin","color":"border","radius":"lg"&#125;; effects &#123;"shadow":"md"&#125;; visibility &#123;"mobile":false&#125;. Responsive: &#123;"spacing":&#123;"padding":&#123;"top":&#123;"base":"3xl","mobile":"xl"&#125;&#125;&#125;&#125;. Keys merge into the current style: send only what changes; null removes a key, a group set to &#123;&#125; is removed. Containers, columns and the Custom section stack children in a column, so there layout.justify is vertical and layout.align horizontal: align center shrinks headings and buttons and centres them while long text stays left. Leave alignment unset so text follows the theme; centre text with typography.align. |
| `conditions` | map of any value |  | Optional `conditions` on any section or element: &#123; audience?: "all" \| "guests" \| "customers", from?, until? &#125;. `audience` "guests" shows it only to shoppers who are not signed in, "customers" only to signed-in ones; "all" is the default and is dropped. `from` is the first moment it shows and `until` the first moment it no longer does, each a datetime value: An ISO 8601 date and time with its offset, such as `2026-12-31T23:59:00+01:00`. A bare date (`2026-12-31`) means midnight at the start of that day and a time without an offset is read on the store clock, both in the store time zone. Empty means unset. The storefront leaves a hidden element out of the page entirely. Replaces the stored conditions; &#123;&#125; or &#123; audience: "all" &#125; without dates clears them. |
| `slot` | string |  | Named region within the section |
| `parent_block_id` | string |  | Nest the new block under this block id |
| `locale` | string |  | Language the settings text is in. The theme's base language (overview base_locale) or omitted writes settings; any other language writes settings_i18n[locale]. Images, videos, URLs and links are shared by every language and written to settings, unless that language already has its own value in settings_i18n[locale], which is then replaced; own_in_locale gives a language its own value |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "type": "button",
  "settings": {
    "label": "Shop now"
  }
}
```

### `theme_block_move` [#theme_block_move]

Move a block to another section or place, with its settings.

Move a block between sections. Settings and settings_i18n stay on the block. A fixed element (pinned in place by the theme) cannot be moved.

- Action key: `theme_block.move`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `block_id` | string | yes | Block id to move, searched recursively in the source section |
| `from_section_id` | string | yes | Section currently holding the block |
| `to_section_id` | string | yes | Destination section |
| `after_block_id` | string |  | Place it right after this element of the same parent and slot |
| `before_block_id` | string |  | Place it right before this element of the same parent and slot. Omit both to add it last |
| `slot` | string |  | Optional slot to assign on the moved block |

Example input:

```json
{
  "template_id": "home",
  "block_id": "button-1",
  "from_section_id": "hero-1",
  "to_section_id": "banner-1"
}
```

### `theme_block_remove` [#theme_block_remove]

Remove a block from a section; a fixed element stays.

Remove a block from a section, searching nested blocks by id. A fixed element (pinned in place by the theme) cannot be removed.

- Action key: `theme_block.remove`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Parent section id |
| `block_id` | string | yes | Block id to remove, searched recursively |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "block_id": "button-1"
}
```

### `theme_block_update` [#theme_block_update]

Merge settings, translations and style into one block, or replace its conditions.

Merge settings (settings_i18n[locale] with locale) and token style into a block found by id; style merges key by key into the stored style, and conditions replace the stored ones. Style nests by group, for example style &#123;"spacing":&#123;"padding":&#123;"top":"2xl","bottom":"2xl"&#125;&#125;,"typography":&#123;"size":"h2"&#125;&#125;; never dotted keys such as "padding.top". own_in_locale gives one language its own image, video, URL or link; share_in_locale shares the base one again.

- Action key: `theme_block.update`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Parent section id |
| `block_id` | string | yes | Block id to update, searched recursively |
| `settings` | map of any value |  | The new setting values, keyed by the setting ids the section or block type declares, e.g. &#123;"heading":"Summer sale","subheading":"Up to 40% off everything"&#125;. Text values are written in locale. An update changes exactly the ids given here; without settings it saves nothing. |
| `style` | map of any value |  | Token style: &#123; layout, spacing, size, media, typography, color, border, effects, hover, background, motion, dividers, visibility &#125;. Groups and tokens per type from theme_section_type_get. Every group is a nested object and every side or corner its own key: a field path such as spacing.padding.top is written &#123; "spacing": &#123; "padding": &#123; "top": "xl" &#125; &#125; &#125;, never as a dotted key and never padding: "xl". background holds media only (image, video, poster, fit, position, attachment, overlay, overlayOpacity); a background colour is color.background, and where the type declares a colour setting the colour is that setting, written in settings. Examples per group: spacing &#123;"padding":&#123;"top":"2xl","right":"lg","bottom":"2xl","left":"lg"&#125;,"margin":&#123;"bottom":"xl"&#125;&#125;; layout &#123;"direction":"row","justify":"between","align":"center","gap":"md"&#125;; size &#123;"maxWidth":"content","minHeight":"half-screen"&#125;; typography &#123;"size":"h2","weight":"semibold","align":"center"&#125;; color &#123;"text":"foreground","background":"muted"&#125;; border &#123;"width":"thin","color":"border","radius":"lg"&#125;; effects &#123;"shadow":"md"&#125;; visibility &#123;"mobile":false&#125;. Responsive: &#123;"spacing":&#123;"padding":&#123;"top":&#123;"base":"3xl","mobile":"xl"&#125;&#125;&#125;&#125;. Keys merge into the current style: send only what changes; null removes a key, a group set to &#123;&#125; is removed. Containers, columns and the Custom section stack children in a column, so there layout.justify is vertical and layout.align horizontal: align center shrinks headings and buttons and centres them while long text stays left. Leave alignment unset so text follows the theme; centre text with typography.align. |
| `conditions` | map of any value |  | Optional `conditions` on any section or element: &#123; audience?: "all" \| "guests" \| "customers", from?, until? &#125;. `audience` "guests" shows it only to shoppers who are not signed in, "customers" only to signed-in ones; "all" is the default and is dropped. `from` is the first moment it shows and `until` the first moment it no longer does, each a datetime value: An ISO 8601 date and time with its offset, such as `2026-12-31T23:59:00+01:00`. A bare date (`2026-12-31`) means midnight at the start of that day and a time without an offset is read on the store clock, both in the store time zone. Empty means unset. The storefront leaves a hidden element out of the page entirely. Replaces the stored conditions; &#123;&#125; or &#123; audience: "all" &#125; without dates clears them. |
| `enabled` | boolean |  | Updated enabled flag |
| `locale` | string |  | Language the settings text is in. The theme's base language (overview base_locale) or omitted writes settings; any other language writes settings_i18n[locale]. Images, videos, URLs and links are shared by every language and written to settings, unless that language already has its own value in settings_i18n[locale], which is then replaced; own_in_locale gives a language its own value |
| `own_in_locale` | list of string |  | Setting ids given in settings (images, videos, URLs and plain links only) that become the own values of the locale language: that language shows the value given, the base and every other language keep theirs, and later writes in that language keep landing there. Needs a locale other than the base language. at most 64 items. 1 to 128 characters |
| `share_in_locale` | list of string |  | Setting ids (images, videos, URLs and plain links only) whose own value in the locale language is dropped, so that language shows the shared value again. Needs a locale other than the base language; leave these ids out of settings. at most 64 items. 1 to 128 characters |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "block_id": "button-1",
  "settings": {
    "label": "Shop now"
  }
}
```

### `theme_customizer_get` [#theme_customizer_get]

The theme's templates, pages, pop-ups, colour schemes, banners, languages and file problems; read it first.

Compact theme customizer overview: templates, theme pages, site_pages (content pages at their own URLs; own_layout means template page:&lt;id> exists, otherwise they share the page template), overlays (the platform pop-ups this theme draws, by their merchant names, where each is edited and the locked parts it always keeps), color_schemes (the named schemes a section or block's color_scheme setting picks), alternate_templates (saved variants of the product or category page), banners (the storefront announcement bars and promo, discount and newsletter pop-ups with their schedules), locales (base_locale is the language settings are written in; other languages are overlays), unpublished state, and schema_errors , theme file problems the merchant sees as a customizer banner; fix any before other work.

- Action key: `theme_customizer.get`
- Permission: `theme.read`
- Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |

Example input:

```json
{}
```

### `theme_element_catalog_get` [#theme_element_catalog_get]

The elements and section types that can be inserted, by picker category.

List insertable elements (platform, plugin, app and theme) with label, icon, category and source (the provider kind); with template_id only those offered there, plus the addable section types.

- Action key: `theme_element_catalog.get`
- Permission: `theme.read`
- Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string |  | Also list the section types this template can add |
| `category` | string |  | Only this picker category. one of "layout", "text", "media", "navigation", "product", "collection", "cart", "forms", "marketing", "content", "basic", "interactive", "commerce" |

Example input:

```json
{
  "template_id": "home"
}
```

### `theme_element_duplicate` [#theme_element_duplicate]

Copy an element right after itself in the same parent and slot.

Duplicate an element (block) right after itself in the same parent and slot, with its children, translations, style and conditions; copies get fresh ids and drop an anchor the page already uses.

- Action key: `theme_element.duplicate`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Section holding the element |
| `block_id` | string | yes | Element id to duplicate, searched recursively |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "block_id": "button-1"
}
```

### `theme_element_insert` [#theme_element_insert]

Insert an element tree into a section or under a block in one write.

Insert an element tree (type, settings, style, children) into a section or under a block in one call; ids are minted, field defaults seeded, accept lists, slots, setting keys and depth &lt;= 5 validated. Max 50 nodes.

- Action key: `theme_element.insert`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Section receiving the element |
| `parent_block_id` | string |  | Insert under this block; omit to insert directly in the section |
| `slot` | string |  | Named slot of the parent for the root element |
| `after_block_id` | string |  | Place it right after this element of the same parent and slot |
| `before_block_id` | string |  | Place it right before this element of the same parent and slot. Omit both to add it last |
| `locale` | string |  | Language the settings text is in. The theme's base language (overview base_locale) or omitted writes settings; any other language writes settings_i18n[locale]. Images, videos, URLs and links are shared by every language and written to settings, unless that language already has its own value in settings_i18n[locale], which is then replaced; own_in_locale gives a language its own value |
| `element` | object | yes | Root element; children nest the same shape |
| `element.type` | string | yes | Element type from theme_element_catalog_get. at least 1 characters |
| `element.settings` | map of any value |  | Settings overlaid on the field defaults (or the locale overlay with locale); an icon setting takes a Lucide icon name such as "shopping-bag" |
| `element.style` | map of any value |  | Token style, checked against the type style capabilities. Containers, columns and the Custom section stack children in a column, so there layout.justify is vertical and layout.align horizontal: align center shrinks headings and buttons and centres them while long text stays left. Leave alignment unset so text follows the theme; centre text with typography.align. |
| `element.conditions` | map of any value |  | Optional `conditions` on any section or element: &#123; audience?: "all" \| "guests" \| "customers", from?, until? &#125;. `audience` "guests" shows it only to shoppers who are not signed in, "customers" only to signed-in ones; "all" is the default and is dropped. `from` is the first moment it shows and `until` the first moment it no longer does, each a datetime value: An ISO 8601 date and time with its offset, such as `2026-12-31T23:59:00+01:00`. A bare date (`2026-12-31`) means midnight at the start of that day and a time without an offset is read on the store clock, both in the store time zone. Empty means unset. The storefront leaves a hidden element out of the page entirely. Replaces the stored conditions; &#123;&#125; or &#123; audience: "all" &#125; without dates clears them. |
| `element.slot` | string |  | Named slot of the parent this node renders in; omitted, the first slot that takes its type |
| `element.children` | list of any value |  | Child elements, same shape |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "element": {
    "type": "text",
    "settings": {
      "text": "Free shipping"
    }
  }
}
```

### `theme_media_search` [#theme_media_search]

Find the store's product, collection, category and media library photos to place in the theme.

Find store photos for any image the customizer places: published products (cover first), collections and categories (their artwork, else photos of their products), and the media library, the photos the store uploaded (the shop, its people, its place; a library row's title is its alt text). Use only items whose images is non-empty: a product's bind value goes in the image setting so the photo follows the product; otherwise set one of its images, a media library ref (media://&lt;id>), exactly as given. An image setting takes only such a ref or a bind, never a web address. For a section about people, a place or the store's story, prefer library photos over product shots. Up to 20 rows per kind, 5 images each.

- Action key: `theme_media.search`
- Permission: `theme.read`
- Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | string |  | Words from a title in the store's base language (theme_customizer_get base_locale); omit to list without a search. at least 1 characters |
| `kind` | string |  | Search only products, collections, categories or the media library; omit to search all four. one of "product", "collection", "category", "library" |
| `limit` | integer |  | Rows per kind, default 8. 1 to 20 |

Example input:

```json
{
  "query": "summer",
  "kind": "product"
}
```

### `theme_section_add` [#theme_section_add]

Add a section to a template, optionally from a preset, with settings, style and conditions.

Add a section to a template with optional settings, token style and conditions (audience, schedule). Mints a unique section id from the type. preset adds it as the customizer's Add section adds that starting layout, with its settings, style and elements (a design from theme_section_library_search is added by its type and one of its presets); settings and style then change it.

- Action key: `theme_section.add`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `type` | string | yes | Section type to add |
| `preset` | string |  | Preset id of the type to add it as that starting layout (theme_section_type_get lists them) |
| `after_section_id` | string |  | Place it right after this section; below the hero means after the hero id |
| `before_section_id` | string |  | Place it right before this section. Omit both to add it at the end of the page |
| `settings` | map of any value |  | The new setting values, keyed by the setting ids the section or block type declares, e.g. &#123;"heading":"Summer sale","subheading":"Up to 40% off everything"&#125;. Text values are written in locale. An update changes exactly the ids given here; without settings it saves nothing. |
| `style` | map of any value |  | Token style: &#123; layout, spacing, size, media, typography, color, border, effects, hover, background, motion, dividers, visibility &#125;. Groups and tokens per type from theme_section_type_get. Every group is a nested object and every side or corner its own key: a field path such as spacing.padding.top is written &#123; "spacing": &#123; "padding": &#123; "top": "xl" &#125; &#125; &#125;, never as a dotted key and never padding: "xl". background holds media only (image, video, poster, fit, position, attachment, overlay, overlayOpacity); a background colour is color.background, and where the type declares a colour setting the colour is that setting, written in settings. Examples per group: spacing &#123;"padding":&#123;"top":"2xl","right":"lg","bottom":"2xl","left":"lg"&#125;,"margin":&#123;"bottom":"xl"&#125;&#125;; layout &#123;"direction":"row","justify":"between","align":"center","gap":"md"&#125;; size &#123;"maxWidth":"content","minHeight":"half-screen"&#125;; typography &#123;"size":"h2","weight":"semibold","align":"center"&#125;; color &#123;"text":"foreground","background":"muted"&#125;; border &#123;"width":"thin","color":"border","radius":"lg"&#125;; effects &#123;"shadow":"md"&#125;; visibility &#123;"mobile":false&#125;. Responsive: &#123;"spacing":&#123;"padding":&#123;"top":&#123;"base":"3xl","mobile":"xl"&#125;&#125;&#125;&#125;. Keys merge into the current style: send only what changes; null removes a key, a group set to &#123;&#125; is removed. Containers, columns and the Custom section stack children in a column, so there layout.justify is vertical and layout.align horizontal: align center shrinks headings and buttons and centres them while long text stays left. Leave alignment unset so text follows the theme; centre text with typography.align. |
| `conditions` | map of any value |  | Optional `conditions` on any section or element: &#123; audience?: "all" \| "guests" \| "customers", from?, until? &#125;. `audience` "guests" shows it only to shoppers who are not signed in, "customers" only to signed-in ones; "all" is the default and is dropped. `from` is the first moment it shows and `until` the first moment it no longer does, each a datetime value: An ISO 8601 date and time with its offset, such as `2026-12-31T23:59:00+01:00`. A bare date (`2026-12-31`) means midnight at the start of that day and a time without an offset is read on the store clock, both in the store time zone. Empty means unset. The storefront leaves a hidden element out of the page entirely. Replaces the stored conditions; &#123;&#125; or &#123; audience: "all" &#125; without dates clears them. |
| `locale` | string |  | Language the settings text is in. The theme's base language (overview base_locale) or omitted writes settings; any other language writes settings_i18n[locale]. Images, videos, URLs and links are shared by every language and written to settings, unless that language already has its own value in settings_i18n[locale], which is then replaced; own_in_locale gives a language its own value |

Example input:

```json
{
  "template_id": "home",
  "type": "hero",
  "settings": {
    "heading": "Summer sale"
  }
}
```

### `theme_section_duplicate` [#theme_section_duplicate]

Copy a section right after itself, with fresh ids.

Duplicate a section right after itself with its settings, translations, style, conditions and elements; every copy gets a fresh id and drops an anchor the page already uses.

- Action key: `theme_section.duplicate`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Section id to duplicate |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1"
}
```

### `theme_section_library_search` [#theme_section_library_search]

Search the designed sections the store can add, with their presets and previews.

Search the designed sections the store can add (the Designs group of Add section, and a theme's own sections that declare what they are for): each with the part of the page it plays (kinds), its mood, the photos and products it needs, height, its presets and a preview image per preset in this store's theme. Add one with theme_section_add using its type and a preset id, then fill its texts and photos with theme_section_update_many; no code is needed. Filter by kinds and moods, words in any language, or the photos the store has.

- Action key: `theme_section_library.search`
- Permission: `theme.read`
- Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string |  | Page template to search for; default home |
| `kinds` | list of string |  | The part of the page the design plays; any of these. one of "strip", "campaign", "hero", "story", "spotlight", "collection", "category", "trust", "value", "proof", "newsletter", "countdown", "faq", "stats" |
| `moods` | list of string |  | How the design feels; any of these. one of "quiet", "bold", "editorial", "warm", "technical", "playful" |
| `query` | string |  | Words from the ask, in any language, matched to names, descriptions and keywords. at least 1 characters |
| `photos_available` | integer |  | Drop designs that need more photos than the store can give. at least 0 |
| `limit` | integer |  | Most designs to return, default 8. 1 to 20 |

Example input:

```json
{
  "kinds": [
    "hero"
  ],
  "limit": 5
}
```

### `theme_section_remove` [#theme_section_remove]

Remove a section from a template; a template's main section stays.

Remove a section from a template. A template's main section (template_get lists its type under required_section_types) shows the page's own data and cannot be removed.

- Action key: `theme_section.remove`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Section id to remove |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1"
}
```

### `theme_section_reorder` [#theme_section_reorder]

Put a template's sections in a new order.

Reorder a template's sections. section_ids must be a permutation of the current ids.

- Action key: `theme_section.reorder`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_ids` | list of string | yes | Permutation of the current section ids. at least 1 items |

Example input:

```json
{
  "template_id": "home",
  "section_ids": [
    "hero-1",
    "featured-1"
  ]
}
```

### `theme_section_type_get` [#theme_section_type_get]

A section or element type's fields, style capabilities, slots and accepted children.

Get a section or element type: fields, style capabilities with their token vocabulary, slots, accepted child types, max_blocks, nested block types, and the conditions and anchor rules.

- Action key: `theme_section_type.get`
- Permission: `theme.read`
- Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `type` | string | yes | Section or element type name |
| `kind` | string |  | Only when a section and an element share the name. one of "section", "element" |

Example input:

```json
{
  "type": "hero"
}
```

### `theme_section_update` [#theme_section_update]

Merge settings, translations and style into one section, or replace its conditions.

Merge settings (settings_i18n[locale] with locale) and token style into a section; style merges key by key into the stored style, and conditions replace the stored ones. Style nests by group, for example style &#123;"spacing":&#123;"padding":&#123;"top":"2xl","bottom":"2xl"&#125;&#125;,"typography":&#123;"size":"h2"&#125;&#125;; never dotted keys such as "padding.top". own_in_locale gives one language its own image, video, URL or link; share_in_locale shares the base one again.

- Action key: `theme_section.update`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Section id to update |
| `settings` | map of any value |  | The new setting values, keyed by the setting ids the section or block type declares, e.g. &#123;"heading":"Summer sale","subheading":"Up to 40% off everything"&#125;. Text values are written in locale. An update changes exactly the ids given here; without settings it saves nothing. |
| `style` | map of any value |  | Token style: &#123; layout, spacing, size, media, typography, color, border, effects, hover, background, motion, dividers, visibility &#125;. Groups and tokens per type from theme_section_type_get. Every group is a nested object and every side or corner its own key: a field path such as spacing.padding.top is written &#123; "spacing": &#123; "padding": &#123; "top": "xl" &#125; &#125; &#125;, never as a dotted key and never padding: "xl". background holds media only (image, video, poster, fit, position, attachment, overlay, overlayOpacity); a background colour is color.background, and where the type declares a colour setting the colour is that setting, written in settings. Examples per group: spacing &#123;"padding":&#123;"top":"2xl","right":"lg","bottom":"2xl","left":"lg"&#125;,"margin":&#123;"bottom":"xl"&#125;&#125;; layout &#123;"direction":"row","justify":"between","align":"center","gap":"md"&#125;; size &#123;"maxWidth":"content","minHeight":"half-screen"&#125;; typography &#123;"size":"h2","weight":"semibold","align":"center"&#125;; color &#123;"text":"foreground","background":"muted"&#125;; border &#123;"width":"thin","color":"border","radius":"lg"&#125;; effects &#123;"shadow":"md"&#125;; visibility &#123;"mobile":false&#125;. Responsive: &#123;"spacing":&#123;"padding":&#123;"top":&#123;"base":"3xl","mobile":"xl"&#125;&#125;&#125;&#125;. Keys merge into the current style: send only what changes; null removes a key, a group set to &#123;&#125; is removed. Containers, columns and the Custom section stack children in a column, so there layout.justify is vertical and layout.align horizontal: align center shrinks headings and buttons and centres them while long text stays left. Leave alignment unset so text follows the theme; centre text with typography.align. |
| `conditions` | map of any value |  | Optional `conditions` on any section or element: &#123; audience?: "all" \| "guests" \| "customers", from?, until? &#125;. `audience` "guests" shows it only to shoppers who are not signed in, "customers" only to signed-in ones; "all" is the default and is dropped. `from` is the first moment it shows and `until` the first moment it no longer does, each a datetime value: An ISO 8601 date and time with its offset, such as `2026-12-31T23:59:00+01:00`. A bare date (`2026-12-31`) means midnight at the start of that day and a time without an offset is read on the store clock, both in the store time zone. Empty means unset. The storefront leaves a hidden element out of the page entirely. Replaces the stored conditions; &#123;&#125; or &#123; audience: "all" &#125; without dates clears them. |
| `enabled` | boolean |  | Updated enabled flag |
| `locale` | string |  | Language the settings text is in. The theme's base language (overview base_locale) or omitted writes settings; any other language writes settings_i18n[locale]. Images, videos, URLs and links are shared by every language and written to settings, unless that language already has its own value in settings_i18n[locale], which is then replaced; own_in_locale gives a language its own value |
| `own_in_locale` | list of string |  | Setting ids given in settings (images, videos, URLs and plain links only) that become the own values of the locale language: that language shows the value given, the base and every other language keep theirs, and later writes in that language keep landing there. Needs a locale other than the base language. at most 64 items. 1 to 128 characters |
| `share_in_locale` | list of string |  | Setting ids (images, videos, URLs and plain links only) whose own value in the locale language is dropped, so that language shows the shared value again. Needs a locale other than the base language; leave these ids out of settings. at most 64 items. 1 to 128 characters |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "settings": {
    "heading": "Summer sale"
  }
}
```

### `theme_section_update_many` [#theme_section_update_many]

Change one section's settings and many of its elements in one write.

Merge settings into a section and any of its blocks in one draft write (one save, one undo step); text goes to settings_i18n[locale] with locale. Use it to rewrite the text of a section and its blocks together.

- Action key: `theme_section.update_many`
- Permission: `theme.write`
- Approval: Waits for approval when the store requires it for this action.
- Effect: Changes a draft; nothing goes live until it is published.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |
| `section_id` | string | yes | Section id to update |
| `settings` | map of any value |  | The new setting values, keyed by the setting ids the section or block type declares, e.g. &#123;"heading":"Summer sale","subheading":"Up to 40% off everything"&#125;. Text values are written in locale. An update changes exactly the ids given here; without settings it saves nothing. |
| `blocks` | list of object |  | Settings for blocks of this section, one entry per block, e.g. [&#123;"block_id":"stat-1","settings":&#123;"value":"40%","label":"Faster checkout"&#125;&#125;]. at most 64 items |
| `blocks[].block_id` | string | yes | Block id inside the section, searched recursively. at least 1 characters |
| `blocks[].settings` | map of any value | yes | The block's new setting values keyed by setting id, e.g. &#123;"value":"40%","label":"Faster checkout"&#125; |
| `locale` | string |  | Language the settings text is in. The theme's base language (overview base_locale) or omitted writes settings; any other language writes settings_i18n[locale]. Images, videos, URLs and links are shared by every language and written to settings, unless that language already has its own value in settings_i18n[locale], which is then replaced; own_in_locale gives a language its own value |

Example input:

```json
{
  "template_id": "home",
  "section_id": "hero-1",
  "settings": {
    "heading": "Summer sale"
  }
}
```

### `theme_template_get` [#theme_template_get]

One template's section tree, with the section types it can add and the ones it requires.

Get one template's section tree (ids, types, enabled, settings, style, conditions, blocks), addable type names, required_section_types and base_locale: settings hold base_locale text; write any other language with locale. A required type is the page's main section, such as product-information or blog-main: it renders the page's own data (the product, the posts, the questions), can be moved and styled, and is never removed or duplicated.

- Action key: `theme_template.get`
- Permission: `theme.read`
- Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `theme_id` | string |  | Theme ID. Omit to use the store active theme, or the only theme if none is marked active. |
| `template_id` | string | yes | Template ID: a fixed template ("home", "products", "collection" (a category or collection page), "product", "cart", "checkout", "order-confirmed" (the thank-you page), "order-status", "login", "register", "account", "page"; content pages "contact", "blog" (blog index and categories), "article" (a blog post), "guides" (guide index and categories), "guide" (a guide article), "faq", "legal", "not-found"), a platform pop-up's own template (theme_customizer_get overlays), an alternate such as "product--&lt;key>" (overview alternate_templates), "page:&lt;page id>" (a site page's own layout), or "layout.header" or "layout.footer" (the store header or footer) |

Example input:

```json
{
  "template_id": "home"
}
```
