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.
Filter object structure
Field filters
Metadata filters
For standard datasource fields, use fieldName:{
"fieldName": "modelName",
"operator": "IN",
"value": ["gpt-4", "gpt-3.5-turbo"]
}
For custom request-metadata keys, use metadataKey. Works on every datasource:{
"metadataKey": "environment",
"operator": "IN",
"value": ["production"]
}
Filterable fields
Most string fields accept the full string operator set: EQUAL, NOT_EQUAL, IN, NOT_IN, STRING_CONTAINS, STRING_NOT_CONTAINS, STRING_STARTS_WITH, STRING_NOT_STARTS_WITH, STRING_ENDS_WITH, STRING_NOT_ENDS_WITH. A few fields are narrower: providerAccountType and createdBySubjectType are comparison-only (no STRING_* operators), traceId is equality-only, and virtualModelName additionally supports IS_NULL.
| Field | Type | Allowed operators |
|---|
modelName | string | EQUAL, NOT_EQUAL, IN, NOT_IN, STRING_CONTAINS, STRING_NOT_CONTAINS, STRING_STARTS_WITH, STRING_NOT_STARTS_WITH, STRING_ENDS_WITH, STRING_NOT_ENDS_WITH |
requestType | string | same as modelName |
virtualModelName | string | same as modelName, plus IS_NULL |
providerModelName | string | same as modelName |
errorCode | string | same as modelName |
providerAccountType | string | EQUAL, NOT_EQUAL, IN, NOT_IN |
createdBySubjectType | string | EQUAL, NOT_EQUAL, IN, NOT_IN |
traceId | string | EQUAL |
userEmail | string | same as modelName |
virtualAccount | string | same as modelName |
conversationID | string | same as modelName |
team | array | ARRAY_HAS_ANY, ARRAY_HAS_NONE |
httpStatusCode | number | EQUAL, NOT_EQUAL, IN, NOT_IN, GREATER_THAN, LESS_THAN, GREATER_THAN_EQUAL, LESS_THAN_EQUAL |
latencyMs | number | GREATER_THAN, LESS_THAN, GREATER_THAN_EQUAL, LESS_THAN_EQUAL, BETWEEN |
inputTokens | number | GREATER_THAN, LESS_THAN, GREATER_THAN_EQUAL, LESS_THAN_EQUAL, BETWEEN |
outputTokens | number | GREATER_THAN, LESS_THAN, GREATER_THAN_EQUAL, LESS_THAN_EQUAL, BETWEEN |
costInUSD | number | GREATER_THAN, LESS_THAN, GREATER_THAN_EQUAL, LESS_THAN_EQUAL, BETWEEN |
isFailure | boolean | EQUAL |
metadataKey / metadata.<key> | string | same as modelName |
For cache-specific fields (cacheType, cacheNamespace, cacheLookupStatus, and the cache token columns), see the Cache Metrics filtering page.
Filter operators
String field operators
| Operator | Description | Example value |
|---|
EQUAL | Exact match | "alice@example.com" |
NOT_EQUAL | Not equal to value | "bot@example.com" |
IN | Match any value in the list | ["gpt-4", "gpt-3.5-turbo"] |
NOT_IN | Exclude values in the list | ["deprecated-model"] |
STRING_CONTAINS | Contains substring | "gpt" |
STRING_NOT_CONTAINS | Does not contain substring | "deprecated" |
STRING_STARTS_WITH | Starts with prefix | "gpt-" |
STRING_NOT_STARTS_WITH | Does not start with prefix | "internal-" |
STRING_ENDS_WITH | Ends with suffix | "-turbo" |
STRING_NOT_ENDS_WITH | Does not end with suffix | "-deprecated" |
IS_NULL | true matches rows where the field is unset; false matches rows where it is set | true |
Numeric field operators
| Operator | Description | Example value |
|---|
EQUAL | Exact match | 1000 |
NOT_EQUAL | Not equal to value | 0 |
IN | Match any value in the list | [100, 200, 300] |
NOT_IN | Exclude values in the list | [0] |
GREATER_THAN | Strictly greater than | 1000 |
LESS_THAN | Strictly less than | 5000 |
GREATER_THAN_EQUAL | Greater than or equal to | 100 |
LESS_THAN_EQUAL | Less than or equal to | 1000 |
BETWEEN | Between two values (inclusive) | [500, 5000] |
IS_NULL | true matches rows where the field is unset; false matches rows where it is set | true |
Boolean field operators
| Operator | Description | Example value |
|---|
EQUAL | Exact match | true |
IS_NULL | true matches rows where the field is unset; false matches rows where it is set | false |
Array field operators (used by team)
| Operator | Description | Example value |
|---|
ARRAY_HAS_ANY | Match if the array contains any of the values | ["team-alpha", "team-beta"] |
ARRAY_HAS_NONE | Match if the array contains none of the values | ["excluded-team"] |
Every datasource supports filtering and grouping by custom request-metadata keys:
- Filter:
{ "metadataKey": "environment", "operator": "EQUAL", "value": "prod" }
- Group: include
"metadata.environment" in the groupBy array (string literal, prefix is metadata.).
Metadata fields are treated as strings; use the String field operators table.
Implicit team unnesting
When 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:
{
"startTs": "2026-04-21T00:00:00.000Z",
"endTs": "2026-04-22T00:00:00.000Z",
"datasource": "modelMetrics",
"type": "distribution",
"filters": [
{"fieldName": "virtualModelName", "operator": "IS_NULL", "value": true},
{"fieldName": "modelName", "operator": "IN", "value": ["gpt-4", "gpt-3.5-turbo"]},
{"fieldName": "latencyMs", "operator": "LESS_THAN", "value": 5000},
{"fieldName": "team", "operator": "ARRAY_HAS_ANY", "value": ["team-alpha"]},
{"metadataKey": "environment", "operator": "IN", "value": ["production"]}
],
"groupBy": ["modelName", "team"]
}