Dashboards
Compose dashboards from a 13-widget library, pin one as the org default, and clone presets to build your own, all gated by per-policy RBAC.
Compose your own dashboards from a 13-widget library and pin one as the org default. Dashboards are owned by the organization, anyone with the right role sees the same set.
System Presets
Four presets ship out of the box. Presets are read-only. You can clone any preset to create your own dashboard, but the originals never change. Presets are served from memory and are never persisted to the database.
| Preset | Audience | Default widgets |
|---|---|---|
executive | Leadership | Stat cards, cost trend, cost reports, budget health, top costly resources, recommendations |
engineering | Engineering teams | Stat cards, cost trend, cost reports, recommendations, schedule activity, schedule success rate |
finops | Finance partners | Stat cards, cost trend, cost reports, budget health, top costly resources, recommendations, schedule activity, schedule success rate |
all_widgets | Everyone | Stat cards, cost trend, cost reports, top costly resources, budget health, recommendations, schedule activity, schedule success rate. The fallback when no org default is set. |
Widget library
Every dashboard is a layout over the same 13 widgets. Each widget declares its required policy and is rendered through an error boundary. A widget you can’t see, or a widget that throws, becomes a placeholder instead of unmounting the page.
| Widget type | What it shows | Required policy |
|---|---|---|
stat_cards | Resources, spend, savings, and savings rate at a glance | report:view |
cost_trend | Daily and accumulated cost over time | report:view |
cloud_spend | Spend split by cloud provider | report:view |
cost_reports | Providers, teams, and tags in one tabbed card | report:view |
top_costly | Highest-cost resources this period | report:view |
recommendations | Top open recommendations by potential monthly savings | recommendation:view |
quick_insights | Top open recommendations as scannable cards | recommendation:view |
budget_health | Budget utilisation by team or group | budget:view |
showback | Cost attribution by team or tag | report:view |
schedule_execution | Recent schedule runs and failures | state-history:view |
upcoming_actions | Scheduled starts and stops in the next window | schedule:view |
schedule_activity | Past schedule runs and upcoming actions in one tabbed card | state-history:view |
schedule_success_rate | Success rate for scheduled start/stop runs | report:view |
Bounds
| Bound | Limit | On exceed |
|---|---|---|
| Dashboards per org | 50 | 409 on create |
| Widgets per dashboard | 50 | 400 on save |
| Widget config size | 4 KiB | 400 on save |
| Layout payload size | 64 KiB | 400 on save |
| Name uniqueness | Per-org (active rows) | 409 on create or rename |
RBAC
Four policies gate dashboard operations:
dashboard:view, read dashboards and presetsdashboard:create. Create new dashboards (counts against the org’s 50-dashboard quota)dashboard:update: rename, edit layout, change widgets, set defaultdashboard:delete: delete a user-created dashboard (presets are immutable)
API
List dashboards
/dashboards List dashboards visible to the caller, plus the org's default-dashboard pointer.
Query: ?limit=20&offset=0&sort_by=name&sort_order=asc. Unlike most list endpoints, this one paginates with limit and offset rather than page. limit defaults to 50 (max 100). sort_by is created_at (default), updated_at, or name. sort_order defaults to desc. The four presets always come first, with isSystem: true.
Layouts are trimmed to one widget and only two of the four presets are shown below.
{ "data": { "data": [ { "id": "executive", "orgId": "org_001", "name": "Executive", "description": "Headline KPIs, trends, savings, and budget health, the leadership view.", "layout": { "version": 1, "widgets": [ { "id": "p-exec-1", "type": "stat_cards", "size": "full", "order": 0 } ] }, "isSystem": true, "category": "leadership", "createdAt": "0001-01-01T00:00:00Z", "updatedAt": "0001-01-01T00:00:00Z" }, { "id": "3f2b8c1e-6d4a-4b7e-9a51-2c8e7f0d1a93", "orgId": "org_001", "name": "Platform Team", "layout": { "version": 1, "widgets": [ { "id": "w1", "type": "stat_cards", "size": "full", "order": 0 } ] }, "isSystem": false, "createdBy": "jane@example.com", "createdAt": "2026-04-26T10:30:00Z", "updatedAt": "2026-04-27T08:00:00Z" } ], "defaultDashboard": "executive" }}Get dashboard
/dashboards/{id} Get a dashboard by id. Preset keys are served from memory; UUIDs hit the dashboards table.
Create dashboard
/dashboards Create a new user-owned dashboard. Cloning a preset is a client-side operation: GET the preset, give its widgets new ids, POST.
{ "name": "Platform Team", "description": "Spend and schedules for the platform team", "layout": { "version": 1, "widgets": [ { "id": "w1", "type": "stat_cards", "size": "full", "order": 0 }, { "id": "w2", "type": "cost_trend", "size": "half", "order": 1, "config": {} } ] }}layout.version must be 1. Each widget needs a unique id, a known type, and a size of full, half, or third. order values must run 0, 1, 2, … with no gaps. titleOverride (max 128 characters) and config are optional.
Update dashboard
/dashboards/{id} Partial update, name, description, or layout. A sent layout replaces the old one whole. An empty body returns 400. PATCH on a preset id returns 405.
Set default dashboard
/dashboards/default Set the org's default dashboard.
{ "id": "executive" }Send { "id": "" } to clear the pointer, frontend falls back to all_widgets.
Delete dashboard
/dashboards/{id} Delete a user-owned dashboard. Preset keys return 405. If the deleted dashboard is the org default, the pointer is cleared right after the delete.
See Roles & Permissions for how dashboard policies compose with the rest of the policy table.