Skip to main content
Query AI usage, cost, latency, Evaluator outcomes, and guardrail metrics programmatically. The Reporting API returns time-series data sliced by model, provider, project, identity, and more in a single JSON request.

Spend dashboards

Track cost by model, provider, project, or credential type. Build per-customer billing breakdowns.

Performance monitoring

Monitor p50, p95, and p99 latency over time across models and providers.

Evaluator quality

Quantify pass rate, average score, and result distribution per Evaluator and version.

Guardrail enforcement

Measure block rate, triggers, and outcomes by Policy and stage.

Endpoint

POST https://api.orq.ai/v2/reporting
  • All requests require a Bearer token. See API Keys for how to generate one.
  • The workspace and project scope are derived from the API key itself.
Trace events flow into reporting in near real time, with a small ingestion delay measured in seconds. Queries against very recent windows may not yet include the latest events.

See the API Reference

Interactive playground and full schema for POST /v2/reporting.

Quickstart

curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.usage",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["model"],
    "include_totals": true
  }'

Request

The wire format is snake_case end-to-end. SDKs expose the same fields in each language’s native style (groupBy in TypeScript, group_by in Python).
{
  "metric": "genai.usage",
  "from": "2026-05-01T00:00:00Z",
  "to": "2026-05-15T00:00:00Z",
  "grain": "day",
  "group_by": ["model", "provider"],
  "filters": [
    { "field": "project", "op": "eq", "values": ["proj_123"] }
  ],
  "include_totals": true,
  "limit": 1000,
  "time_zone": "UTC"
}
See the API reference for the full field schema, types, defaults, and validation rules.

Response

Every successful response follows the same envelope. The data array contains time-ordered buckets. Each bucket carries:
  • a dimensions map: the group_by values for that row (see Dimensions)
  • a metrics map: shape depends on the metric requested
Scalar metrics return a single named value per bucket. Bundle metrics (such as genai.usage) return a full set of related fields in one call. totals is present only when include_totals: true is set in the request; otherwise the field is omitted. Metric values are rounded to 10 decimal places server-side.
{
  "object": "report",
  "request": { },
  "data": [
    {
      "timestamp": "2026-05-01T00:00:00Z",
      "dimensions": { "model": "gpt-4o-mini", "provider": "openai" },
      "metrics": { }
    }
  ],
  "totals": {
    "metrics": { }
  },
  "has_more": false,
  "meta": {
    "effective_grain": "day",
    "row_count": 14,
    "request_id": "req_...",
    "currency": "USD"
  }
}

Metric catalog

MetricDescription
genai.requestsNumber of LLM requests
genai.tokensTotal tokens (input + output)
genai.costTotal cost in USD
genai.errorsNumber of failed requests
genai.latency.p50Median request latency (ms)
genai.latency.p9595th percentile latency (ms)
genai.latency.p9999th percentile latency (ms)
genai.usageBundle of request, token, and cost fields
Quantile metrics (genai.latency.p*) carry a +/-1-2% error band typical of t-digest estimation at high cardinality.
Evaluator and guardrail metrics read from the same source: every Evaluator run is recorded as a guardrail check regardless of the Evaluator implementation type. Pick the metric that matches the question being asked.

Dimensions

The API picks the right index for the query automatically. Asking for an entity dimension (agent, tool, tag, and so on) on a usage metric routes the query through entity attribution; everything else stays on the core usage path.
billing_billable is available as a filter field for usage metrics, but not as a group_by dimension. To break down Orq.ai-managed versus customer-owned credentials, use credential_type instead. The values orq_managed and customer_byok are derived at query time from the workspace billing setup, not stored on each event.
Pair these with genai.requests, genai.tokens, genai.cost, genai.errors, genai.latency.*, or genai.usage.
DimensionNotes
projectWorkspace project the request is attributed to
identityEnd-user identifier from Identities
providerFor example, openai, anthropic
modelFor example, gpt-4o-mini
productWhich Orq.ai product surface served the request
api_keyAPI key used to authenticate the request
status_codeHigh-level status (OK, ERROR)
http_status_codeHTTP status from the upstream model
credential_typeorq_managed (Orq.ai-managed keys) or customer_byok (customer BYOK keys)

Examples by use case

Get request count, tokens, and cost in one call. Best for headline dashboards.
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.usage",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "include_totals": true
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-13T00:00:00Z",
    "to":   "2026-05-14T00:00:00Z",
    "grain": "hour",
    "group_by": ["model"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-04-15T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["credential_type"]
  }'
The response carries dimensions.credential_type as "orq_managed" or "customer_byok".
Grouping by an entity auto-routes the query to attribution storage.
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["agent"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.tokens",
    "from": "2026-04-15T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["tag"],
    "filters": [
      { "field": "project", "op": "eq", "values": ["proj_123"] }
    ]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["tool"],
    "filters": [
      { "field": "model", "op": "in", "values": ["openai/gpt-4o", "openai/gpt-4o-mini"] }
    ]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.latency.p95",
    "from": "2026-05-13T00:00:00Z",
    "to":   "2026-05-14T00:00:00Z",
    "grain": "hour",
    "group_by": ["model"]
  }'
metrics["genai.latency.p95"] is reported in milliseconds.
Quantile metrics are independent calls. Fire them concurrently from the client.
for metric in genai.latency.p50 genai.latency.p95 genai.latency.p99; do
  curl -X POST "https://api.orq.ai/v2/reporting" \
    -H "Authorization: Bearer $ORQ_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"metric\":\"$metric\",\"from\":\"2026-05-13T00:00:00Z\",\"to\":\"2026-05-14T00:00:00Z\",\"grain\":\"hour\"}" &
done
wait
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.errors",
    "from": "2026-05-13T00:00:00Z",
    "to":   "2026-05-14T00:00:00Z",
    "grain": "hour",
    "group_by": ["provider"]
  }'
Fetch requests and errors in parallel and divide on the client.
curl -X POST "https://api.orq.ai/v2/reporting" -H "Authorization: Bearer $ORQ_API_KEY" -H "Content-Type: application/json" \
  -d '{"metric":"genai.requests","from":"2026-05-13T00:00:00Z","to":"2026-05-14T00:00:00Z","grain":"hour","group_by":["model"]}' &
curl -X POST "https://api.orq.ai/v2/reporting" -H "Authorization: Bearer $ORQ_API_KEY" -H "Content-Type: application/json" \
  -d '{"metric":"genai.errors","from":"2026-05-13T00:00:00Z","to":"2026-05-14T00:00:00Z","grain":"hour","group_by":["model"]}' &
wait
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.evaluator.pass_rate",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["evaluator", "evaluator_version"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.evaluator.score.avg",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["evaluator"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.evaluator.runs",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["evaluator", "result_label"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.guardrail.block_rate",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["evaluator", "evaluation_stage"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.guardrail.triggered",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["policy", "guardrail_stage"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.guardrail.runs",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["evaluator"],
    "filters": [
      { "field": "guardrail_origin", "op": "eq", "values": ["rule"] }
    ]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["project"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.usage",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["api_key"],
    "include_totals": true
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["identity"]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.requests",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "filters": [
      { "field": "identity", "op": "eq", "values": ["user_42"] }
    ]
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-01T04:00:00Z",
    "to":   "2026-05-15T04:00:00Z",
    "grain": "day",
    "time_zone": "America/New_York"
  }'
Bucket boundaries align to midnight in the requested zone.
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.requests",
    "from": "2026-05-14T11:00:00Z",
    "to":   "2026-05-14T12:00:00Z",
    "grain": "minute"
  }'
curl -X POST "https://api.orq.ai/v2/reporting" \
  -H "Authorization: Bearer $ORQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metric": "genai.cost",
    "from": "2026-05-01T00:00:00Z",
    "to":   "2026-05-15T00:00:00Z",
    "grain": "day",
    "group_by": ["credential_type", "model"]
  }'

Errors

Errors come back as JSON envelopes with a numeric code, a human-readable message, and an empty details array.
{
  "code": 3,
  "message": "time range exceeds maximum: 11952h0m0s > 90d",
  "details": []
}
HTTPCodeReason
4003Unknown metric, dimension not allowed, range outside workspace retention, range over 90 days, from >= to, grain outside retention, or invalid filter operator.
40116Missing or invalid bearer token.
4037API key does not have access to the requested project.
50013Unexpected backend failure. Forward meta.request_id to support.
Every successful response includes meta.request_id. Include it in support tickets for fast log correlation.

Limits

LimitValue
Query windowWorkspace retention period, capped at 90 days
group_by5 columns
filters20 entries
filter.values100 values per filter
limit5000 bucket rows (default 1000)
Per-query timeout30 seconds