DEV Community

Alex Spinov
Alex Spinov

Posted on

Grafana Cloud Has a Free API: Here's How to Build Dashboards and Query Metrics Programmatically

What is Grafana Cloud?

Grafana Cloud is a fully managed observability platform combining Grafana, Prometheus, Loki, and Tempo. You get metrics, logs, traces, and dashboards — all in one place.

The free tier includes 10K metrics, 50 GB logs, 50 GB traces — and the HTTP API is completely free to use.

Grafana HTTP API

Authentication

export GRAFANA_URL="https://your-instance.grafana.net"
export GRAFANA_TOKEN="your-service-account-token"
Enter fullscreen mode Exit fullscreen mode

Create a Dashboard

curl -X POST "$GRAFANA_URL/api/dashboards/db" \
  -H "Authorization: Bearer $GRAFANA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "dashboard": {
      "title": "API Performance",
      "panels": [
        {
          "title": "Request Rate",
          "type": "timeseries",
          "gridPos": {"h": 8, "w": 12, "x": 0, "y": 0},
          "targets": [{
            "expr": "rate(http_requests_total[5m])",
            "legendFormat": "{{method}} {{status}}"
          }]
        }
      ]
    },
    "overwrite": false
  }'
Enter fullscreen mode Exit fullscreen mode

Query Prometheus Metrics

# Instant query
curl -G "$GRAFANA_URL/api/datasources/proxy/1/api/v1/query" \
  -H "Authorization: Bearer $GRAFANA_TOKEN" \
  --data-urlencode 'query=up'

# Range query
curl -G "$GRAFANA_URL/api/datasources/proxy/1/api/v1/query_range" \
  -H "Authorization: Bearer $GRAFANA_TOKEN" \
  --data-urlencode 'query=rate(http_requests_total[5m])' \
  --data-urlencode 'start=2026-03-28T00:00:00Z' \
  --data-urlencode 'end=2026-03-28T12:00:00Z' \
  --data-urlencode 'step=60'
Enter fullscreen mode Exit fullscreen mode

Query Loki Logs

curl -G "$GRAFANA_URL/api/datasources/proxy/2/loki/api/v1/query_range" \
  -H "Authorization: Bearer $GRAFANA_TOKEN" \
  --data-urlencode 'query={app="my-service"} |= "error"' \
  --data-urlencode 'limit=100'
Enter fullscreen mode Exit fullscreen mode

Node.js SDK

const fetch = require("node-fetch");

const GRAFANA_URL = process.env.GRAFANA_URL;
const TOKEN = process.env.GRAFANA_TOKEN;

async function queryMetrics(promql) {
  const res = await fetch(
    `${GRAFANA_URL}/api/datasources/proxy/1/api/v1/query?query=${encodeURIComponent(promql)}`,
    { headers: { Authorization: `Bearer ${TOKEN}` } }
  );
  return res.json();
}

async function createAlert(name, condition) {
  const res = await fetch(`${GRAFANA_URL}/api/v1/provisioning/alert-rules`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: name,
      condition: "A",
      data: [{
        refId: "A",
        queryType: "",
        model: { expr: condition, intervalMs: 1000, maxDataPoints: 43200 },
      }],
      for: "5m",
    }),
  });
  return res.json();
}

// Usage
const result = await queryMetrics('rate(http_requests_total{status="500"}[5m])');
console.log(result.data.result);
Enter fullscreen mode Exit fullscreen mode

Push Metrics (Prometheus Remote Write)

// Push custom metrics to Grafana Cloud
const pushMetric = async (name, value, labels = {}) => {
  const labelStr = Object.entries(labels)
    .map(([k, v]) => `${k}="${v}"`)
    .join(",");

  const body = `# TYPE ${name} gauge\n${name}{${labelStr}} ${value} ${Date.now()}\n`;

  await fetch(`${GRAFANA_URL}/api/prom/push`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${TOKEN}`,
      "Content-Type": "text/plain",
    },
    body,
  });
};

await pushMetric("app_active_users", 142, { region: "us-east" });
Enter fullscreen mode Exit fullscreen mode

Manage Alerts via API

# List all alert rules
curl "$GRAFANA_URL/api/v1/provisioning/alert-rules" \
  -H "Authorization: Bearer $GRAFANA_TOKEN"

# Create notification contact point
curl -X POST "$GRAFANA_URL/api/v1/provisioning/contact-points" \
  -H "Authorization: Bearer $GRAFANA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "slack-alerts",
    "type": "slack",
    "settings": {
      "url": "https://hooks.slack.com/services/xxx"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Free Tier

Feature Free Forever
Metrics 10,000 series
Logs 50 GB
Traces 50 GB
Dashboards Unlimited
Alerts Unlimited
Users 3
API Access Full

Need custom monitoring dashboards or observability automation?

📧 spinov001@gmail.com
🔧 My tools on Apify Store

What monitoring stack do you use? Share below!

Top comments (0)