DEV Community

Alex Spinov
Alex Spinov

Posted on

Grafana Has a Free API — Here's How to Create Dashboards and Query Data Programmatically

Grafana is an open-source observability platform with a powerful HTTP API. You can create dashboards, manage data sources, set up alerts, and query metrics — all programmatically.

Getting Started

docker run -d -p 3000:3000 grafana/grafana-oss
Enter fullscreen mode Exit fullscreen mode

Default credentials: admin/admin. Create an API key in Settings → API Keys.

Create a Dashboard

const response = await fetch("http://localhost:3000/api/dashboards/db", {
  method: "POST",
  headers: {
    "Authorization": "Bearer your-api-key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    dashboard: {
      title: "API Performance",
      panels: [{
        type: "timeseries",
        title: "Request Latency",
        gridPos: { h: 8, w: 12, x: 0, y: 0 },
        targets: [{
          expr: "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))",
          legendFormat: "p95 latency"
        }]
      }, {
        type: "stat",
        title: "Total Requests",
        gridPos: { h: 4, w: 6, x: 12, y: 0 },
        targets: [{
          expr: "sum(rate(http_requests_total[1h]))"
        }]
      }],
      time: { from: "now-6h", to: "now" }
    },
    overwrite: false
  })
});

const data = await response.json();
console.log(`Dashboard URL: ${data.url}`);
Enter fullscreen mode Exit fullscreen mode

Add a Data Source

await fetch("http://localhost:3000/api/datasources", {
  method: "POST",
  headers: {
    "Authorization": "Bearer your-api-key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    name: "Prometheus",
    type: "prometheus",
    url: "http://prometheus:9090",
    access: "proxy",
    isDefault: true
  })
});
Enter fullscreen mode Exit fullscreen mode

Query Data Sources

const result = await fetch("http://localhost:3000/api/ds/query", {
  method: "POST",
  headers: {
    "Authorization": "Bearer your-api-key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    queries: [{
      datasourceId: 1,
      expr: "up",
      refId: "A"
    }],
    from: "now-1h",
    to: "now"
  })
});
Enter fullscreen mode Exit fullscreen mode

Alerting API

// Create alert rule
await fetch("http://localhost:3000/api/v1/provisioning/alert-rules", {
  method: "POST",
  headers: {
    "Authorization": "Bearer your-api-key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    title: "High Error Rate",
    condition: "C",
    data: [{
      refId: "A",
      queryType: "range",
      model: { expr: "rate(http_errors_total[5m])" }
    }],
    for: "5m"
  })
});
Enter fullscreen mode Exit fullscreen mode

Need to extract or automate web content at scale? Check out my web scraping tools on Apify — no coding required. Or email me at spinov001@gmail.com for custom solutions.

Top comments (0)