Authorization: Bearer <your_api_key> and Content-Type: application/json.
Access control
Access to metrics is governed by the data access rules configured by your tenant. The server applies these rules automatically based on the caller’s identity—you don’t pass any RBAC or scoping fields in the request. What a caller can query (their own data, their team’s data, or tenant-wide data) depends entirely on the rules an admin has set up. See Configure Data Access for how these rules are defined and evaluated.Authentication
Get your API key
Get your API key
- Personal Access Token (PAT): Go to Access → Personal Access Tokens in your TrueFoundry dashboard
- Virtual Account Token (VAT): Go to Access → Virtual Account Tokens (requires admin permissions)
Quick start
- Distribution query
- Timeseries query
API reference
Post JSON to the endpoint above withAuthorization: Bearer <your_api_key> and Content-Type: application/json.
Request parameters
"configMetrics" for Gateway routing metrics."distribution": returns aggregated rows (one row pergroupBycombination)."timeseries": returns time-bucketed rows. Requiresinterval.
{ type, column } objects describing the aggregations to compute. When omitted, only the implicit total = COUNT(*) is returned.Supported aggregation types
Supported aggregation types
Supported aggregation columns
Supported aggregation columns
metadata. prefix.Available group-by fields
Available group-by fields
groupBy contains userEmail (without virtualaccount), the server auto-injects WHERE CreatedBySubjectType = 'user'. virtualaccount alone auto-injects 'virtualaccount'. When both appear, scope it yourself with createdBySubjectType if needed.<positive integer> <unit>, where <unit> is one of second, minute, hour, day, week, month, year (with or without a trailing s). Examples: "30 second", "5 minute", "1 hour", "1 day". Compound expressions like "1 hour 30 minute" are rejected.interval. Accepts a positive integer number of seconds. Prefer interval in new code. If both are provided, interval wins.Filtering
Filters narrow down the rows that go into each aggregation and group. They are AND-combined; there is no OR-group support. The server enforces a per-field operator allow-list, so the exact subset of operators you can use depends on the field.- Field filters
- Metadata filters
fieldName:Filterable fields and allowed operators
Filterable fields and allowed operators
httpStatusCode, errorType, and latencyMs are not filterable on configMetrics. Sending them returns 400 Bad Request with Unsupported gateway config filter name: <field>. Use status in groupBy to see allowed vs blocked or failure outcomes instead.Filter operators reference
Filter operators reference
team)Custom metadata, team unnesting, and combining filters
Custom metadata, team unnesting, and combining filters
- Filter:
{ "metadataKey": "environment", "operator": "EQUAL", "value": "prod" } - Group: include
"metadata.environment"in thegroupByarray.
team is in groupBy (or used as the column of an aggregation), the server transparently UNNESTs the Teams array CTE before applying RBAC. Callers don’t need to do anything extra. Rows whose Teams array is NULL or empty drop out naturally.Combining multiple filters. Filters are AND-combined:Query examples
Every example posts a JSON body to the endpoint above. To keep the snippets short, only thejson body is shown; the request wrapper is identical to the Quick start.
Distribution examples
Aggregated snapshots of routing rule applications over a time window.Routing volume by config type and status
Routing volume by config type and status
total count; group by configType and status to see the breakdown of rule applications:Attempts distribution per loadbalance rule
Attempts distribution per loadbalance rule
Where a specific requested model ends up
Where a specific requested model ends up
requestedModel and see which targetModels the request lands on, with outcome:Activity for a specific ratelimit rule
Activity for a specific ratelimit rule
ratelimitRuleId and group by status to see allowed vs blocked counts for that rule:Failed routings only
Failed routings only
Distinct target models per rule
Distinct target models per rule
Group by team
Group by team
Timeseries examples
Time-bucketed routing metrics over a window. Every timeseries query must includeinterval (or the deprecated intervalInSeconds).
Hourly routing volume by config type
Hourly routing volume by config type
configType:Hourly average attempts per rule
Hourly average attempts per rule
Hourly routing volume per requested-to-target pair
Hourly routing volume per requested-to-target pair
Hourly outcome breakdown
Hourly outcome breakdown
status over time:5-minute traffic during an incident
5-minute traffic during an incident
Daily routings over a week
Daily routings over a week
Hourly activity for a specific ratelimit rule
Hourly activity for a specific ratelimit rule
Response format
Every successful response has the same outer shape:total: implicitCOUNT(*)for the row. Always present.<aggregationKey>: one key per requested aggregation. The key is<type><Column>in camelCase (e.g.sumLoadbalanceTargetAttemptCount,avgLoadbalanceTargetAttemptCount).<groupByKey>: one key pergroupByentry. The key is the lowerCamelCase form of the underlying column. Two special mappings:userEmailandvirtualaccountboth map tocreatedBySubjectSlugin the response.teammaps toteam(the value is a single unnested scalar, not an array). All othergroupBykeys preserve their lowerCamelCase name.
startTimestamp: present only for timeseries responses. Bucket start as an ISO 8601 timestamp string (e.g."2026-04-29T12:00:00.000Z"). Distribution responses omit it.endTimestamp: present only for timeseries responses. Bucket end as an ISO 8601 timestamp string, equal to the next bucket’sstartTimestamp(e.g."2026-04-29T13:00:00.000Z"). Distribution responses omit it.
Distribution response example
Distribution response example
Timeseries response example
Timeseries response example
groupBy is empty or omitted, the response collapses to a single row (or one row per timeseries bucket) summarising every rule application inside the window.Error responses
A malformed query returns400 Bad Request:
Common causes and other status codes
Common causes and other status codes
400:- Unsupported field name for
configMetrics. The error message is typicallyUnsupported gateway config filter name: <field>. Notably,httpStatusCode,errorType, andlatencyMsare not filterable on this datasource; usestatusingroupByfor outcome breakdowns. - Operator not allowed on this field. For example,
STRING_CONTAINSonloadbalanceRuleId(it supports onlyIN/NOT_IN). - Missing required
value(or wrong shape, e.g. scalar where array is expected forIN). - Invalid
intervalformat (compound expressions, unrecognised unit, non-positive integer). - Missing required
intervalfor a timeseries query.
401 Unauthorized: missing or invalid bearer token.403 Forbidden: caller does not have permission for the requested scope.500 Internal Server Error: unexpected server error while executing the query.