Skip to main content

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).

GET/api/dashboards/collections🔒 auth

List collections in the current org/project.

POST/api/dashboards/collections🔒 auth

Create a collection. Body: {name, description, parent_id?}.

PATCH/api/dashboards/collections/{collection_id}🔒 auth

Rename or move a collection.

DELETE/api/dashboards/collections/{collection_id}🔒 auth

Delete a collection. Requires the collection to be empty.

Dashboard CRUD

GET/api/dashboards🔒 auth

List dashboards visible to the caller. Supports collection_id, q, limit, offset.

GET/api/dashboards/{dashboard_id}🔒 auth

Full dashboard config including layout, all card configs, parameters, and share grants.

POST/api/dashboards🔒 auth

Create an empty dashboard. Body: {name, collection_id?, parameters?}.

PATCH/api/dashboards/{dashboard_id}🔒 auth

Update top-level dashboard fields (name, description, parameters, default audience). Use the dedicated layout/card endpoints for content edits.

DELETE/api/dashboards/{dashboard_id}🔒 auth

Delete a dashboard. Requires dashboard.edit (or legacy editor role) on the dashboard.

POST/api/dashboards/{dashboard_id}/duplicate🔒 auth

Deep-copy a dashboard including all cards and pages. Returns the new dashboard ID.

Templates

GET/api/dashboards/templates🔒 auth

List 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.

POST/api/dashboards/from-template🔒 auth

Instantiate 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.

POST/api/dashboards/{dashboard_id}/cards🔒 auth

Add a card to a dashboard. Body: {card_type, config, layout: {x, y, w, h}}.

PATCH/api/dashboards/{dashboard_id}/cards/{card_id}🔒 auth

Update a card's config or position. Send only the fields you're changing.

DELETE/api/dashboards/{dashboard_id}/cards/{card_id}🔒 auth

Remove a card.

POST/api/dashboards/{dashboard_id}/cards/{card_id}/duplicate🔒 auth

Duplicate a card on the same dashboard.

Layout

PATCH/api/dashboards/{dashboard_id}/layout🔒 auth

Bulk-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.

POST/api/dashboards/{dashboard_id}/pages🔒 auth

Add a new page to a dashboard. Body: {name, position}.

PATCH/api/dashboards/{dashboard_id}/pages/{page_number}🔒 auth

Rename a page or change its position.

DELETE/api/dashboards/{dashboard_id}/pages/{page_number}🔒 auth

Delete a page. Cards on the page are deleted with it.

Sharing

GET/api/dashboards/{dashboard_id}/shares🔒 auth

List share grants on the dashboard. Each grant has subject_type (user or group), subject_id, and access_level (viewer, commenter, editor).

POST/api/dashboards/{dashboard_id}/shares🔒 auth

Add or upsert a share grant. Sending the same (subject_type, subject_id) pair twice updates the existing grant rather than creating a duplicate.

DELETE/api/dashboards/{dashboard_id}/shares/{share_id}🔒 auth

Revoke a share grant.

Rendering

GET/api/dashboards/{dashboard_id}/render?param.x=y&page=1🔒 auth

Render 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

StatusErrorCause
403permission_deniedCaller lacks dashboard.edit on the dashboard.
404dashboard_not_foundDashboard ID doesn't exist in the current org.
409card_position_conflictLayout update overlaps an unmoved card. The PATCH is atomic — fix the layout client-side and retry.
422invalid_card_configThe card's config doesn't validate against its card_type schema.