# Grafana Dashboard API Patterns ## Creating a dashboard via REST API After the Prometheus data source is created, provision dashboards via POST to `/api/dashboards/db`: ```bash curl -s -X POST http://127.0.0.1:3002/api/dashboards/db \ -H "Content-Type: application/json" \ -u admin:admin \ -d @dashboard.json ``` Response: `{"id":..., "uid":"...", "slug":"...", "status":"success", "url":"/d/uid/title"}` ## Common node_exporter panel queries ### CPU Usage (stat or timeseries) ``` avg by(instance) (1 - rate(node_cpu_seconds_total{mode='idle'}[5m])) ``` ### RAM Usage (gauge or timeseries) ``` 1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) ``` Bytes variant: `node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes` ### Disk Usage (gauge) ``` 1 - (node_filesystem_avail_bytes{mountpoint='/'} / node_filesystem_size_bytes{mountpoint='/'}) ``` ### Uptime (stat) ``` time() - node_boot_time_seconds ``` ## Panel layout reference (gridPos) The dashboard grid is 24 columns wide. Common layouts: | Panel | gridPos | Width | |-------|---------|-------| | Single stat | `{h:8, w:6, x:0, y:0}` | 1/4 width | | Timeseries full | `{h:10, w:12, x:0, y:8}` | 1/2 width | | Two stat row | `{h:8, w:12, x:0, y:0}` + `{h:8, w:12, x:12, y:0}` | 1/2 each | ## Adding a Prometheus data source ```bash curl -s -X POST http://127.0.0.1:3002/api/datasources \ -H "Content-Type: application/json" \ -u admin:admin \ -d '{ "name":"Prometheus", "type":"prometheus", "url":"http://127.0.0.1:9090", "access":"proxy", "isDefault":true }' ``` Response: `{"datasource":{"id":1,"uid":"...","name":"Prometheus",...},"message":"Datasource added"}` ## Pitfalls - **Auth**: Use `-u admin:admin` (or whatever password was set with `GF_SECURITY_ADMIN_PASSWORD`). Default is `admin/admin`. - **Default data source**: Set `"isDefault":true` so panels don't need an explicit data source reference. - **Overwriting**: When re-importing, send `"overwrite": true` in the payload body (at the same level as `"dashboard"`). - **Time range**: Set `"time": {"from": "now-6h", "to": "now"}` and `"refresh": "30s"` at the `dashboard` level.