Skip to main content Skip to content

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.

5 min read Last updated: 

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.

PresetAudienceDefault widgets
executiveLeadershipStat cards, cost trend, cost reports, budget health, top costly resources, recommendations
engineeringEngineering teamsStat cards, cost trend, cost reports, recommendations, schedule activity, schedule success rate
finopsFinance partnersStat cards, cost trend, cost reports, budget health, top costly resources, recommendations, schedule activity, schedule success rate
all_widgetsEveryoneStat 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 typeWhat it showsRequired policy
stat_cardsResources, spend, savings, and savings rate at a glancereport:view
cost_trendDaily and accumulated cost over timereport:view
cloud_spendSpend split by cloud providerreport:view
cost_reportsProviders, teams, and tags in one tabbed cardreport:view
top_costlyHighest-cost resources this periodreport:view
recommendationsTop open recommendations by potential monthly savingsrecommendation:view
quick_insightsTop open recommendations as scannable cardsrecommendation:view
budget_healthBudget utilisation by team or groupbudget:view
showbackCost attribution by team or tagreport:view
schedule_executionRecent schedule runs and failuresstate-history:view
upcoming_actionsScheduled starts and stops in the next windowschedule:view
schedule_activityPast schedule runs and upcoming actions in one tabbed cardstate-history:view
schedule_success_rateSuccess rate for scheduled start/stop runsreport:view

Bounds

BoundLimitOn exceed
Dashboards per org50409 on create
Widgets per dashboard50400 on save
Widget config size4 KiB400 on save
Layout payload size64 KiB400 on save
Name uniquenessPer-org (active rows)409 on create or rename

RBAC

Four policies gate dashboard operations:

  • dashboard:view, read dashboards and presets
  • dashboard:create. Create new dashboards (counts against the org’s 50-dashboard quota)
  • dashboard:update: rename, edit layout, change widgets, set default
  • dashboard:delete: delete a user-created dashboard (presets are immutable)

API

List dashboards

GET /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.

Response
{
"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

GET /dashboards/{id}

Get a dashboard by id. Preset keys are served from memory; UUIDs hit the dashboards table.

Create dashboard

POST /dashboards

Create a new user-owned dashboard. Cloning a preset is a client-side operation: GET the preset, give its widgets new ids, POST.

Request
{
"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

PATCH /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

PUT /dashboards/default

Set the org's default dashboard.

Request
{ "id": "executive" }

Send { "id": "" } to clear the pointer, frontend falls back to all_widgets.

Delete dashboard

DELETE /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.

Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·