Documentation

Dashboards

Compose dashboards from a 10-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 10-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
executiveLeadership / FinOps leadsStat cards, cost trend, top costly resources, recommendations
engineeringPlatform & SRE teamsSchedule execution, upcoming actions, recommendations, cloud spend
finopsFinance partnersShowback by team, cost trend, budget health, top costly resources
all_widgetsEveryoneAll 10 widgets, useful as a starting point for clones

Widget library

Every dashboard is a layout over the same 10 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_cardsCompact key-metric tiles (cost, savings, anomalies, resources)dashboard:view
cost_trendDaily/weekly/monthly cost line chartreports:view
cloud_spendPer-provider spend breakdownreports:view
top_costlyTop N costly resourcesreports:view
recommendationsOpen recommendations + savingsrecommendation:view
quick_insightsCurated callouts (idle/orphan/anomalies)reports:view
budget_healthBudget status across teamsreports:view
showbackCost attribution by team or tagreports:view
schedule_executionRecent scheduler executionsschedule:view
upcoming_actionsNext 24h scheduled start/stop actionsschedule:view

Bounds

BoundLimitOn exceed
Dashboards per org50409 — code: DASHBOARD_LIMIT_EXCEEDED
Widgets per dashboard50400 on save
Widget config size4 KiB400 on save
Layout payload size64 KiB400 on save
Name uniquenessPer-org (active rows)409 — code: DUP_NAME

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

Response · json
{
"data": [
  { "id": "executive", "name": "Executive", "kind": "preset" },
  { "id": "engineering", "name": "Engineering", "kind": "preset" },
  { "id": "finops", "name": "FinOps", "kind": "preset" },
  { "id": "all_widgets", "name": "All Widgets", "kind": "preset" },
  {
    "id": "01HF8K9C5G4M2N3P4Q5R6S7T8U",
    "name": "Platform Team",
    "kind": "user",
    "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, modify, POST.

Request · json
{
"name": "Platform Team",
"layout": { "rows": [[{ "type": "stat_cards", "size": "wide" }]] },
"widgets": [
  { "type": "stat_cards", "config": {} }
]
}

Update dashboard

PATCH/dashboards/{id}

Partial update — name, layout, or widgets. All-nil bodies return 400. PATCH on a preset id returns 405 (ErrPresetImmutable).

Set default dashboard

PUT/dashboards/default

Set the org's default dashboard. Pointer lives in org_settings under key default_dashboard.

Request · json
{ "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 in the same transaction.

See Roles & Permissions for how dashboard policies compose with the rest of the policy table.