Navigation#
Navigations have no draft state, so a saved tree is live at once.
Read a menu#
navigations_get returns a navigation’s tree for one site, in the shape Statamic stores and navigations_update accepts. Each entry branch also carries resolved, with the linked entry’s current title, url, and status. That block is read-only, and writes ignore it.
{
"handle": "main",
"title": "Main",
"site": "en",
"max_depth": null,
"expects_root": false,
"collections": ["pages"],
"fields": [
{ "handle": "icon", "type": "text", "required": false },
{ "handle": "new_tab", "type": "toggle", "required": false }
],
"tree": [
{
"id": "80512498-c701-4c20-bc1c-e427beaea1ef",
"entry": "f6541180-3baf-4454-a0b4-cecd43593ea8",
"resolved": { "title": "Home", "url": "/home", "status": "published" }
},
{
"id": "e3c3f8cb-fe0d-4dd6-9610-98f602fa1c59",
"title": "Contact",
"url": "/contact"
}
],
"cp_edit_url": "https://example.com/cp/navigation/main"
} The response also lists what a write has to respect: max_depth, expects_root, the collections entry branches may link, and the blueprint fields that branch data takes. blueprints_get with type: navigation describes those fields in full.
A resolved status of missing means the entry is deleted or not exposed to MCP, so it may be a live page. An agent should send that branch back unchanged unless someone asks to remove it.
Change a menu#
navigations_update replaces a site’s tree with the complete tree you send, the way saving the tree in the Control Panel does. Send every branch, in order.
{
"handle": "main",
"tree": [
{ "entry": "f6541180-3baf-4454-a0b4-cecd43593ea8" },
{ "entry": "5887cf2d-7997-4801-a040-51957ee98206", "data": { "icon": "bike" } },
{ "title": "Contact", "url": "/contact" }
]
} - Branches keep the ids they come with. A branch without one gets a new id, which the result lists under
added. - An entry branch has to link an existing entry of one of the navigation’s collections in the same site.
- A branch without an entry needs a url or a title, and a title alone makes a text item.
- The tool enforces
max_depthand the root page rule, and it runs branchdatathrough the navigation’s blueprint. - A tree that equals the stored one saves nothing.
- An empty list clears the navigation.
To build a menu for new pages, create them with entries_create, passing parent to nest them in a structured collection. Then send navigations_update a tree whose entry branches link their ids.
Permissions for menus#
Reading takes view {nav} nav, and changing the tree takes edit {nav} nav. For a menu agent, add View Main navigation and the Edit navigation permission under it to the role.
The tools check these per-navigation permissions and ignore Configure Navigation. The Control Panel treats that one as access to every navigation and hides the per-navigation checkboxes while it’s ticked, so untick it to grant them.
On multi-site installs the role also needs Access {site} site for each site whose menu the agent reads or changes, the default site included.
Forms#
Form submissions are read-only, as they are in the Control Panel. A submission is what a visitor sent through the front-end form, with its honeypot, validation, and emails, so nothing creates or edits one through MCP.
Read submissions#
submissions_list returns a form’s submissions newest first, each with its id, date, and full data keyed by field handle. Submissions are flat and small, so the list carries the data itself, and an agent can summarize a week of contact requests in one call.
{
"form": "contact",
"total": 2,
"page": 1,
"per_page": 25,
"next_page": null,
"submissions": [
{
"id": "1790330400",
"date": "2026-09-25T10:00:00+00:00",
"data": {
"name": "Ana",
"email": "[email protected]",
"message": "Can we book a tour for six?"
}
}
],
"cp_url": "https://example.com/cp/forms/contact"
} A field the visitor didn’t send is absent from data. submissions_get returns one submission by form handle and id, with cp_url, and it looks the id up within that form only. blueprints_get with type: form names the fields.
Filter them#
| Parameter | What it does |
|---|---|
since | On or after this date, inclusive. |
before | Before this date, exclusive. before: 2026-09-27 covers everything up to the end of the 26th. |
search | The Control Panel’s search, a substring match over text, textarea, and integer fields. It also matches the date as stored, YYYY-MM-DD HH:MM:SS in UTC. Use since and before for dates. On the default Stache driver it matches plain text. SQL-backed repositories keep % and _ as wildcards. |
limit, page | Paginated like the other list tools. |
A time without an offset is read in server.timezone, and a date alone means midnight.
Delete one#
submissions_delete is only registered when deletes is on. It removes spam or honors an erasure request. Files the submission uploaded stay in their asset container, as when deleting in the Control Panel.
Permissions for forms#
Reading takes view {form} form submissions, and deleting takes delete {form} form submissions. configure forms grants both on every form, which is how Statamic’s own form policies read it.
statamic_overview lists the forms you may read, with stores_submissions, which is false on a form that only sends email, and their submission count. Submissions aren’t per site.