Last9 Last9

Mar 4th, ‘25 / 11 min read

Getting Started with the Grafana API: Practical Use Cases

Learn how to use the Grafana API to automate dashboards, manage users, and set up alerts—saving time and reducing manual effort.

Getting Started with the Grafana API: Practical Use Cases

Building dashboards one by one in Grafana can quickly become tedious. Clicking through the UI for every change isn’t exactly efficient. There’s a better way.

The Grafana API lets you automate repetitive tasks and extend Grafana’s capabilities beyond the UI. If you're new to monitoring or managing a complex observability setup, understanding the API can make your workflow more efficient and scalable.

What Is the Grafana API (And Why Should You Care?)

The Grafana API isn't just another technical checkbox – it's the backdoor to everything that makes Grafana powerful. At its core, it's a RESTful interface that lets you programmatically control nearly every aspect of your Grafana instance.

Here's the deal: anything you can click in the UI, you can automate with the API. Creating dashboards? Check. Managing users? Yep. Setting up data sources? Absolutely. But that's just scratching the surface.

For developers and DevOps engineers, this means:

  • Automation at scale – Create hundreds of dashboards in seconds, not days
  • Version control for your monitoring – Git-ify your dashboards and roll back when needed
  • Consistent dashboard design – Enforce standards across your organization
  • Dynamic dashboards – Generate dashboards that respond to changing infrastructure

The best part? It's all available through simple HTTP requests – no special plugins or tools required.

💡
To make your Grafana dashboards more dynamic and interactive, you can use variables to filter data efficiently. Here's how to set them up.

Getting Started with the Grafana API

Before jumping into the code, you'll need to grab an API key. Think of it as your VIP pass to the Grafana backend.

3 Authentication Options to Get API Key

You've got three ways to authenticate:

  1. API Keys – Simple but being deprecated in newer versions
  2. Service Accounts – The recommended approach for automation
  3. Basic Auth – For when you're testing or in a pinch

For most automation tasks, service accounts are your best bet. Here's how to set one up:

  1. Navigate to Administration → Service Accounts
  2. Create a new service account
  3. Assign appropriate permissions (Viewer, Editor, or Admin)
  4. Generate and securely store your token

Now you're ready to make your first API call. Let's start with something simple – checking the health of your Grafana instance:

curl -H "Authorization: Bearer your-token-here" https://your-grafana-instance/api/health

If everything's working, you'll get back a simple JSON response:

{
  "database": "ok",
  "version": "9.5.2"
}

You've just made your first Grafana API call!

3 Essential Grafana API Endpoints for Everyday Use

Let's talk practicality. These are the endpoints you'll find yourself reaching for constantly:

Dashboard Management

Creating and managing dashboards is where the API really shines. Here's how to get all dashboards:

curl -H "Authorization: Bearer your-token-here" https://your-grafana-instance/api/search

To grab a specific dashboard:

curl -H "Authorization: Bearer your-token-here" https://your-grafana-instance/api/dashboards/uid/your-dashboard-uid

And the crown jewel – creating a dashboard:

curl -X POST \
  -H "Authorization: Bearer your-token-here" \
  -H "Content-Type: application/json" \
  -d '{"dashboard": {"title": "API Created Dashboard", "panels": [...]}, "overwrite": true, "message": "Created via API"}' \
  https://your-grafana-instance/api/dashboards/db
💡
If you're running Grafana in a containerized environment, setting it up with Docker can simplify deployment and scaling. Learn more here.

Data Source Operations

Data sources are essential for Grafana dashboards, as they provide the metrics and logs that power your visualizations. The Grafana API allows you to manage data sources programmatically instead of configuring them manually through the UI.

1. Listing All Data Sources

curl -H "Authorization: Bearer your-token-here" https://your-grafana-instance/api/datasources

What this does:

  • Sends a GET request to the Grafana API to retrieve a list of all configured data sources.
  • Uses an Authorization header with a Bearer token (your-token-here) to authenticate the request.
  • The response will return details about each data source, such as their names, types, and connection settings.

2. Creating a New Prometheus Data Source

curl -X POST \
  -H "Authorization: Bearer your-token-here" \
  -H "Content-Type: application/json" \
  -d '{"name":"My Prometheus","type":"prometheus","url":"http://prometheus:9090","access":"proxy"}' \
  https://your-grafana-instance/api/datasources

Breaking it down:

  • -X POST → Specifies that this is a POST request, which is used to create new resources.
  • -H "Authorization: Bearer your-token-here" → Authenticates the request using your API token.
  • -H "Content-Type: application/json" → Tells Grafana that the request body contains JSON data.
  • -d '{...}' → The JSON payload defining the new data source:
    • "name": "My Prometheus" → The name of the data source.
    • "type": "prometheus" → The type of data source (in this case, Prometheus).
    • "url": "http://prometheus:9090" → The URL where Prometheus is running.
    • "access": "proxy" → Defines how Grafana connects to the data source. "proxy" means Grafana will route requests through its backend instead of the user's browser.
  • The API endpoint https://your-grafana-instance/api/datasources is where Grafana manages data sources.

What happens next?
If the request is successful, Grafana will return a response confirming the creation of the new Prometheus data source. You can now use it in your dashboards without manually configuring it in the UI.

User and Team Management

For those of you managing Grafana at scale:

# List all users
curl -H "Authorization: Bearer your-token-here" https://your-grafana-instance/api/users

# Create a new team
curl -X POST \
  -H "Authorization: Bearer your-token-here" \
  -H "Content-Type: application/json" \
  -d '{"name":"DevOps Team"}' \
  https://your-grafana-instance/api/teams

Breaking it down:

  • -X POST → Specifies that this is a POST request, used to create new resources.
  • -H "Authorization: Bearer your-token-here" → Authenticates the request using your API token.
  • -H "Content-Type: application/json" → Tells Grafana that the request body contains JSON data.
  • -d '{"name":"DevOps Team"}' → The JSON payload that defines the new team:
    • "name": "DevOps Team" → Sets the name of the team.
  • The API endpoint https://your-grafana-instance/api/teams is where Grafana manages team creation.

What happens next?
If successful, the API will return a response with details about the newly created team. You can then assign users to the team, manage permissions, and integrate it with other Grafana features like dashboard access controls.

💡
Handling exceptions properly in Python can save you hours of debugging. Learn how to set up effective logging for errors. Read more here.

How to Automate Dashboard Creation with Python

Manually creating and updating dashboards in Grafana can be time-consuming, especially when managing multiple services.

Instead of relying on Bash scripts for simple API calls, Python provides more flexibility and scalability.

The requests library makes it easy to interact with Grafana’s API and automate dashboard creation.

1. Setting Up API Credentials

import requests
import json

GRAFANA_URL = "https://your-grafana-instance"
API_TOKEN = "your-token-here"
HEADERS = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Content-Type": "application/json"
}
  • Imports requests and json to handle API calls and data processing.
  • Defines the GRAFANA_URL (your Grafana instance URL) and API_TOKEN (your API key for authentication).
  • Sets up the HEADERS, which include authorization and content type (JSON).

2. Loading a Dashboard Template

# Load dashboard template from file
with open('dashboard_template.json', 'r') as f:
    dashboard = json.load(f)
  • Reads a dashboard template JSON file, which contains the structure of a Grafana dashboard.
  • Loads the JSON data into the dashboard variable for further modifications.

3. Customizing the Dashboard for Each Service

services = ["auth", "payments", "inventory", "shipping"]

for service in services:
    # Customize dashboard for this service
    dashboard["dashboard"]["title"] = f"{service.capitalize()} Service Dashboard"
  • Defines a list of services (auth, payments, inventory, shipping).
  • Loops through each service and updates the dashboard title to match the service name.

4. Updating Dashboard Panels with Service-Specific Metrics

# Update variables and panel targets
    for panel in dashboard["dashboard"]["panels"]:
        panel["targets"][0]["expr"] = panel["targets"][0]["expr"].replace("${service}", service)
  • Loops through the panels in the dashboard and updates the PromQL expressions to reflect the specific service.
  • Uses .replace("${service}", service) to dynamically modify queries.

5. Sending the Dashboard to Grafana

# Create the dashboard
    response = requests.post(
        f"{GRAFANA_URL}/api/dashboards/db",
        headers=HEADERS,
        json={
            "dashboard": dashboard["dashboard"],
            "overwrite": True,
            "message": f"Updated {service} dashboard via API"
        }
    )
  • Makes a POST request to the Grafana API (/api/dashboards/db) to create or update the dashboard.
  • Includes:"dashboard": dashboard["dashboard"] → The modified dashboard JSON."overwrite": True → Ensures existing dashboards with the same name are updated."message" → Adds a commit-style message for tracking changes.

6. Handling the API Response

if response.status_code == 200:
        print(f"Successfully created dashboard for {service}")
    else:
        print(f"Failed to create dashboard for {service}: {response.text}")
  • Checks the HTTP status code to determine if the request was successful.
  • If 200 OK, prints a success message; otherwise, prints the error response.
💡
If Grafana doesn’t fit your needs, there are plenty of other open-source and commercial alternatives worth exploring. Check them out here.

Advanced Techniques: Dynamic Dashboards & Alerting

Now that you've got the basics down, let's level up your Grafana API knowledge.

Generating Dashboards Based on Infrastructure Changes

One of the most powerful applications is generating dashboards automatically when your infrastructure changes.

Here's how you might hook this into your Terraform workflow:

def update_dashboards_from_terraform_output(tf_output_file):
    """Create or update dashboards based on Terraform outputs"""
    with open(tf_output_file, 'r') as f:
        infrastructure = json.load(f)
    
    # For each new service discovered in Terraform output
    for service in infrastructure['services']['value']:
        # Check if dashboard exists
        search_response = requests.get(
            f"{GRAFANA_URL}/api/search?query={service['name']}",
            headers=HEADERS
        )
        
        if len(search_response.json()) == 0:
            # No dashboard exists, create from template
            create_dashboard_for_service(service)
        else:
            # Update existing dashboard
            update_dashboard_for_service(service, search_response.json()[0]['uid'])

Breaking down the code:

This function automates the creation and updating of Grafana dashboards based on Terraform outputs.

  1. Read Terraform Output File
    • The function opens and loads a JSON file (tf_output_file) containing Terraform output data.
    • This file includes infrastructure details, such as deployed services.
  2. Iterate Over Services
    • It loops through the services listed in the Terraform output (infrastructure['services']['value']).
    • Each service is processed to determine whether a dashboard already exists in Grafana.
  3. Check for Existing Dashboards
    • Sends a GET request to Grafana’s API (/api/search) to check if a dashboard already exists for the service.
    • The query parameter filters dashboards by the service name.
    • If the response is empty (len(search_response.json()) == 0), it means no dashboard exists.
  4. Create or Update Dashboards
    • If no dashboard exists, it calls create_dashboard_for_service(service) to generate a new dashboard from a template.
    • If a dashboard already exists, it updates it using update_dashboard_for_service(service, search_response.json()[0]['uid']), passing the existing dashboard’s unique ID (uid).

This ensures that dashboards stay aligned with the current infrastructure state, avoiding manual intervention.

💡
If you're using OpenTelemetry for observability, integrating it with Grafana can help you visualize and analyze your telemetry data effectively. Learn more here.

Programmatic Alert Management

Alerts are critical but often overlooked for API automation. Here's how to manage them:

# Create a new alert rule
alert_rule = {
    "name": "High Error Rate",
    "condition": "C",
    "data": [
        {"refId": "A", "queryType": "range", "datasourceUid": "prometheus", 
         "model": {"expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) / sum(rate(http_requests_total[5m])) > 0.05"}},
        {"refId": "B", "queryType": "range", "datasourceUid": "prometheus", 
         "model": {"expr": "sum(rate(http_requests_total[5m]))"}},
        {"refId": "C", "queryType": "reduce", "reducer": "last", "datasourceUid": "__expr__", 
         "model": {"expression": "$A > 0.05", "type": "math"}}
    ],
    "noDataState": "OK",
    "execErrState": "Error",
    "for": "5m",
    "labels": {"severity": "warning"},
    "annotations": {"summary": "High error rate detected"}
}

response = requests.post(
    f"{GRAFANA_URL}/api/ruler/grafana/api/v1/rules/default",
    headers=HEADERS,
    json=[{
        "name": "Error Rates",
        "interval": "1m",
        "rules": [alert_rule]
    }]
)

Breaking down the Code:

This script defines and creates an alert rule in Grafana using its API. The alert rule monitors HTTP request error rates and triggers a warning if the error rate exceeds 5%.

  1. Define the Alert Rule (alert_rule)
    • The rule is named "High Error Rate" and evaluates conditions using three query steps (A, B, and C).
    • Query A: Calculates the error rate by summing HTTP 5xx status requests over a 5-minute window and dividing it by the total request count.
    • Query B: Retrieves the total number of HTTP requests in the last 5 minutes.
    • Query C: Uses a mathematical expression ($A > 0.05) to determine if the error rate exceeds 5%.
  2. Alert Conditions
    • noDataState: "OK" → If no data is available, the system assumes everything is fine.
    • execErrState: "Error" → If an execution error occurs, the alert enters an error state.
    • for: "5m" → The condition must persist for 5 minutes before triggering the alert.
    • Labels and Annotations help categorize the alert (severity: warning) and provide a summary.
  3. Send the Alert Rule to Grafana
    • A POST request is made to Grafana’s /api/ruler/grafana/api/v1/rules/default endpoint.
    • The rule is grouped under "Error Rates", with a 1-minute evaluation interval.
    • The request payload includes the alert rule as a list inside "rules".

Outcome

If the error rate exceeds 5% for more than 5 minutes, Grafana triggers an alert, helping teams detect and respond to high failure rates in real-time.

💡
If you're deciding between Kibana and Grafana for data visualization and monitoring, understanding their strengths can help. Compare them here.

Grafana API Limitations and Workarounds

Like any tool, the Grafana API has its rough edges. Here are some common challenges and how to handle them:

Version Compatibility Issues

The API changes between versions. To maintain compatibility:

  • Use feature detection when possible
  • Include version checks in your scripts
  • Test automation against staging environments before production

Rate Limiting

For large operations, you might hit rate limits. Solution:

  • Implement backoff strategies in your code
  • Batch operations where possible
  • Run intensive operations during off-hours

Working with Provisioning

Sometimes the API conflicts with provisioning. To handle this:

  • Use tags to identify API-managed resources
  • Implement safeguards to prevent overwrites
  • Consider a hybrid approach for critical components

Practical Use Case: Integrating Grafana API with Last9

Last9 takes your observability to the next level, and combining it with Grafana's API creates a powerful workflow. Here's how to connect these tools:

Setting Up the Last9 Integration

First, establish the connection between Grafana and Last9:

  1. Create a dedicated service account in Grafana for Last9
  2. Generate an API key with appropriate permissions
  3. Configure the Last9 integration with your Grafana URL and API key

Syncing Dashboards with Last9

Once connected, you can sync your dashboards:

import requests

# Last9 API details
LAST9_API_URL = "https://api.last9.io"
LAST9_API_KEY = "your-last9-api-key"

# Get dashboards from Grafana
grafana_dashboards = requests.get(
    f"{GRAFANA_URL}/api/search?type=dash-db",
    headers=GRAFANA_HEADERS
).json()

# Sync with Last9
for dashboard in grafana_dashboards:
    dashboard_details = requests.get(
        f"{GRAFANA_URL}/api/dashboards/uid/{dashboard['uid']}",
        headers=GRAFANA_HEADERS
    ).json()
    
    # Send to Last9
    requests.post(
        f"{LAST9_API_URL}/v1/dashboards/import",
        headers={"Authorization": f"Bearer {LAST9_API_KEY}"},
        json={
            "source": "grafana",
            "dashboard": dashboard_details["dashboard"]
        }
    )

Using Last9's Advanced Features

With this integration, you can now:

  • Create service maps that correlate with your Grafana dashboards
  • Implement cross-dashboard dependencies
  • Set up advanced SLO tracking that complements Grafana's visualizations

The real power comes from automating this entire workflow – keeping Last9 and Grafana in perfect sync as your infrastructure evolves.

Wrapping Up

We've covered a lot of ground, from basic authentication to advanced integrations. Here's how to develop your API strategy:

  1. Start small – Automate one repetitive task first
  2. Build a library – Create reusable functions for common operations
  3. Version control everything – Store your scripts in Git alongside your infrastructure code
  4. Implement testing – Verify your API interactions before they hit production
  5. Document your approach – Make sure your team understands the automation
💡
And if you ever need to talk things through, our Discord community is open. There's a dedicated channel where you can discuss your use case with other developers.

FAQs

What's the difference between Grafana's API v1 and v2?

The main difference is in authentication and endpoint structure. V1 used API keys exclusively, while v2 introduced service account tokens which are more secure and flexible. V2 also reorganized many endpoints for better consistency and added new capabilities for alerting, library panels, and annotations. If you're starting fresh, always go with v2.

Can I use the Grafana API with the cloud-hosted version?

Absolutely. The Grafana Cloud API works essentially the same way as self-hosted instances. The main difference is in authentication – you'll need to use Grafana Cloud API keys or tokens. Also, some enterprise features might have slightly different endpoints, so check the docs for your specific Grafana Cloud tier.

How do I handle API rate limiting?

Grafana implements rate limiting to prevent abuse, but the specifics vary by deployment. For heavy automation:

  • Implement exponential backoff in your scripts
  • Batch operations where possible (create multiple items in one request)
  • Schedule large operations during off-hours
  • Monitor HTTP 429 responses and adjust accordingly

Is there an official Grafana API client library?

Grafana doesn't maintain official client libraries, but there are excellent community options:

  • For Python: grafana-client or grafanalib
  • For Go: grafana-api-golang-client
  • For JavaScript: grafana-api-js-client

These libraries handle authentication, serialization, and common operations, saving you from writing boilerplate code.

How do I version control my Grafana dashboards?

The API makes this straightforward:

  1. Export dashboards using the /api/dashboards/uid/{uid} endpoint
  2. Store the JSON in your Git repository
  3. Use CI/CD to deploy changes back to Grafana
  4. Consider tools like grafana-dash-gen to make the process even easier

This approach gives you rollbacks, change history, and proper peer reviews for your monitoring configuration.

Can I migrate dashboards between Grafana instances with the API?

Yes, and it's a common use case:

  1. Export from the source using GET /api/dashboards/uid/{uid}
  2. Modify the result (change data source references if needed)
  3. Remove the id field from the dashboard object
  4. POST to the target instance's /api/dashboards/db endpoint

Just be aware that you'll need to handle data source mappings if the instances use different data sources.

How do I debug API issues?

When things go wrong:

  1. Check HTTP response codes and body content
  2. Enable debug headers with X-Grafana-Debug: true
  3. Verify your authentication token hasn't expired
  4. Try the operation in the Grafana UI to see if it's an API issue or underlying problem
  5. Check Grafana server logs for more details

Contents


Newsletter

Stay updated on the latest from Last9.

Authors
Prathamesh Sonpatki

Prathamesh Sonpatki

Prathamesh works as an evangelist at Last9, runs SRE stories - where SRE and DevOps folks share their stories, and maintains o11y.wiki - a glossary of all terms related to observability.

X
Topics