---
title: "Compose a new page from an intent"
method: POST
path: "/dashboards/{dashboard_id}/plan-page"
tags: ["Dashboard v3"]
---

# Compose a new page from an intent

`POST /dashboards/{dashboard_id}/plan-page`

## Request

- Base URL: `https://app.mammoth.io/api/v2`
- URL: `https://app.mammoth.io/api/v2/dashboards/{dashboard_id}/plan-page`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-KEY` and API key in header `X-API-SECRET` and API key in header `X-WORKSPACE-ID`

The Add → Page omnibox: classify the intent to a dashboard ARCHETYPE (a PRESET page carrying type + focus, re-derived at bake) or, when it names a specific chart, compose one authored figure via the deterministic figure-intent resolve (a CUSTOM page). Returns an appendable PageV3 directly — this endpoint persists NOTHING; the FE lands the page via the canvas PUT. Synchronous (like figure-intent): one classify call + one engine resolve, no bake to run, and the editor awaits the result — a job + poll would only add latency. The blocking LLM / profile / render work runs off the event loop.

## Path parameters

- `dashboard_id` integer, required

## Request body

- PlanPageSpec: Add → Page request
  - `params` PlanPageParams
    - `intent` string, nullable: Free-text description of the wanted page
    - `archetype` string, nullable: An explicit content page type id
    - `kind` string, nullable: An explicit chart kind
    - `fields` object, nullable: Explicit binding-role overrides (picker path)
    - `page_id` string, nullable: The EXISTING page being RECOMPOSED (a format or structure change), as opposed to composing a brand-new one. Two effects: the returned page carries this id rather than the canvas's next free one, and the page's own focus is excluded from the diversification set. A defaulted focus is otherwise read as duplicating the very page it replaces and rotated onto a different measure — silently changing what the board is about. Omit when ADDING a page.

## Response `200`

A composed, appendable dashboard page

- PlanPageResponse
  - `page` object, required
  - `composed` boolean, required
  - `message` string, nullable
  - `preview` object[]

## Other responses

- `400`: Bad request syntax or unsupported method
- `403`: Request forbidden -- authorization will not help

---

[API](https://skmtc.dev/mammoth/apis/mammoth-analytics.md) · [All operations](https://skmtc.dev/mammoth/apis/mammoth-analytics/llms.txt) · [OpenAPI document](https://skmtc.dev/mammoth/apis/mammoth-analytics/revisions/fe078afe239b?raw)
