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

# PromQL and Grafana

> Query your OpenTelemetry metrics with PromQL through a Prometheus-compatible API, and add Squasher as a Grafana data source.

Squasher answers PromQL over the metrics a project sends through OpenTelemetry. The API follows the
Prometheus HTTP API, so Grafana and other Prometheus clients can use it as a data source. You do
not run a Prometheus server.

## Endpoint and authentication

Every project has its own Prometheus base URL:

```text theme={null}
https://api.squasher.ai/v1/projects/$SQUASHER_PROJECT_ID/prometheus
```

Send an API key in `x-squasher-key: <key>` or in `Authorization: Bearer <key>`. The key needs the
`project:read` scope, which the `read` scope includes. An ingest key cannot read data. See
[API keys](https://docs.squasher.ai/api-reference/api-keys.md). A request reads only the metrics of its own project.

| Path | Methods | Parameters |
| - | - | - |
| `/api/v1/query` | GET, POST | `query`, `time`, `timeout`, `lookback_delta` |
| `/api/v1/query_range` | GET, POST | `query`, `start`, `end`, `step`, `timeout`, `lookback_delta` |
| `/api/v1/series` | GET, POST | `match[]` (required), `start`, `end`, `limit` |
| `/api/v1/labels` | GET, POST | `match[]`, `start`, `end`, `limit` |
| `/api/v1/label/{name}/values` | GET | `match[]`, `start`, `end`, `limit` |
| `/api/v1/metadata` | GET | `metric`, `start`, `end`, `limit` |

`series`, `labels`, `label/{name}/values`, and `metadata` read the last hour when you do not send
`start`. `metadata` returns the type and unit of each metric, and no help text. A POST body is a
form (`application/x-www-form-urlencoded`) of at most 64 KiB.

```bash theme={null}
curl "https://api.squasher.ai/v1/projects/$SQUASHER_PROJECT_ID/prometheus/api/v1/query_range" \
  -H "x-squasher-key: $SQUASHER_API_KEY" \
  --data-urlencode 'query=sum by (job) (rate(http_server_requests_total[5m]))' \
  --data-urlencode "start=$(date -u -v-1H +%s)" \
  --data-urlencode "end=$(date -u +%s)" \
  --data-urlencode 'step=60'
```

Answers and errors use the Prometheus JSON shape. An error has `status: "error"`, an `errorType`,
and an `error` message. The types are `bad_data` (400), `execution` (422), `timeout` (503), and
`unavailable` (503). On `unavailable`, wait and retry.

## Add Squasher to Grafana

**1. Create an API key**

Create a key with the `read` scope. See [API keys](https://docs.squasher.ai/api-reference/api-keys.md).

**2. Add a Prometheus data source**

In Grafana, add a data source of type **Prometheus**. Set the **URL** to
`https://api.squasher.ai/v1/projects/<project id>/prometheus`.

**3. Send the key**

Add a custom HTTP header named `x-squasher-key` with the API key as its value. Grafana has no
bearer token field, so use a custom header. Leave basic authentication off.

**4. Save and explore**

Save the data source, then open **Explore** and run a query with one of your metric names. The
metric browser and autocomplete list the names Squasher exposes.

Grafana can use GET or POST for queries. Both work. Features that need other Prometheus endpoints
do not work: exemplars, recording and alerting rules, and the `/api/v1/status/*` endpoints.

## Metric and label names

OpenTelemetry names are not valid in the classic Prometheus syntax, so Squasher maps them. The
rules follow the OpenTelemetry Prometheus compatibility rules, without unit suffixes.

| OpenTelemetry | Prometheus |
| - | - |
| Metric name `http.server.duration` | `http_server_duration`. Characters outside `a-z A-Z 0-9 _ :` become `_`. |
| Gauge | Gauge with the same name. |
| Monotonic sum | Counter with the suffix `_total`. A selector without `_total` matches it. |
| Non-monotonic sum | Gauge. |
| Explicit-bucket histogram | `<name>_bucket{le="..."}`, `<name>_count`, and `<name>_sum`. |
| Delta sum or histogram | Made cumulative when read. Use `rate()` or `increase()` on it. |
| Data point attribute `http.method` | Label `http_method`. Other characters become `_`, and a leading digit gets the prefix `key_`. |
| Resource `service.namespace`, `service.name` | Label `job`: `namespace/name`, or `name` when there is no namespace. |
| Resource `service.instance.id` | Label `instance`. |

Two attributes that map to the same label name join their values with `;`. Other resource
attributes are not labels, and there is no `target_info` series.

A quoted name selects the original OpenTelemetry name, in the Prometheus 3 UTF-8 syntax:

```promql theme={null}
max({"system.cpu.utilization"})
sum by (job) (rate({"http.server.requests", "http.method"="GET"}[5m]))
```

## Example queries

Metric names depend on what your services send. These examples assume `http.server.requests` is a
monotonic sum and `http.server.duration` is an explicit-bucket histogram in seconds.

```promql theme={null}
# Requests per second for each service
sum by (job) (rate(http_server_requests_total[5m]))

# 95th percentile latency for each service
histogram_quantile(0.95, sum by (le, job) (rate(http_server_duration_bucket[5m])))

# Top five instances by request rate
topk(5, sum by (instance) (rate(http_server_requests_total[5m])))
```

## Supported PromQL

* Selectors with `offset`, `@`, and subqueries. Instant selectors look back 5 minutes, as in
  Prometheus 3.
* Functions: `rate`, `irate`, `increase`, `delta`, `idelta`, `resets`, `changes`, `deriv`,
  `predict_linear`, the `*_over_time` family (`avg`, `min`, `max`, `sum`, `count`, `last`,
  `quantile`, `stddev`, `stdvar`, `present`), `absent`, `histogram_quantile`, `label_replace`,
  `label_join`, `clamp`, `round`, `sort`, `scalar`, `vector`, `time`, and the math and date
  functions.
* Aggregations: `sum`, `avg`, `min`, `max`, `count`, `group`, `stddev`, `stdvar`, `topk`,
  `bottomk`, `quantile`, and `count_values`, with `by` and `without`.
* Binary operators, comparisons with and without `bool`, `and`, `or`, `unless`, and `on`,
  `ignoring`, `group_left`, and `group_right` matching.

## Limits and unsupported items

| Limit | Value | Error |
| - | - | - |
| Raw samples a query reads | 5,000,000 | `execution` |
| Series a selector matches | 20,000 | `execution` |
| Points in each series of a range | 11,000 | `bad_data` |
| Evaluation time | 60 seconds | `timeout` |

Narrow the time range, add label matchers, or raise `step` to stay inside a limit. The `timeout`
parameter can only lower the evaluation time.

These return a `bad_data` error that says the feature is unsupported:

* Exponential histograms and the native histogram functions (`histogram_count`, `histogram_sum`,
  `histogram_fraction`, `histogram_avg`, `histogram_stddev`, `histogram_stdvar`). Send explicit-bucket
  histograms if you need them in PromQL.
* `limitk`, `limit_ratio`, `fill()` modifiers, and experimental functions such as
  `first_over_time`, `mad_over_time`, `sort_by_label`, and `info`.

The API has no exemplars, rules, alerts, or remote write endpoints. To send Prometheus metrics to
Squasher, see [Prometheus metrics](https://docs.squasher.ai/integrations/prometheus-metrics.md).

## Next steps

> [card] [Query guide and safe SQL](https://docs.squasher.ai/api-reference/query-guide.md)
>
> Run SQL over logs, spans, and metrics.

> [card] [Prometheus metrics](https://docs.squasher.ai/integrations/prometheus-metrics.md)
>
> Send Prometheus scrape data to Squasher.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.