← Back to Wiki
Monitoring / Grafana

Wiring Checkmk Into Grafana: the Undocumented Request Shapes and the One Field That Breaks Everything

The official Checkmk datasource plugin for Grafana works well once it's actually configured correctly — but its real request-body shape isn't documented anywhere reachable through Grafana's own API docs, and one specific settings field defaults to a value that silently breaks every single graph on a free/Community Checkmk install.

Share on X

The #1 thing to check if every graph is broken

The datasource's "Edition" setting defaults to a commercial-edition assumption, even when pointed at a free/Community Checkmk install. With the wrong edition selected, every graph query 404s on an autocomplete call that simply doesn't exist on Community/Raw builds. The error that surfaces sounds like a helpful hint ("Choose correct Checkmk edition...") but it's easy to miss, since the settings field already shows some selection — it doesn't look empty or obviously wrong at a glance.

Fix: in the datasource's settings, explicitly set Edition to Community Edition (or whichever matches your actual install), then Save & Test. If every panel using this datasource is failing identically regardless of what host/service it targets, check this field before anything else.

The real panel query shape, since it isn't documented anywhere obvious

This plugin is frontend-only JavaScript with no backend binary, which means its actual request format isn't discoverable through Grafana's normal datasource API documentation — recovering it required reading the plugin's own minified source and capturing a real request via a browser network inspector. A panel target looks like this:

{
  "refId": "A",
  "datasource": {"type": "checkmk-cloud-datasource", "uid": "<datasource-uid>"},
  "requestSpec": {
    "site": "monitoring",
    "host_name": "<host>",
    "service": "<service description>",
    "graph_type": "predefined_graph",
    "graph": "<graph-id, resolved separately>",
    "aggregation": "off"
  }
}

graph_type can also be "single_metric", which needs a metric ID instead of a graph ID (resolved via a different autocomplete endpoint than the one below).

Resolving graph IDs — call Checkmk's REST API directly, not through Grafana

Graph IDs aren't predictable from a service name alone, and they're not portable across hosts even for identically-named services — the same "CPU utilization" service can resolve to a completely different internal graph ID depending on whether the underlying check is SNMP-based or an agent/kernel-level check. Resolve it per host+service pair, every time, via Checkmk's own REST API directly (not through Grafana's datasource proxy):

curl -s -X POST "http://<checkmk-host>/<site>/check_mk/api/1.0/objects/autocomplete/available_graphs" \
  -H "Authorization: Bearer automation <secret>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"value":"","parameters":{"strict":true,"show_independent_of_context":false,
       "context":{"siteopt":{"site":"monitoring"},"host":{"host":"<host>"},
                  "service":{"service":"<service>"}}}}'
The request body shape has several non-obvious traps, and every wrong guess produces a different, unhelpful error rather than one that states the correct shape: the top-level key is parameters, not params; context nests inside parameters, not alongside value; and host/service/site are each wrapped in their own single-key object ({"host": {"host": "..."}}, not a bare string). Also worth being explicit about the Accept: application/json header — some HTTP clients don't set it by default, and without it this Checkmk version returns a bare 406 regardless of whether the body itself is correct.

Building a large dashboard: skip the panel editor, POST the JSON directly

For a dashboard with more than a handful of panels, clicking through Grafana's panel editor once per series is slow and error-prone. Build the full dashboard JSON — every panel, every target — as one structure client-side, then create it in a single call:

POST /api/dashboards/db

Set a fixed, explicit "uid" in that payload rather than letting Grafana generate one — this avoids ending up with duplicate dashboards if you ever need to re-run the same creation script (a fixed UID makes it an update instead of a fresh create).