# 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.
