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

# Telemetry API

> Query traces, logs, and usage metrics through one endpoint: latency, cost, and output throughput in one response shape per source.

See [HTTP URLs and authentication](/docs/reference/base-urls.md) and the API reference for complete request and response formats.

The **Telemetry API** answers usage, cost, latency, trace, and log questions from one endpoint. Every request names a `source`, a time range, and one or more `compute` entries, and every source answers with the same row shape.

> [!NOTE]
>
> The **Telemetry API** is the recommended query surface for new integrations: one envelope covers usage metrics, trace aggregates, and logs. The [Reporting API](/docs/ai-studio/observability/reporting-api.md) is deprecated in its favor. The trace aggregate endpoints remain supported for existing callers.

> [card] [Usage and cost](#examples-by-use-case)
>
> Group genai metrics by model, provider, project, agent, or tool.

> [card] [Trace aggregates](#sources-and-metrics)
>
> Count traces and spans, and take latency percentiles or token and cost totals.

> [card] [Log volume](#sources-and-metrics)
>
> Count log records and error records, grouped by severity or service.

> [card] [Discover the surface](#discover-what-is-available)
>
> List the metrics, operations, and dimensions the caller can reach.

## Endpoint

POST `https://router.toqan.ai/eu/v3/telemetry/query`

* All requests require a `Bearer` token. See API Keys for how to generate one.
* The workspace and project scope come from the API key.

> [card] [Query telemetry](/docs/reference/telemetry/query-telemetry.md)
>
> Full schema for `POST /v3/telemetry/query`.

> [card] [List capabilities](/docs/reference/telemetry/list-telemetry-capabilities.md)
>
> `GET /v3/telemetry/capabilities`.

> [card] [List facet values](/docs/reference/telemetry/list-telemetry-facet-values.md)
>
> `POST /v3/telemetry/facet-values`.

## Quickstart

Count requests per model over the last day:

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\",\"from\": \"$FROM\",\"to\": \"$TO\",\"compute\": [{\"metric\": \"genai.requests\", \"op\": \"count\"}],\"grain\": \"hour\",\"group_by\": [\"model\"]}"
```

## Request

| Field | Type | Description |
| - | - | - |
| `source` | string | `TELEMETRY_SOURCE_TRACES`, `TELEMETRY_SOURCE_METRICS`, or `TELEMETRY_SOURCE_LOGS`. Required. |
| `compute` | array | One to ten `{ "metric": "…", "op": "…" }` entries. Required. |
| `from`, `to` | timestamp | RFC 3339 bounds. `from` is inclusive and `to` is exclusive on the traces and logs sources; the metrics source includes a data point recorded exactly at `to`. Required. |
| `grain` | string | `none`, `auto`, `minute`, `hour`, or `day`. `none` and an omitted field return one row per group instead of a time series. |
| `interval_seconds` | integer | Explicit bucket width, 1 to 86400, taking precedence over `grain`. Supported on raw trace metrics, span metrics and the metrics source. Rejected for genai metrics, which take `grain`, and ignored on the logs source. |
| `mode` | string | `timeseries` buckets by grain; `scalar` returns one row per group. Omitted, the grain selects the shape. A grouped scalar genai query accepts exactly one `compute` entry. |
| `group_by` | array | Up to five dimensions to break the rows down by. |
| `filters` | array | Up to twenty `{ "field": "…", "op": "…", "values": ["…"] }` entries. |
| `filter_operator` | string | `and` or `or` between filters. Defaults to `and`. |
| `query` | string | Free-text search, up to 512 characters, matched like the trace list search: trace, session and thread IDs, plus span names, span IDs, models, providers, agent names and tool names. Traces source with raw trace metrics only; rejected for genai metrics and other sources. |
| `oql` | string | [OQL](/docs/ai-studio/observability/oql.md) trace selection (`fetch traces \| …`), up to 4096 characters, compiled to filters. Traces source with raw trace metrics only. Cannot be combined with `filters` or `query`. |
| `sort` | string | `desc` or `asc` for scalar and top-list rows. Defaults to `desc`. |
| `limit` | integer | Scalar queries: maximum rows, default 100. Time-series queries: maximum distinct groups, and exceeding it fails the query instead of truncating timelines. |
| `time_zone` | string | Places bucket boundaries in the zone for genai and span metrics. Every other source buckets in UTC and returns a `meta.warnings` entry when a zone other than `UTC` is sent. |
| `include_totals` | boolean | Adds a `totals` row covering the whole window. |
| `selected_range_seconds` | integer | The span the client originally selected, so `grain: "auto"` stays stable while a live window grows. Read by raw trace metrics and span metrics only; every other source resolves the bucket from `from` and `to` alone. |

`auto` resolves the bucket width from the requested range, and the ladder depends on the source:

| Source | `auto` ladder |
| - | - |
| traces, raw trace metrics | 1s up to 5 minutes, 5s up to 15 minutes, 15s up to 30 minutes, 30s up to an hour, then minute, 5m, 10m, 2h, 6h, 12h and day |
| traces, genai metrics | `minute` up to 6 hours, `hour` up to 7 days, `day` beyond |
| metrics | `minute` up to 48 hours, `hour` up to 14 days, `day` beyond |
| logs | `minute` up to 6 hours, `hour` up to 7 days, `day` beyond |

## Response

Every source answers with the same envelope:

```json Envelope theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "object": "telemetry.query",
  "request": { },
  "data": [
    {
      "timestamp": "2026-05-01T00:00:00Z",
      "group": { "model": "openai/gpt-5.4-mini" },
      "metrics": { "trace_count:count": 128 }
    }
  ],
  "totals": {
    "group": { },
    "metrics": { "trace_count:count": 4021 }
  },
  "meta": {
    "effective_grain": "hour",
    "warnings": [],
    "row_count": 24,
    "request_id": "req_...",
    "currency": ""
  },
  "has_more": false
}
```

* `metrics` keys are the requested metric and operation joined by a colon, for example `trace_count:count` or `genai.cost:sum`.
* `timestamp` is present on bucketed rows only.
* `totals` appears only when the request sets `include_totals: true`, and carries no timestamp and an empty `group`.
* `meta.effective_grain` reports the bucket actually applied, including widths `interval_seconds` or `auto` resolved to. `meta.currency` is `USD` only when every `compute` entry is `genai.cost`, and empty on every other query.
* `meta.warnings` explains a value the source ignored, for example a `time_zone` sent to a source that buckets in UTC.

## Sources and metrics

`TELEMETRY_SOURCE_TRACES` covers raw trace aggregates, the genai usage metrics and span metrics. The three cannot be mixed in one request.

Span metrics (`gen_ai.*` and `orq.gen_ai.*`) are computed per LLM request span. They honor `time_zone` and accept several computes on a grouped scalar query, sorted by the first one.

| Metric | Operations | Source |
| - | - | - |
| `trace_count` | `count` | traces |
| `span_count` | `count` | traces |
| `duration_ms` | `avg`, `p50`, `p95`, `p99`, `min`, `max` | traces |
| `tokens.total`, `tokens.prompt`, `tokens.completion` | `sum`, `avg` on the total; `sum` on the breakdowns | traces |
| `cost.total`, `cost.input`, `cost.output` | `sum`, `avg` on the total; `sum` on the breakdowns | traces |
| `error_count` | `count` | traces |
| `error_rate` | `ratio` | traces |
| `genai.requests` | `count` | traces |
| `genai.tokens` | `sum` | traces |
| `genai.cost` | `sum` | traces |
| `genai.errors` | `count` | traces |
| `genai.error_rate` | `rate` | traces |
| `genai.latency.avg` | `avg` | traces |
| `genai.latency.p50`, `genai.latency.p90`, `genai.latency.p95`, `genai.latency.p99` | `p50`, `p90`, `p95`, `p99`, one per metric | traces |
| `genai.ttft.runs` | `count` | traces |
| `genai.ttft.avg` | `avg` | traces |
| `genai.ttft.p50`, `genai.ttft.p90`, `genai.ttft.p95`, `genai.ttft.p99` | `p50`, `p90`, `p95`, `p99`, one per metric | traces |
| `genai.tokens.input`, `genai.tokens.output`, `genai.tokens.cached`, `genai.tokens.reasoning` | `sum` | traces |
| `genai.cost.input`, `genai.cost.output`, `genai.cost.cache_read`, `genai.cost.cache_write`, `genai.cost.web_search` | `sum` | traces |
| `genai.cache_hit_rate` | `rate` | traces |
| `genai.blended_cost_per_mtok` | `avg` | traces |
| `genai.evaluator.runs`, `genai.evaluator.errors`, `genai.guardrail.runs`, `genai.guardrail.triggered` | `count` | traces |
| `genai.evaluator.pass_rate`, `genai.evaluator.fail_rate`, `genai.evaluator.error_rate`, `genai.guardrail.block_rate` | `rate` | traces |
| `genai.evaluator.score.avg` | `avg` | traces |
| `gen_ai.client.inference.duration`, `gen_ai.client.inference.time_to_first_chunk`, `gen_ai.server.time_per_output_token`, `orq.gen_ai.generation.duration` (seconds), `orq.gen_ai.output_throughput` (tokens per second) | `avg`, `p50`, `p90`, `p95`, `p99`, `min`, `max` | traces |
| `orq.gen_ai.requests`, `orq.gen_ai.errors`, `orq.gen_ai.response_cache.hits` | `count` | traces |
| `orq.gen_ai.error_rate`, `orq.gen_ai.cache_hit_rate`, `orq.gen_ai.blended_cost_per_mtok`, `orq.gen_ai.response_cache.hit_rate` | `ratio` | traces |
| `gen_ai.client.inference.usage.input_tokens`, `gen_ai.client.inference.usage.output_tokens`, `gen_ai.client.inference.usage.reasoning.output_tokens`, `gen_ai.client.inference.usage.cache_read.input_tokens`, `gen_ai.client.inference.usage.cache_write.input_tokens`, `orq.gen_ai.usage.total_tokens` | `sum`, `avg`, `p50`, `p90`, `p95`, `p99` | traces |
| `orq.gen_ai.cost`, `orq.gen_ai.cost.input`, `orq.gen_ai.cost.output`, `orq.gen_ai.cost.cache_read`, `orq.gen_ai.cost.cache_write`, `orq.gen_ai.cost.reasoning`, `orq.gen_ai.cost.web_search` | `sum`, `avg` | traces |
| `log_count` | `count` | logs |
| `error_count`, `error_rate` | `count`, `ratio` | logs |

`TELEMETRY_SOURCE_METRICS` covers the custom metrics registered in the workspace. `TELEMETRY_SOURCE_LOGS` covers log records only.

`genai.usage` is a bundle: request it with `op: "bundle"`, and it answers every field in one row under `genai.usage:<field>` keys. Its fields are not queryable metrics on their own, and the compute cannot be mixed with any other in one request.

## Discover what is available

Capabilities list what a key can reach, so a client never hard-codes the vocabulary:

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl "https://router.toqan.ai/eu/v3/telemetry/capabilities?source=TELEMETRY_SOURCE_TRACES" \
  -H "Authorization: Bearer $TOQAN_API_KEY"
```

Each metric entry carries its label, unit, operations, default operation, query modes, result kinds, and the dimensions it can group by, including whether each dimension is groupable and which filter operators it accepts.

Facet values list the distinct values a field takes in the workspace, so a filter can be built from real data. Only the traces source is supported: the metrics and logs sources answer `501`.

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM=$(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "7 days ago" +%Y-%m-%dT%H:%M:%SZ)
TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
curl -X POST "https://router.toqan.ai/eu/v3/telemetry/facet-values" \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\",\"metric\": \"trace_count\",\"field\": \"model\",\"from\": \"$FROM\",\"to\": \"$TO\"}"
```

## Examples by use case

> [accordion] Spend: cost by model
>
> `genai.cost` sums what the window recorded, `group_by` splits it per model, and `include_totals` adds the window total:
>
> ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
> {
>   "source": "TELEMETRY_SOURCE_TRACES",
>   "from": "2026-05-01T00:00:00Z",
>   "to": "2026-05-08T00:00:00Z",
>   "compute": [{ "metric": "genai.cost", "op": "sum" }],
>   "grain": "day",
>   "group_by": ["model"],
>   "include_totals": true
> }
> ```

> [accordion] Errors: failing traces by Agent
>
> Count only the failing traces. `status` takes `ok`, `error`, or `unset`:
>
> ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
> {
>   "source": "TELEMETRY_SOURCE_TRACES",
>   "from": "2026-05-01T00:00:00Z",
>   "to": "2026-05-08T00:00:00Z",
>   "compute": [{ "metric": "trace_count", "op": "count" }],
>   "grain": "day",
>   "group_by": ["agent_name"],
>   "filters": [{ "field": "status", "op": "eq", "values": ["error"] }]
> }
> ```

> [accordion] Latency: p95 by Tool
>
> A scalar top list: no grain, one row per tool, ordered by the metric:
>
> ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
> {
>   "source": "TELEMETRY_SOURCE_TRACES",
>   "from": "2026-05-01T00:00:00Z",
>   "to": "2026-05-08T00:00:00Z",
>   "compute": [{ "metric": "duration_ms", "op": "p95" }],
>   "mode": "scalar",
>   "group_by": ["tool_name"],
>   "sort": "desc",
>   "limit": 10
> }
> ```

> [accordion] Logs: volume by severity
>
> The logs source groups by the OpenTelemetry fields it stores, and `severity_text` carries values such as `INFO`, `WARN`, or `ERROR`:
>
> ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
> {
>   "source": "TELEMETRY_SOURCE_LOGS",
>   "from": "2026-05-01T00:00:00Z",
>   "to": "2026-05-02T00:00:00Z",
>   "compute": [{ "metric": "log_count", "op": "count" }],
>   "grain": "hour",
>   "group_by": ["severity_text"]
> }
> ```

> [accordion] Spend: cost by day (bundle)
>
> Get request count, tokens, and cost in one call. Best for headline dashboards.
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.usage\", \"op\": \"bundle\"}], \"grain\": \"day\", \"include_totals\": true}"
> ```

> [accordion] Spend: cost by model per hour
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"hour\", \"group_by\": [\"model\"]}"
> ```

> [accordion] Spend: BYOK vs Toqan Router-managed credentials
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"group_by\": [\"credential_type\"]}"
> ```
>
> The response carries `group.credential_type` as `"orq_managed"` or `"customer_byok"`.

> [accordion] Entity dimension: cost by Agent
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"group_by\": [\"agent\"]}"
> ```

> [accordion] Entity dimension: cost by Tool with model filter
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"group_by\": [\"tool\"], \"filters\": [{\"field\": \"model\", \"op\": \"in\", \"values\": [\"openai/gpt-5.6-sol\", \"openai/gpt-5.4-mini\"]}]}"
> ```

> [accordion] Latency: p95 by model
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.latency.p95\", \"op\": \"p95\"}], \"grain\": \"hour\", \"group_by\": [\"model\"]}"
> ```
>
> The `genai.latency.p95:p95` key is reported in milliseconds.

> [accordion] Latency: p50, p95, p99 in parallel
>
> Each quantile is its own call. Fire three requests concurrently when all three are needed.
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> for pair in genai.latency.p50:p50 genai.latency.p95:p95 genai.latency.p99:p99; do
>   curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>     -H "Authorization: Bearer $TOQAN_API_KEY" \
>     -H "Content-Type: application/json" \
>     -d "{\"source\":\"TELEMETRY_SOURCE_TRACES\",\"from\":\"$FROM\",\"to\":\"$TO\",\"compute\":[{\"metric\":\"${pair%%:*}\",\"op\":\"${pair##*:}\"}],\"grain\":\"hour\"}" &
> done
> wait
> ```

> [accordion] Errors: count by provider
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.errors\", \"op\": \"count\"}], \"grain\": \"hour\", \"group_by\": [\"provider\"]}"
> ```

> [accordion] Errors: error rate by model (client-side ratio)
>
> Fetch requests and errors in parallel and divide on the client.
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" -H "Authorization: Bearer $TOQAN_API_KEY" -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.requests\", \"op\": \"count\"}], \"grain\": \"hour\", \"group_by\": [\"model\"]}" &
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" -H "Authorization: Bearer $TOQAN_API_KEY" -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.errors\", \"op\": \"count\"}], \"grain\": \"hour\", \"group_by\": [\"model\"]}" &
> wait
> ```

> [accordion] Evaluator: pass rate by Evaluator and version
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.evaluator.pass_rate\", \"op\": \"rate\"}], \"grain\": \"day\", \"group_by\": [\"evaluator\", \"evaluator_version\"]}"
> ```

> [accordion] Evaluator: average score
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.evaluator.score.avg\", \"op\": \"avg\"}], \"grain\": \"day\", \"group_by\": [\"evaluator\"]}"
> ```

> [accordion] Evaluator: runs by result label
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.evaluator.runs\", \"op\": \"count\"}], \"grain\": \"day\", \"group_by\": [\"evaluator\", \"result_label\"]}"
> ```

> [accordion] Guardrail: block rate by Evaluator and stage
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.guardrail.block_rate\", \"op\": \"rate\"}], \"grain\": \"day\", \"group_by\": [\"evaluator\", \"evaluation_stage\"]}"
> ```

> [accordion] Guardrail: triggers by Policy and stage
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.guardrail.triggered\", \"op\": \"count\"}], \"grain\": \"day\", \"group_by\": [\"policy\", \"guardrail_stage\"]}"
> ```

> [accordion] Guardrail: filter by origin
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.guardrail.runs\", \"op\": \"count\"}], \"grain\": \"day\", \"group_by\": [\"evaluator\"], \"filters\": [{\"field\": \"guardrail_origin\", \"op\": \"eq\", \"values\": [\"rule\"]}]}"
> ```

> [accordion] Multi-tenant: cost per project per day
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"group_by\": [\"project\"]}"
> ```

> [accordion] Multi-tenant: usage per API key
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.usage\", \"op\": \"bundle\"}], \"grain\": \"day\", \"group_by\": [\"api_key\"], \"include_totals\": true}"
> ```

> [accordion] Identity: cost per end-user Identity
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"group_by\": [\"identity\"]}"
> ```

> [accordion] Identity: requests filtered to a single end-user
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.requests\", \"op\": \"count\"}], \"grain\": \"day\", \"filters\": [{\"field\": \"identity\", \"op\": \"eq\", \"values\": [\"user_42\"]}]}"
> ```

> [accordion] Time zone: day buckets in America/New\_York
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"time_zone\": \"America/New_York\"}"
> ```
>
> Bucket boundaries align to midnight in the requested zone.

> [accordion] High resolution: requests per minute, last hour
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 hour ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.requests\", \"op\": \"count\"}], \"grain\": \"minute\"}"
> ```

> [accordion] Cross-dimension: cost by credential type and model
>
> ```bash wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
> FROM=$(date -u -v-1d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "1 day ago" +%Y-%m-%dT%H:%M:%SZ)
> TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
> curl -X POST "https://router.toqan.ai/eu/v3/telemetry/query" \
>   -H "Authorization: Bearer $TOQAN_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d "{\"source\": \"TELEMETRY_SOURCE_TRACES\", \"from\": \"$FROM\", \"to\": \"$TO\", \"compute\": [{\"metric\": \"genai.cost\", \"op\": \"sum\"}], \"grain\": \"day\", \"group_by\": [\"credential_type\", \"model\"]}"
> ```

The same shape answers the entity questions: swap `group_by` for `provider`, `product`, `base_model`, `project_id`, `tool_name`, or `agent_name` on traces, `service_name` or `host_name` on logs, and `agent`, `tool`, or `project` on the genai usage metrics. The ttft, evaluator, and guardrail metrics accept no entity dimension beyond `project`. Dynamic dimensions are addressable by prefix: `attributes.*` and `metadata.*` on traces, `attribute.*`, `resource.*`, and `scope.*` on logs.

## Trace status values

Each surface names the same two outcomes differently. `unset` is a trace that finished without an error status, and the Traces view counts it as successful.

| Outcome | OQL and Traces filters | Telemetry API `status` | Reporting `status_code` |
| - | - | - | - |
| Success | `success` | `ok`, `unset` | `OK` |
| Error | `error` | `error` | `ERROR` |

## Errors

A rejected query returns a JSON envelope with a numeric `code`, a human-readable `message`, and a `details` array (the 401 and 403 responses carry `code` and `message` only):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "code": 3,
  "message": "invalid filter: unsupported aggregate op \"sum\" for metric \"trace_count\"",
  "details": []
}
```

| HTTP | Code | Reason |
| - | - | - |
| 400 | 3 | Unknown metric, an operation the metric does not accept, a dimension that cannot be grouped, genai and raw computes in one request, more than one compute on a grouped scalar genai query, `interval_seconds` on a genai metric, an unusable `time_zone`, a `minute` or `hour` grain past its rollup retention, or a query that exceeds a budget. |
| 501 | 12 | Facet values requested for a source other than traces. |
| 401 | 16 | Missing or forged bearer token. |
| 403 | 7 | API key lacks the domain behind the requested source: `traces-read`, `reporting-read`, or `logs-read`. |
| 415 | 3 | Request body is not JSON. |
| 500 | 13 | Unexpected backend failure. Contact support if it persists. |

> [!TIP]
>
> Every successful query response includes `meta.request_id`. Include it in support tickets for fast log correlation.

Budget rejections carry an `ErrorInfo` detail naming the resource that ran out (`range_days`, `buckets`, `rows`, `series`, or `metric_values`) and its limit; on every source except genai metrics, a bucket overflow also reports the amount required.

## Limits

| Limit | Value |
| - | - |
| Query window | 90 days; every source except raw trace metrics also honours the workspace retention period. On genai metrics an explicit `minute` grain also requires `from` within 14 days, and `hour` within 90 days |
| `compute` entries | 10 |
| `group_by` | 5 dimensions |
| `filters` | 20 entries, 100 values each |
| `limit` | 5000 (default 100) |
| Time-series result | 5000 rows, 5000 buckets, 50000 metric values |
| `interval_seconds` | 1 to 86400 |
| Execution | 30 seconds |


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