HudQL API

Use Hud's API for a flexible access to Hud's data, for creating automations, dashboards, and alerts.

What is HudQL?

HudQL is Hud's SQL query API. It lets you run SQL directly against the runtime data Hud collects from your services - endpoint metrics, function metrics, machine metrics, and more.

HudQL is the data layer beneath Hud MCP, and it's also available through an API - for building automations, dashboards, or setting alerts.

View the API definition here, or tell your coding agent to use the get-schema tool in Hud MCP - it has all the tips and tricks on how to best utilize the data.


API Key

Use the API key in Hud > Settings > API Keys link . If you don't have a key - feel free to contact Hud and we will generate one for you.


How to use the API?

View the API definition here.

Authentication: Include your API key in the x-api-key header.

Endpoint: POST https://api.hud.io/v1/query

Request body:

{
  "query": "SELECT ...",
  "environment": "production",
  "service_names": ["my-service"]
}

Example - P90 latency per endpoint, last 24 hours:

curl -X POST https://api.hud.io/v1/query \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT e.endpoint_name, SUM(m.invocations) AS requests, percentileMS(m.duration_buckets, 90) AS p90_ms FROM EndpointMetricsLowResolution m JOIN Endpoints e ON m.endpoint_id = e.endpoint_id WHERE m.hour_end >= now() - INTERVAL 24 HOUR GROUP BY e.endpoint_name, m.endpoint_id ORDER BY p90_ms DESC LIMIT 20",
    "service_names": ["my-service"]
  }'

Add a HudQL Datasource in Grafana

HudQL returns standard JSON/CSV over HTTP, so you can connect it to Grafana using the Infinity datasource plugin.

  1. Install the Infinity plugin In Grafana, go to Administration > Plugins, search for Infinity (yesoreyeram-infinity-datasource), and install it.

  2. Create a new Infinity datasource Go to Connections > Data sources > Add data source, select Infinity, and configure:

    1. Name: Hud (or any name you prefer)
    2. [](https://api.hud.io)

  3. Under Authentication select API Key Value pair, and add:

    1. Key: x-api-key
    2. Value: Your Hud API key
    3. Add to: Header


Query Hud in Grafana

After adding Hud as a datasource, you can query it by configuring the following (see screenshot bellow too).

SettingValue
TypeCSV
ParserBackend
SourceURL
URL/v1/query
MethodPOST
Body typeRaw
Body content typeJSON (application/json)

In the body, send your HudQL query. Use Grafana's built-in ${__from} and ${__to} variables for time range binding:

{
  "query": "SELECT hour_end AS time, SUM(invocations) AS requests FROM EndpointMetricsLowResolution WHERE hour_end >= toDateTime('${__from:date:YYYY-MM-DD HH:mm:ss}') AND hour_end <= toDateTime('${__to:date:YYYY-MM-DD HH:mm:ss}') GROUP BY hour_end ORDER BY time ASC LIMIT 10000",
  "service_names": ["${service_name}"]
}

Define columns in the Infinity query editor to map types correctly (e.g. timestamp - time, requests- number) Tip - Grafana template variables: You can create a dashboard variable for service_name by querying distinct service names:

{
  "query": "SELECT DISTINCT service_name FROM EndpointMetricsLowResolution WHERE hour_end >= toDateTime('${__from:date:YYYY-MM-DD HH:mm:ss}') AND hour_end <= toDateTime('${__to:date:YYYY-MM-DD HH:mm:ss}') ORDER BY service_name LIMIT 100"
}

Build a Dashboard with Hud's Data

You can use the following prompt to create a Grafana dashboard JSON:

Use the Hud MCP hud-get-schema tool to understand the full HudQL database schema — tables, columns, custom SQL functions, and query examples.

Then create a Grafana dashboard JSON using the Infinity datasource. Include $datasource and $service_name template variables.

Template variables:

// 1. Datasource selector (type: "datasource")
{ "name": "datasource", "type": "datasource", "query": "yesoreyeram-infinity-datasource" }
// 2. Service name (type: "query") — note the queryType/infinityQuery wrapper
{
  "name": "service_name",
  "type": "query",
  "datasource": { "type": "yesoreyeram-infinity-datasource", "uid": "${datasource}" },
  "query": {
    "queryType": "infinity",
    "infinityQuery": {
      "refId": "variable",
      "type": "csv", "parser": "backend", "source": "url", "format": "table",
      "url": "/v1/query",
      "url_options": {
        "method": "POST", "body_type": "raw", "body_content_type": "application/json",
        "data": "{\"query\": \"SELECT DISTINCT service_name FROM EndpointMetricsLowResolution ORDER BY service_name LIMIT 100\"}"
      },
      "columns": [{ "selector": "service_name", "text": "service_name", "type": "string" }],
      "filters": [], "root_selector": "", "global_query_id": ""
    }
  }
}

Every panel target must use this exact structure:

{
  "datasource": { "type": "yesoreyeram-infinity-datasource", "uid": "${datasource}" },
  "refId": "A",
  "type": "csv",
  "parser": "backend",
  "source": "url",
  "format": "table",
  "url": "/v1/query",
  "url_options": {
    "method": "POST",
    "body_type": "raw",
    "body_content_type": "application/json",
    "data": "{\"query\": \"SELECT ...\", \"service_names\": [\"${service_name}\"]}"
  },
  "columns": [
    { "selector": "col_alias", "text": "Display Name", "type": "timestamp|number|string" }
  ],
  "filters": [],
  "root_selector": "",
  "global_query_id": ""
}

Critical details:

- The POST body key is data, NOT body. Using body causes 400 errors.
- Every target must include filters: [], root_selector: "", global_query_id: "".
- Use "uid": "${datasource}" everywhere — never hardcode a datasource UID.
- Time range: toDateTime('${__from:date:YYYY-MM-DD HH:mm:ss}') and same for ${__to}.
- Time series: alias the time column as time. For per-endpoint series, add a partitionByValues transformation referencing the column's text (display name), with "naming": { "asLabels": true }.
- Stat panels: reduceOptions.fields as regex like /^total_requests$/, calcs: ["lastNotNull"]. Stat panel columns can be [].

Panels: Summary stats (total requests, avg latency, 5xx rate, active pods), time series (request rate, P50/P90/P99 latency), P90 per endpoint over time, and drill-down tables (top endpoints by P99, top exceptions). Use EndpointMetricsLowResolution for metrics, join Endpoints for names.


Paste the output in a new dashboard (Settings > JSON Modal).

And voilà!


Setting Up Alerts

After creating a dashboard - you can also set up alerts on some of its panels, by clicking on the 3 dots > More > New alert rule.

This enables you to configure alerts based on Hud's data, and any logic you have in mind.