Skip to main content
This page is a private readiness artifact. POST /v3/telemetry/query is retained for internal consumers but is intentionally absent from the public OpenAPI, Mintlify navigation, and released SDKs until the live readiness checks in ADR 0004 pass. POST /v2/reporting and POST /v3/traces/aggregate remain supported public APIs.
The private POST /v2/telemetry/query route is a compatibility alias for already-deployed internal callers. New integrations use the canonical v3 route shown below. QueryTelemetry provides one bounded request and response shape for trace aggregates, registered OTLP metrics, and log aggregates. The source selects the planner; it never accepts table names, SQL, or arbitrary expressions.

Endpoint and permissions

Permissions are selected from the request instead of using one new broad permission: A restricted key with the wrong source permission receives HTTP 403. Missing authentication receives HTTP 401. Authorization is checked before planner execution.

Request schema

Filter operations use eq, neq, in, not_in, gt, gte, lt, lte, between, contains, exists, and not_exists. Each source exposes a smaller field/op allowlist. Reporting presets retain their existing eq/neq/in/not_in behavior rather than accepting a filter the public Reporting API would reject.

Metric and operation discovery

Discovery remains source-owned because a single static list would be wrong for workspace-registered metrics: Reporting preset operations are canonical: for example genai.cost:sum, genai.latency.p95:p95, and genai.error_rate:rate. genai.usage:bundle returns all usage sub-fields with keys such as genai.usage:request_count, genai.usage:total_tokens, and genai.usage:total_cost. Registered metrics can advertise sum, avg, count, min, max, increase, rate, and p50/p90/p95/p99. The registry decides which operations are legal for a particular metric. Cumulative monotonic counters use reset-safe deltas from raw points; histogram quantiles merge bucket vectors before interpolation.

Response schema

timestamp is omitted for scalar rows. group is empty for an ungrouped row. Metric map keys use <metric>:<op> so two operations cannot collide. Bundle presets use <bundle>:<field>. has_more is always false in this version; lower the requested limit or time range instead of expecting a page token.

Examples

Reporting-compatible grouped scalar

Grouped trace time series

Registered metric with an OR filter group

The server compiles the last two filters as a nested OR group and separately ANDs the authenticated workspace condition. Client filters can never make the tenant predicate optional.

Compatibility and migration

No migration is required while this endpoint is private. Reporting presets cannot be mixed with trace aggregates in one request. A mixed request returns HTTP 400. Scalar/top-list sorting also accepts one compute only, avoiding an ambiguous sort key.

Errors and limitations

Current limitations:
  • no cursor pagination; has_more remains false;
  • no raw SQL or arbitrary metric expressions;
  • metrics, logs, and trace aggregates use UTC buckets;
  • grouped time series return observed group/bucket rows and do not synthesize every missing group/bucket combination;
  • the legacy /v2/analytics/metrics/:name/query response remains unchanged and still rejects interval plus group_by; grouped metric series use this neutral envelope;
  • publication, SDK generation, and migration guidance remain blocked on the deployed-ingress and restricted-key readiness suite.