dashboarding
grafana/skills
Build and ship Grafana dashboards as JSON via HTTP API with panels, variables, transformations, and annotations.
What is dashboarding?
This skill enables programmatic creation and modification of Grafana dashboards by working directly with the dashboard JSON model and HTTP API. Use it when you need to script dashboard creation, add template variables, apply transformations, or push dashboards via API—even when requests don't explicitly mention the API or schema.
- Push new dashboards and update existing ones via POST /api/dashboards/db with verification
- Configure panel types: timeseries, stat, gauge, table, heatmap, logs, traces, node-graph
- Define template variables (query, multi-select, chained) with datasource bindings
- Apply transformations: organize, calculateField, filterByValue to reshape data
- Add dashboard and panel links with variable interpolation (${__field.labels.x}, ${__from})
- Overlay Loki/Prometheus annotations and configure gridPos 24-column layout with units and thresholds
How to install dashboarding
npx skills add https://github.com/grafana/skills --skill dashboarding- Grafana stack (OSS, Enterprise, or Cloud) reachable from your machine
- API token with dashboards:write permission
- jq for inspecting JSON responses
How to use dashboarding
- 1.Fetch an existing dashboard or create new dashboard JSON with uid, title, schemaVersion, and panels array
- 2.Define datasources (Prometheus, Loki) and template variables in the templating.list section
- 3.Configure panels with gridPos layout, fieldConfig (units, thresholds), targets, and transformations
- 4.Validate JSON syntax with jq before sending
- 5.POST the dashboard payload to /api/dashboards/db with Authorization header and overwrite: true
- 6.Verify the response contains status=success and version number, then GET the dashboard UID to confirm round-trip
Use cases
- Create a dashboard for a new service by writing and pushing dashboard JSON
- Add a $job dropdown variable to filter metrics across multiple services
- Compute an Error % column by chaining a calculateField transformation
- Overlay deployment events as annotations on timeseries panels
- Export and version-control dashboard JSON, then push updates via API
- Platform engineers automating dashboard provisioning
- SREs scripting observability infrastructure
- DevOps teams managing dashboards as code
- Backend developers building monitoring for new services
dashboarding FAQ
Fetch the dashboard JSON, append an object to templating.list with name: 'job', type: 'query', datasource pointing to Prometheus, and query: 'label_values(up, job)'. Update panel expressions to use {job=~"$job"} and POST back with overwrite: true.
Grafana dashboards use a 24-column grid. Each panel has gridPos with x (0-23), y (row position), w (width 1-24), and h (height in grid units). Panels can overlap; y auto-increments as you add panels.
Check the POST response for status: 'success', uid, url, and version fields. Then GET /api/dashboards/uid/{uid} and confirm the title and panel count match your payload.
Yes. Add a calculateField transformation to the panel's transformations array with mode: 'reduceRow', a binary operator (/, *, +, -), and left/right field names. The new field appears in the panel output.
Add an annotations array to the dashboard JSON with datasource (Loki or Prometheus), query, and tagKeys. Use a logs panel or timeseries with annotation queries to show events like deploys on your metrics.
Full instructions (SKILL.md)
Source of truth, from grafana/skills.
name: dashboarding
license: Apache-2.0
description: Build, modify, and ship Grafana dashboards as JSON via the HTTP API — panel types (timeseries / stat / gauge / table / heatmap / logs / traces / node-graph), gridPos 24-column layout, units, thresholds, template + datasource + chained variables, transformations (organize / calculateField / filterByValue), panel + dashboard links with ${__field.labels.x} / ${__from}, and Loki/Prometheus annotations. Use when scripting dashboard creation, writing the dashboard JSON for a new service, adding a $job dropdown variable, computing an "Error %" column with a transformation, overlaying deploys as annotations, or pushing a dashboard via POST /api/dashboards/db — even when the user says "create a dashboard for this metric", "add a service dropdown", "show errors as percentage", "overlay our deploys", or "export the dashboard JSON" without naming the API or schema. After every API push, verify with the returned version plus a GET on the dashboard UID.
Grafana Dashboard Authoring
Dashboards are JSON. Author once, push via API, share by uid.
Prerequisites
- Grafana stack (OSS, Enterprise, or Cloud) reachable from your machine
- API token with
dashboards:write(Authorization: Bearer <token>) jqfor inspecting responses- The JSON-schema cheat sheet in
references/json-schema.md
Common Workflows
1. Push a new dashboard via the API + verify
# 1. Build the payload — wrap the dashboard JSON, set folder, mark overwrite
cat > /tmp/dash.json <<'JSON'
{
"dashboard": {
"uid": "demo-svc-v1",
"title": "Demo Service",
"schemaVersion": 41,
"tags": ["demo"],
"time": { "from": "now-1h", "to": "now" },
"templating": { "list": [] },
"panels": [{
"id": 1, "type": "timeseries", "title": "Request Rate",
"gridPos": { "x": 0, "y": 0, "w": 24, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [{
"expr": "sum(rate(http_requests_total[5m])) by (status_code)",
"legendFormat": "{{status_code}}", "refId": "A"
}],
"fieldConfig": { "defaults": { "unit": "reqps" }, "overrides": [] }
}]
},
"folderUid": "",
"overwrite": true,
"message": "initial push"
}
JSON
# 2. Validate the JSON BEFORE you send it (catches trailing-comma typos)
jq empty /tmp/dash.json && echo "json ok"
# 3. POST
RESP=$(curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"$GRAFANA/api/dashboards/db" -d @/tmp/dash.json)
echo "$RESP" | jq '{status, uid, url, version}'
# Expect: status="success", url="/d/demo-svc-v1/...", version=1 (incremented on each push)
# 4. Verify the round-trip — read it back and confirm one panel + the expected title
curl -s -H "Authorization: Bearer $TOKEN" \
"$GRAFANA/api/dashboards/uid/demo-svc-v1" \
| jq '{title: .dashboard.title, panels: (.dashboard.panels | length)}'
# Expect: {"title":"Demo Service","panels":1}
# 5. Open the dashboard in a browser — confirm the panel renders with data.
2. Add a $job template variable to an existing dashboard
# 1. Fetch existing dashboard
curl -s -H "Authorization: Bearer $TOKEN" \
"$GRAFANA/api/dashboards/uid/demo-svc-v1" > /tmp/dash.json
# 2. Edit templating.list — append:
# { "name":"job", "type":"query",
# "datasource":{"type":"prometheus","uid":"prometheus"},
# "query":{"query":"label_values(up, job)","refId":"A"},
# "refresh":2, "includeAll":true, "multi":true, "label":"Service" }
# (Use jq, an editor, or the Grafana UI — schema in references/json-schema.md.)
# 3. Update the panel expr to use the variable: rate(http_requests_total{job=~"$job"}[5m])
# 4. POST it back with overwrite: true. Verify the variable appears in the UI dropdown.
3. Compute an "Error %" column with a transformation
{
"id": "calculateField",
"options": {
"alias": "Error %", "mode": "reduceRow",
"reduce": { "reducer": "last" },
"binary": { "left": "errors", "right": "total", "operator": "/" }
}
}
Add this to the panel's transformations: []. Verify in the UI panel inspector — the new field should appear and update with the variable selection.
Full schema (panels, units, all transformations, annotations, links): references/json-schema.md.
API reference
# Get
curl -s -H "Authorization: Bearer $TOKEN" \
"$GRAFANA/api/dashboards/uid/<uid>" | jq '.dashboard'
# Search
curl -s -H "Authorization: Bearer $TOKEN" \
"$GRAFANA/api/search?query=kubernetes&type=dash-db" | jq '.[] | {uid,title,folderTitle}'
# Create folder
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" "$GRAFANA/api/folders" \
-d '{"uid":"platform-team","title":"Platform Team"}'
For dashboards embedded in app plugins, use @grafana/scenes (skill grafana-o11y:grafana-scenes).
Resources
Related skills
More from grafana/skills and the wider catalog.

database-observability
Query-level insights for MySQL and PostgreSQL without code changes—RED metrics, explain plans, and APM correlation.

datasources-provisioning
Generate Grafana data source provisioning files (YAML or Terraform) from plugin schemas.

dpm-finder
Rank Prometheus metrics by Data Points per Minute to identify cost drivers in Grafana Cloud.

fleet-management
Manage a fleet of Grafana Alloy collectors remotely via OpAMP—author pipelines once, target with matchers, deploy without restarts.

grafana-oss
Provision Grafana OSS dashboards, data sources, users, and plugins from YAML with API validation.

grafana-scenes
Build reactive Grafana plugin pages with declarative scene objects and data-driven layouts.