---
title: "Panel and variable data"
description: "The panel and variable data endpoints of the HTTP API."
---

> Documentation Index
> Fetch the complete documentation index at: https://slashobserve.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Panel and variable data

## GET /dashboards/{id}/versions/{version}/panels/{panel_id}/data

Run the saved queries of one panel in one dashboard version and return their frames.

The queries are fixed by the saved version, so the request names a panel and never carries query text; the parameters `query`, `expr`, `sql` and `q` are refused with 403 `query_not_in_spec` even when their value is malformed, and any other unknown parameter or a malformed query string with 400. Each variable selection is a repeated `var-<name>` parameter, for example `var-pod=a&var-pod=b`, and the single value `$__all` selects All; OpenAPI 3.0 cannot describe a parameter family, so these are not listed below. A variable that is not given gets its default, and a request for an undeclared variable is a 400. An interval variable accepts `$__auto` when its `auto` is set, a constant accepts only its value, and a textbox accepts one value, an empty one included. An adhoc variable takes repeated `var-<name>=key|op|value` filters (at most 20) with `=`, `!=`, `=~` or `!~`, split at the first two `|`. A group by variable takes repeated `var-<name>=<label>` values (at most 20 label names), `var-<name>=` means none, and without the parameter it uses its saved `default`; its labels join every Prometheus aggregation of a query on its datasource that does not name the variable, and a value that is not a label name is a 400. `from` and `to` accept a Spec time expression such as `now-6h`, an RFC 3339 time or epoch milliseconds, default to the version's `time`, and may span at most 400 days. A range panel aligns `from` and `to` down to a multiple of the step, and an instant panel aligns `to` down to 5 seconds; the aligned range comes back in `meta`. Every query runs as a range query unless it sets `instant` or the panel is a table or logs panel. A panel's `timeFrom` replaces the range with the last N units up to now, and `timeShift` moves the range back; `meta.from` and `meta.to` report the range that ran. Every visible query of the panel runs in this one request (at most 4 at a time), and each frame carries the `ref` of the query that produced it; a hidden query does not run. The panel's `maxDataPoints` caps `max_data_points`, and a query's or the panel's `interval` is the minimum step of a range query. A failing query fails the whole request, and the error names it in `ref`. Successful results are cached in the server for 10 seconds, and each caller may have at most 8 query requests in flight.

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `id` (required) | path | `string` (uuid) |   |
| `version` (required) | path | `integer` | Between 1 and 2147483647. |
| `panel_id` (required) | path | `string` |   |
| `from` | query | `string` |   |
| `to` | query | `string` |   |
| `tz` | query | `string` | The browser's IANA time zone, such as `Asia/Kolkata`. Relative times resolve in it when the dashboard's `timezone` is `browser`, and it is ignored otherwise. An unknown zone is a 400 `invalid_request`. |
| `max_data_points` | query | `integer` | Between 10 and 11000. Default `1000`. |

### Responses

| Status | Description | Body |
| --- | --- | --- |
| `200` | The frames the saved queries returned, an empty list when the result is empty or every query is hidden. | [`PanelData`](/docs/reference/api/schemas/#paneldata) |
| `400` | The request is malformed or fails validation, for example an undeclared variable or an invalid variable selection. | [`PanelDataError`](/docs/reference/api/schemas/#paneldataerror) |
| `401` | Authentication is missing or invalid. | [`Error`](/docs/reference/api/schemas/#error) |
| `403` | The request carried query text; the code is `query_not_in_spec`. | [`Error`](/docs/reference/api/schemas/#error) |
| `404` | The dashboard or version does not exist (`not_found`), or the version has no such panel (`panel_not_found`). | [`PanelDataError`](/docs/reference/api/schemas/#paneldataerror) |
| `422` | A query or a variable cannot run: `query_invalid`, `query_forbidden`, `limit_exceeded` (also for a response over 32 MiB), `unknown_datasource`, `variable_empty` or `expression_error` (an expression query failed or one of its inputs did). | [`PanelDataError`](/docs/reference/api/schemas/#paneldataerror) |
| `429` | The caller already has the maximum number of query requests in flight, or the server's shared upstream call slots stayed busy for 5 seconds. | [`Error`](/docs/reference/api/schemas/#error) |
| `500` | The server failed to handle the request, including a datasource call that failed without a classified cause. | [`PanelDataError`](/docs/reference/api/schemas/#paneldataerror) |
| `502` | A datasource is unavailable. | [`PanelDataError`](/docs/reference/api/schemas/#paneldataerror) |
| `504` | A datasource did not answer within the query timeout, or the panel's queries did not all finish within 55 seconds; `ref` names the lowest-index query that failed. | [`PanelDataError`](/docs/reference/api/schemas/#paneldataerror) |

## GET /dashboards/{id}/versions/{version}/variables/{name}/values

List the values of one variable in one dashboard version.

A custom variable returns its options without an upstream call. A constant returns its value, an interval variable its options with `$__auto` first when `auto` is set, and a datasource variable the uids of the configured datasources of its type; a textbox variable lists nothing, and an adhoc or group by variable has no list, so asking for it is a 400. A query variable runs its saved query with the selections of the variables declared before it, given as repeated `var-<name>` parameters (not listed below, see the panel data operation); an earlier variable without a selection gets its default, and a selection for the listed variable or a later one is a 400. `from` and `to` behave as for panel data, and the range is aligned like the default range of a range panel. The same query-text refusal and in-flight limit apply.

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `id` (required) | path | `string` (uuid) |   |
| `version` (required) | path | `integer` | Between 1 and 2147483647. |
| `name` (required) | path | `string` |   |
| `from` | query | `string` |   |
| `to` | query | `string` |   |
| `tz` | query | `string` | The browser's IANA time zone, such as `Asia/Kolkata`. Relative times resolve in it when the dashboard's `timezone` is `browser`, and it is ignored otherwise. An unknown zone is a 400 `invalid_request`. |

### Responses

| Status | Description | Body |
| --- | --- | --- |
| `200` | Up to 1000 values; `truncated` is true when there were more. | [`VariableValues`](/docs/reference/api/schemas/#variablevalues) |
| `400` | The request is malformed or fails validation. | [`Error`](/docs/reference/api/schemas/#error) |
| `401` | Authentication is missing or invalid. | [`Error`](/docs/reference/api/schemas/#error) |
| `403` | The request carried query text; the code is `query_not_in_spec`. | [`Error`](/docs/reference/api/schemas/#error) |
| `404` | The resource does not exist. | [`Error`](/docs/reference/api/schemas/#error) |
| `422` | The query or its variables cannot run, or its result exceeds a limit. | [`Error`](/docs/reference/api/schemas/#error) |
| `429` | The caller already has the maximum number of query requests in flight, or the server's shared upstream call slots stayed busy for 5 seconds. | [`Error`](/docs/reference/api/schemas/#error) |
| `500` | The server failed to handle the request. | [`Error`](/docs/reference/api/schemas/#error) |
| `502` | The datasource is unavailable. | [`Error`](/docs/reference/api/schemas/#error) |
| `504` | The datasource did not answer within the query timeout. | [`Error`](/docs/reference/api/schemas/#error) |

## POST /datasources/{uid}/lint

Parse a query for a datasource and return diagnostics, without executing it or returning data.

Prometheus queries are parsed and checked for metric names that do not exist; ClickHouse queries are checked with `EXPLAIN SYNTAX`. The call times out after 5 seconds, counts against the same in-flight limit as panel data, and takes one of the server's shared upstream slots, waiting at most 5 seconds for one before answering 429. When the datasource cannot be reached the call answers 502 or 504 instead of a diagnostic. A query over 64 KiB is refused with 400 `query_too_long`, and a body over 512 KiB with 413 `too_large`.

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `uid` (required) | path | `string` |   |

### Request body

`application/json`, required.

| Field | Type | Description |
| --- | --- | --- |
| `query` (required) | `string` |   |

### Responses

| Status | Description | Body |
| --- | --- | --- |
| `200` | The diagnostics, empty when the query is clean. | [`LintResult`](/docs/reference/api/schemas/#lintresult) |
| `400` | The request is malformed or fails validation. | [`Error`](/docs/reference/api/schemas/#error) |
| `401` | Authentication is missing or invalid. | [`Error`](/docs/reference/api/schemas/#error) |
| `404` | The resource does not exist. | [`Error`](/docs/reference/api/schemas/#error) |
| `413` | The request body exceeds the size limit. | [`Error`](/docs/reference/api/schemas/#error) |
| `429` | The caller already has the maximum number of query requests in flight, or the server's shared upstream call slots stayed busy for 5 seconds. | [`Error`](/docs/reference/api/schemas/#error) |
| `500` | The server failed to handle the request. | [`Error`](/docs/reference/api/schemas/#error) |
| `502` | The datasource is unavailable. | [`Error`](/docs/reference/api/schemas/#error) |
| `504` | The datasource did not answer within the query timeout. | [`Error`](/docs/reference/api/schemas/#error) |

Generated from [`api/openapi.yaml`](https://github.com/slashobserve/slashobserve/blob/bac0fe39/api/openapi.yaml) at `bac0fe39`. [Report a problem](https://github.com/slashobserve/slashobserve/issues/new).
