Dashboards API
The /api/dashboards/* surface covers dashboard CRUD, tile-level operations (the platform's tile primitive is called a card), layout updates, paging, and templates.
For the conceptual model — block types, design mode, parameters, sharing — see Dashboards. For each tile's data-fetch path, see Datasets.
Collections
Dashboards live under collections (the platform's name for dashboard folders).
/api/dashboards/collections🔒 authList collections in the current org/project.
/api/dashboards/collections🔒 authCreate a collection. Body: {name, description, parent_id?}.
/api/dashboards/collections/{collection_id}🔒 authRename or move a collection.
/api/dashboards/collections/{collection_id}🔒 authDelete a collection. Requires the collection to be empty.
Dashboard CRUD
/api/dashboards🔒 authList dashboards visible to the caller. Supports collection_id, q, limit, offset.
/api/dashboards/{dashboard_id}🔒 authFull dashboard config including layout, all card configs, parameters, and share grants.
/api/dashboards🔒 authCreate an empty dashboard. Body: {name, collection_id?, parameters?}.
/api/dashboards/{dashboard_id}🔒 authUpdate top-level dashboard fields (name, description, parameters, default audience). Use the dedicated layout/card endpoints for content edits.
/api/dashboards/{dashboard_id}🔒 authDelete a dashboard. Requires dashboard.edit (or legacy editor role) on the dashboard.
/api/dashboards/{dashboard_id}/duplicate🔒 authDeep-copy a dashboard including all cards and pages. Returns the new dashboard ID.
Templates
/api/dashboards/templates🔒 authList built-in dashboard templates (KPI summary, profile-detail, etc.). Each template has a fixed shape that's instantiated against a dataset of the user's choice.
/api/dashboards/from-template🔒 authInstantiate a template against a dataset. Body: {template_id, dataset_id, name}. The platform creates a new dashboard pre-populated with the template's tiles wired to the chosen dataset's columns.
Cards (tiles)
A card is a tile on the dashboard grid. Each card has a card_type matching one of the block types documented under Dashboards → Block palette.
/api/dashboards/{dashboard_id}/cards🔒 authAdd a card to a dashboard. Body: {card_type, config, layout: {x, y, w, h}}.
/api/dashboards/{dashboard_id}/cards/{card_id}🔒 authUpdate a card's config or position. Send only the fields you're changing.
/api/dashboards/{dashboard_id}/cards/{card_id}🔒 authRemove a card.
/api/dashboards/{dashboard_id}/cards/{card_id}/duplicate🔒 authDuplicate a card on the same dashboard.
Layout
/api/dashboards/{dashboard_id}/layout🔒 authBulk-update card positions after a drag-and-drop reorder. Body: array of {card_id, x, y, w, h} updates. Atomic — either all updates succeed or none do.
Paging
A dashboard can have multiple pages (tabs at the top of the canvas). Each page has its own card layout.
/api/dashboards/{dashboard_id}/pages🔒 authAdd a new page to a dashboard. Body: {name, position}.
/api/dashboards/{dashboard_id}/pages/{page_number}🔒 authRename a page or change its position.
/api/dashboards/{dashboard_id}/pages/{page_number}🔒 authDelete a page. Cards on the page are deleted with it.
Sharing
/api/dashboards/{dashboard_id}/shares🔒 authList share grants on the dashboard. Each grant has subject_type (user or group), subject_id, and access_level (viewer, commenter, editor).
/api/dashboards/{dashboard_id}/shares🔒 authAdd or upsert a share grant. Sending the same (subject_type, subject_id) pair twice updates the existing grant rather than creating a duplicate.
/api/dashboards/{dashboard_id}/shares/{share_id}🔒 authRevoke a share grant.
Rendering
/api/dashboards/{dashboard_id}/render?param.x=y&page=1🔒 authRender the dashboard's tiles, returning each tile's data with parameters substituted. Public dashboards expose a similar endpoint at /api/public/dashboards/{slug}/render with no auth.
The render response shape:
{
"dashboard": { "name": "...", "parameters": {...} },
"page": 1,
"cards": [
{
"card_id": 7,
"card_type": "chart",
"data": {...},
"error": null
},
...
]
}
Each card is rendered independently; a single card error doesn't fail the whole response.
Auth and access
Reads (GET) are gated by the dashboard's audience and per-user share grants. Writes (POST, PATCH, DELETE) require dashboard.edit (new layer) or editor role (legacy layer). Public dashboards bypass auth on the render endpoint only — every other endpoint requires a valid token.
Errors
| Status | Error | Cause |
|---|---|---|
| 403 | permission_denied | Caller lacks dashboard.edit on the dashboard. |
| 404 | dashboard_not_found | Dashboard ID doesn't exist in the current org. |
| 409 | card_position_conflict | Layout update overlaps an unmoved card. The PATCH is atomic — fix the layout client-side and retry. |
| 422 | invalid_card_config | The card's config doesn't validate against its card_type schema. |