Menu
Use your own AI
Tools: forms, SEO and redirects
Reference for the tools that manage forms, page and site SEO, and redirects.
These tools manage forms, SEO and redirects. See the Tool reference for shared errors.
list_forms
Lists the site's forms with their field counts and where submissions go.
When to use it: Before adding or changing a form.
Needs an open turn: No.
No inputs besides siteId.
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ"
}
Example result
{
"success": true,
"forms": [
{
"id": "contact",
"name": "Contact",
"fieldCount": 3,
"destinations": [
"store",
"email"
]
}
]
}
modify_form
Creates, updates or deletes a form. Place a form on a page with <Form formId="contact" />; never write <form> or <input> markup.
When to use it: Whenever the user wants visitors to send something: contact, enquiries, sign-ups, uploads.
Needs an open turn: Yes. Call start_turn first.
| Input | Type | Required | Meaning |
|---|---|---|---|
action |
string: create, update or delete |
Yes | What to do. |
formId |
string | Yes | The form's ID: lowercase letters, digits, - and _, starting with a letter, up to 64 characters. |
name |
string | For create | The form's name. |
fields |
array | For create | The fields. On update, sending fields replaces them all. Each field has id, type, label, and optional required, placeholder, options, showWhen, fileKind, maxFiles and others. |
settings |
object | No | submitLabel, successMessage, errorMessage, redirectUrl, honeypot (default true). Merged with existing settings on update. |
destinations |
array | No | Where submissions go: {"type": "store"}, {"type": "email", "to": …} or {"type": "webhook", "url": …}. On update, leaving it out keeps the current ones; an empty list removes them. |
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ",
"action": "create",
"formId": "contact",
"name": "Contact",
"fields": [
{
"id": "name",
"type": "text",
"label": "Name",
"required": true
},
{
"id": "email",
"type": "email",
"label": "Email",
"required": true
},
{
"id": "message",
"type": "textarea",
"label": "Message"
}
],
"destinations": [
{
"type": "store"
},
{
"type": "email",
"to": "owner@example.com"
}
]
}
Example result
{
"success": true,
"formId": "contact",
"verificationNeeded": [
"owner@example.com"
]
}
Field types: text, email, textarea, select, checkbox, radio, number, url, tel, date, time, file.
selectandradioneedoptions.filefields needfileKind(imageordocument),maxFilesfrom 1 to 10, and astoredestination.- A field can have one
showWhencondition,{"field": …, "equals": …}or{"field": …, "in": [ … ]}, based on aselect,radioorcheckboxfield that isn't itself conditional. - Webhooks are sent unsigned. Sites have no secrets, so never put keys or tokens in destinations.
See Add a form and Form field types.
Errors
| You see | What it means | What to do |
|---|---|---|
| "Invalid formId …" | The ID has characters that aren't allowed. | Use lowercase letters, digits, - and _, starting with a letter. |
| "Form … already exists. Use action: "update" to modify it." | That ID is taken. | Use update, or pick another ID. |
| "Form … not found." | There's no form with that ID. | Check the ID with list_forms. |
| "Cannot delete form … — still referenced by N file(s)." | A page or component still shows the form. | Remove the <Form formId="…" /> uses first, then delete. |
verificationNeeded in the result |
Notification emails go only to verified addresses. | Tell the user to verify each address in the Forms panel. |
not_lock_holder |
Your agent has no open turn on this site, or its turn lapsed. | Call start_turn, then retry. |
lock_lost |
Someone took the site back (for example with Take back control) or the turn expired and was reopened. | Call start_turn to begin a new turn, then retry. |
site_publishing |
The site is publishing. Editing is paused until it finishes. | Wait for the publish to finish, then retry. |
seo_list
Shows the site's SEO defaults and, for every page, its SEO settings and a health status: good, warning or missing.
When to use it: To find pages that need titles and descriptions.
Needs an open turn: No.
No inputs besides siteId.
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ"
}
Example result
{
"siteDefaults": {
"siteName": "Bakery",
"locale": "en"
},
"pages": [
{
"slug": "index",
"status": "missing",
"seo": {
"ogType": "website",
"noIndex": false,
"keywords": []
}
}
]
}
seo_get_page
Reads one page's SEO settings and its health status.
When to use it: Before changing a page's SEO.
Needs an open turn: No.
| Input | Type | Required | Meaning |
|---|---|---|---|
slug |
string | Yes | The page's address without the leading /: about for /about, index for the home page. |
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ",
"slug": "index"
}
Example result
{
"slug": "index",
"seo": {},
"status": "missing"
}
seo_set_page
Sets a page's SEO title, description and other fields. Values are merged with what's there.
When to use it: To give a page its own title and description, social image or indexing setting.
Needs an open turn: Yes. Call start_turn first.
| Input | Type | Required | Meaning |
|---|---|---|---|
slug |
string | Yes | The page's address without the leading /; index for home. |
title |
string | No | The page's SEO title. |
description |
string | No | The page's SEO description. |
fields |
object | No | Other page SEO fields, such as ogImage or robots. |
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ",
"slug": "about",
"title": "About us",
"description": "A family bakery in Portland since 1998."
}
Example result
{
"slug": "about",
"seo": {
"title": "About us",
"description": "A family bakery in Portland since 1998."
},
"status": "good"
}
See Page SEO.
Errors
| You see | What it means | What to do |
|---|---|---|
not_lock_holder |
Your agent has no open turn on this site, or its turn lapsed. | Call start_turn, then retry. |
lock_lost |
Someone took the site back (for example with Take back control) or the turn expired and was reopened. | Call start_turn to begin a new turn, then retry. |
site_publishing |
The site is publishing. Editing is paused until it finishes. | Wait for the publish to finish, then retry. |
seo_set_defaults
Sets site-wide SEO: site name, default description, language, social image, icons, search engine verification codes, crawler settings and Google Analytics. Only the fields you send change.
When to use it: For anything site-wide. Never hand-write these tags into a snippet file.
Needs an open turn: Yes. Call start_turn first.
| Input | Type | Required | Meaning |
|---|---|---|---|
siteName |
string | No | Used in page titles and social previews. |
description |
string | No | Description for pages that don't have their own. |
locale |
string | No | Site language, such as en or en-GB. |
ogImage |
string | No | Default social preview image: a library image URL. |
favicon |
string | No | Favicon: a library image URL. |
faviconDark |
string | No | Favicon for dark mode: a library image URL. |
appleTouchIcon |
string | No | Apple touch icon: a library image URL. |
verificationCodes |
object | No | {"google": …, "bing": …}: the content values from Google Search Console and Bing Webmaster Tools. |
blockAiCrawlers |
boolean | No | Block known AI training crawlers. Search engines aren't affected. |
hideFromSearch |
boolean | No | Hide the whole site from search engines. |
googleAnalyticsId |
string | No | Your GA4 measurement ID, such as G-XXXXXXXXXX. Added to the published site only. |
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ",
"siteName": "Bakery",
"locale": "en",
"verificationCodes": {
"google": "abc123"
}
}
Example result
{
"success": true
}
Crawler and search settings take effect on the next publish. See Site SEO defaults and Search engines and AI crawlers.
Errors
| You see | What it means | What to do |
|---|---|---|
not_lock_holder |
Your agent has no open turn on this site, or its turn lapsed. | Call start_turn, then retry. |
lock_lost |
Someone took the site back (for example with Take back control) or the turn expired and was reopened. | Call start_turn to begin a new turn, then retry. |
site_publishing |
The site is publishing. Editing is paused until it finishes. | Wait for the publish to finish, then retry. |
redirects_list
Lists the site's redirect rules in the order they're checked, plus redirects created automatically when CMS item slugs changed.
When to use it: Before adding or reordering redirects.
Needs an open turn: No.
No inputs besides siteId.
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ"
}
Example result
{
"rules": [
{
"id": "r_…",
"from": "/old-menu",
"to": "/menu",
"status": 301,
"enabled": true,
"note": "Old menu page"
}
]
}
contentRedirects lists the automatic CMS redirects. Only the user can remove those, in the Redirects panel.
redirects_modify
Adds, changes, deletes or reorders redirect rules. Rules take effect on the published site at the next publish.
When to use it: When a page moves or the user asks for a redirect.
Needs an open turn: Yes. Call start_turn first.
| Input | Type | Required | Meaning |
|---|---|---|---|
action |
string: create, update, delete or reorder |
Yes | What to do. |
rule |
object | For create and update | from, to, optional status (301 permanent or 302 temporary), enabled and note. For update, only the fields to change. |
id |
string | For update and delete | The rule's ID from redirects_list. |
orderedIds |
array of strings | For reorder | Every rule ID, once each, in the new order. |
Example call
{
"siteId": "0APMiuxGY2yB4xJm5BilJ",
"action": "create",
"rule": {
"from": "/blog/:slug",
"to": "/journal/:slug",
"status": 301
}
}
Example result
{
"success": true
}
from can include one :name part that matches any single segment and can be reused in to. An exact rule wins over a pattern, and a pattern never redirects a page that exists. See Redirects.
Errors
| You see | What it means | What to do |
|---|---|---|
| Invalid rule | The from or to isn't valid, or the rule duplicates another. |
Fix the rule using the message. |
| Missing or extra IDs on reorder | orderedIds must list every rule exactly once. |
Call redirects_list and send the full list. |
not_lock_holder |
Your agent has no open turn on this site, or its turn lapsed. | Call start_turn, then retry. |
lock_lost |
Someone took the site back (for example with Take back control) or the turn expired and was reopened. | Call start_turn to begin a new turn, then retry. |
site_publishing |
The site is publishing. Editing is paused until it finishes. | Wait for the publish to finish, then retry. |