PromQL HTTP API
This functionality is in technical preview and might be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
These endpoints run under the /_prometheus/ prefix.
They are intended for Prometheus-compatible tooling such as Grafana data sources, autocompletion, variable queries, and similar clients.
These APIs only consider metric data stored in time series data streams (TSDS).
Every path has two forms:
- Cluster default:
/_prometheus/api/v1/<path> - Explicit index expression:
/_prometheus/{index}/api/v1/<path>
The {index} segment is an Elasticsearch index expression (for example, metrics-generic.prometheus-*) that restricts which indices are considered in the query.
This can reduce latency on clusters that contain many large time series data streams when you query a subset of indices.
When you omit {index} in the path, qualifying indices are identified through the default index expression metrics-*.
These endpoints mirror the Prometheus range query and instant query APIs.
GET /_prometheus/api/v1/query_range
POST /_prometheus/api/v1/query_range
GET /_prometheus/{index}/api/v1/query_range
POST /_prometheus/{index}/api/v1/query_range
This endpoint evaluates a PromQL expression over a time window and returns matrix data (resultType: "matrix").
| Parameter | Required | Description |
|---|---|---|
query |
Yes | PromQL expression |
start |
Yes | Range start, Timestamp |
end |
Yes | Range end, Timestamp |
step |
Yes | Resolution between samples, Step width |
limit |
No (default: 0) |
Maximum number of series returned, limit |
The timeout, lookback_delta, and stats parameters are not supported yet (see Limitations).
GET /_prometheus/api/v1/query
POST /_prometheus/api/v1/query
GET /_prometheus/{index}/api/v1/query
POST /_prometheus/{index}/api/v1/query
This endpoint evaluates at a single instant and returns vector data (resultType: "vector").
| Parameter | Required | Description |
|---|---|---|
query |
Yes | PromQL expression |
time |
No (default: now) | Evaluation instant, Timestamp. The handler still uses an internal five-minute range ending at this time (see Limitations) |
limit |
No (default: 0) |
Maximum number of series returned, limit |
The timeout, lookback_delta, and stats parameters are not supported yet (see Limitations).
These entrypoints mirror the Prometheus metric metadata, label-name discovery, label-value queries, and series discovery by matchers APIs so UIs can browse metrics, build time series selectors, and populate template variables.
GET /_prometheus/api/v1/labels
POST /_prometheus/api/v1/labels
GET /_prometheus/{index}/api/v1/labels
POST /_prometheus/{index}/api/v1/labels
This endpoint returns sorted label names present on matching series.
match[] is not required. If you omit every match[], results are still limited to the start and end time range.
| Parameter | Required | Description |
|---|---|---|
match[] |
No (default: no selectors) | Optional repeated selectors (for example, match[]=up{job="prometheus"}). Omit all to return label names for every series in the selected time window |
start |
No (default: 24h before end) |
Start of time range, Timestamp |
end |
No (default: now) | End of time range, Timestamp |
limit |
No (default: 0) |
Maximum number of label names in the response, limit |
GET /_prometheus/api/v1/label/{name}/values
GET /_prometheus/{index}/api/v1/label/{name}/values
This endpoint returns sorted, deduplicated values for one label.
match[] is not required. If you omit every match[], results are still limited to the start and end time range.
Label names can use OpenMetrics U__ encoding for characters that are not valid in Prometheus label names. The server decodes them before matching series.
| Parameter | Required | Description |
|---|---|---|
match[] |
No (default: no selectors) | Optional repeated selectors. Same semantics as labels |
start |
No (default: 24h before end) |
Start of time range, Timestamp |
end |
No (default: now) | End of time range, Timestamp |
limit |
No (default: 0) |
Maximum number of values returned for this label, limit |
Unknown label names are returned as an empty successful result (data: []), matching typical Prometheus client expectations.
GET /_prometheus/api/v1/series
POST /_prometheus/api/v1/series
GET /_prometheus/{index}/api/v1/series
POST /_prometheus/{index}/api/v1/series
This endpoint returns the set of series matching the given selectors.
At least one match[] parameter is required.
| Parameter | Required | Description |
|---|---|---|
match[] |
Yes (at least one) | Repeated selectors |
start |
No (default: 24h before end) |
Start of time range, Timestamp |
end |
No (default: now) | End of time range, Timestamp |
limit |
No (default: 0) |
Maximum number of series in the response, limit |
GET /_prometheus/api/v1/metadata
GET /_prometheus/{index}/api/v1/metadata
This endpoint returns metric-level information such as type, help, and unit, analogous to Prometheus TYPE, HELP, and UNIT lines.
The help field is always an empty string for now (see Limitations).
| Parameter | Required | Description |
|---|---|---|
metric |
No (default: all metrics in lookback) | Restrict to a single metric name |
limit |
No (default: 0) |
Maximum number of distinct metrics in the response, limit |
limit_per_metric |
No (default: 0) |
Maximum number of metadata entries returned per metric, limit |
The metadata route does not support match[], start, or end.
Elasticsearch discovers type and unit using the ES|QL METRICS_INFO command over time series data streams (TSDS), with a fixed 24-hour lookback ending when the request runs.
Parameter encodings match the Prometheus HTTP API. See the upstream format overview.
For GET requests, send parameters in the query string.
For endpoints that support POST, send parameters in an application/x-www-form-urlencoded request body.
Do not repeat a parameter in both the URL and the form body.
Form-encoded POST requests are accepted only when security is enabled, xpack.security.http.ssl.enabled is true on the Elasticsearch HTTP interface, and the request is authenticated (not anonymous). The check uses Elasticsearch’s own HTTP TLS setting, so deployments that terminate TLS before Elasticsearch and expose plain HTTP to the node must use GET with query-string parameters instead. Unauthenticated or plain-HTTP POST requests with application/x-www-form-urlencoded bodies return HTTP 406 Not Acceptable.
Values may be an RFC 3339 timestamp or Unix time in seconds as a numeric string, with optional fractional digits for sub-second precision. This matches Prometheus request parsing. Sample timestamps inside JSON results use Unix seconds, as in Prometheus.
Each value must be URL-encoded. Syntax is the same as Prometheus time series selectors (for example, up or http_requests_total{job="api"}).
Repeatable query parameters use a [] suffix, matching Prometheus. Whether any match[] must be present is defined in each endpoint’s parameter table.
The step query parameter accepts:
- A non-negative decimal integer string: seconds between samples (for example,
15for 15s resolution). - Or Prometheus-style duration literals such as
30s,5m, or1h30m: a non-negative integer plus a unit suffix (ms,s,m,h,d,w, ory), repeated and concatenated when needed (for example,1h30m). See Prometheus float literals and time durations.
limit defaults to 0, which means no cap from the request (Prometheus-style unlimited) on routes that accept it. Elasticsearch may still truncate very large responses when enforcing esql.query.timeseries_result_truncation_max_size.
The metadata route also takes limit_per_metric with the same 0 default (no per-metric cap from the request).
Responses use JSON. Successful calls return HTTP 200 with:
{
"status": "success",
"data": { ... }
}
The data object shape depends on the route (for example, resultType and result for query / query_range).
When the limit is reached and the server detects truncation, the response might include a top-level warnings array (strings). The preview uses a fixed message such as results truncated due to limit.
Numeric sample values in query results are JSON strings (including NaN, +Inf, and -Inf), matching common Prometheus JSON encoding.
Errors return a non-2xx HTTP status and a JSON body of the form:
{
"status": "error",
"errorType": "bad_data",
"error": "<message>"
}
Client errors (HTTP 4xx) mean the request or expression is not valid for this implementation, for example, malformed parameters, parameters not supported yet on a route, invalid selectors, or PromQL that Elasticsearch does not evaluate yet (see Limitations). Those failures usually return errorType: bad_data.
Server errors (HTTP 5xx) and timeout responses reflect operational failures inside Elasticsearch. Those responses typically use errorType: timeout or execution depending on the situation.