Dashboards as code
Every Plexus dashboard is one JSON file. Pull it into your repo, change it by hand or ask your coding agent to, and push it back. The same file is on the JSON tab of each dashboard's settings.
Pull, edit, push
pip install -U plexus-python
plexus init # once: saves a key that can manage dashboards
plexus dashboards list
plexus dashboards pull rover-01-starter
# edit plexus/dashboards/rover-01-starter.json
plexus dashboards diff # what would change
plexus dashboards pushFiles live in plexus/dashboards/<uid>.json (change it with --dir or
PLEXUS_DASHBOARDS_DIR). Commit them.
- Pushing an unchanged file does nothing. Running push twice is safe.
- Edits made in the app aren't overwritten. Push sends the version you
last pulled. If someone changed the dashboard in Plexus since then, push
stops and tells you. Pull again, or use
--forceto overwrite. - A new
uidcreates a dashboard. Push never deletes one. - Embedded panels are protected. Removing a panel that's embedded in a
live page is refused unless you pass
--force.
diff exits 1 when there are changes, so CI can check for drift:
- run: pip install plexus-python
- run: plexus dashboards diff
env:
PLEXUS_API_KEY: ${{ secrets.PLEXUS_DASHBOARDS_KEY }}The file
{
"$schema": "https://app.plexus.company/schemas/dashboard.v1.json",
"schemaVersion": 1,
"uid": "rover-01-starter",
"name": "rover-01 — starter",
"timeRange": { "type": "relative", "value": "15m" },
"refreshInterval": 5000,
"panels": [
{
"id": "battery",
"type": "stat",
"title": "Battery",
"description": "Is the pack healthy?",
"layout": { "x": 0, "y": 0, "w": 6, "h": 4 },
"metrics": ["rover-01:battery_v"],
"config": { "unit": "V", "decimals": 2 }
}
]
}uidis the dashboard's stable id and the file name. Renaming the dashboard doesn't change it.- Sources are slugs (
rover-01,scout-pg), so a file works in another workspace that has the same sources."plexus"means SQL over your Plexus telemetry. - Panel
ids must stay the same: embeds and links point at them. Leaveidout on a new panel and Plexus assigns one; push writes it back into your file. - Layout is a 24-column grid with 40px rows. A stat tile is
w: 6, h: 4, a chartw: 12, h: 6. configholds panel settings. Unknown keys there are kept. Unknown keys anywhere else are an error, so typos get caught.- The
$schemaline gives you autocomplete and checks in VS Code, Cursor and JetBrains.
API
Both endpoints are on https://app.plexus.company and take an API key with
the Manage dashboards scope in x-api-key.
| Method | Path | Does |
|---|---|---|
GET | /api/dashboards/{uid}/json | The file, with an ETag header |
PUT | /api/dashboards/{uid}/json | Replace it, or create it if the uid is new |
PUT options: If-Match: <etag> (refuse if it changed, 412),
?dryRun=true (validate, write nothing), ?force=true (allow removing
embedded panels). Errors come back as { message, details: [{ path, message }] }.