BrowserStack AI Evals
Evaluation

Online Evaluations

Create, manage, and query online-evaluation rules from the SDK across TypeScript, Python, Java, and Go.

Online Evaluations

Online evaluations score your live traces (or sessions) with evaluator lists as they come in. You define a rule — what to watch, how often to sample, which evaluators to run.

Setup

import { AISDK } from '@browserstack/ai-sdk';const publicKey = process.env.AISDK_PUBLIC_KEY!;const secretKey = process.env.AISDK_SECRET_KEY!;const client = new AISDK({  publicKey,  secretKey,});

Create a rule

const rule = await client.onlineEval.create({  name,  samplingRate: 10,  delay: 60,  status: true,  evaluatorListIds: [evaluatorListId],});

Creates a new online-evaluation rule in your project. You can have up to 5 rules per project — going over that returns a 400 error.

ParamTypeRequiredDescription
namestringtrueHuman-readable name for the rule, 1-255 characters.
descriptionstring | nullfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdstringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNamestring | nullfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagstring | nullfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRatenumberfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delaynumberfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountnumberfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusbooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersOnlineEvalFilter[]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
namestrtrueHuman-readable name for the rule, 1-255 characters.
descriptionOptional[str]falseOptional free-text description shown alongside the rule in the UI.
source_typeOptional[EventSchedulerType]falseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
dataset_idOptional[str]falseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
dataset_mapping_typeOptional[DatasetMappingType]falseHow the trace becomes a dataset item.
dataset_extraction_modeOptional[DatasetExtractionMode]falseWhether to use the whole trace or a specific observation as the item.
output_observation_nameOptional[str]falseIf `extractionMode` targets a specific observation, this is its span name.
dataset_tagOptional[str]falseRequired when `datasetMappingType` is `LLM_OUTPUT`.
sampling_rateOptional[int]falsePercent of matching traces the rule fires on (1–100).
Default: 100
delayOptional[int]falseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
trigger_trace_countOptional[int]falseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusOptional[bool]falseSet to `false` to create the rule paused instead of active.
Default: true
filtersOptional[list[OnlineEvalFilterInput]]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
nameStringtrueHuman-readable name for the rule, 1-255 characters.
descriptionStringfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdStringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNameStringfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagStringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRateIntegerfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delayIntegerfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountIntegerfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusBooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersList<OnlineEvalFilter>falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
NamestringtrueHuman-readable name for the rule, 1-255 characters.
Description*stringfalseOptional free-text description shown alongside the rule in the UI.
SourceType*EventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
DatasetId*stringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
DatasetMappingType*DatasetMappingTypefalseHow the trace becomes a dataset item.
DatasetExtractionMode*DatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
OutputObservationName*stringfalseIf `extractionMode` targets a specific observation, this is its span name.
DatasetTag*stringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
SamplingRate*intfalsePercent of matching traces the rule fires on (1–100).
Default: 100
Delay*intfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
TriggerTraceCount*intfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
Status*boolfalseSet to `false` to create the rule paused instead of active.
Default: true
Filters*[]OnlineEvalFilterfalseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []

List rules

const res = await client.onlineEval.list();

Each row also includes traceCount — the number of distinct traces the rule has evaluated so far.

Lists the rules in your project, paginated. You can page through results and search by name — richer filtering isn't available on this endpoint.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
searchstringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
searchOptional[str]falseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
searchStringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
Search*stringfalseSubstring match on name + description (case-insensitive)

Get a rule by id

const fetchedRule = await client.onlineEval.get(ruleId);

Get one online evaluation rule by id

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Update a rule

const updated = await client.onlineEval.update(ruleId, {  samplingRate: 80,  status: false,});

Updates the rule. Only the fields you send are changed — anything you leave out stays the same. To clear the description, pass `description: null`. You can't change `sourceType` after the rule is created. To point the rule at different evaluators or a different dataset, send the new `evaluatorListIds` or `datasetId`. To pause the rule without deleting it, set `status: false`.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
namestringfalseNew rule name.
descriptionstring | nullfalseNew description. Pass `null` to clear it.
onlineEvalEnabledbooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledbooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdstringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNamestring | nullfalseNew target observation name for extraction.
datasetTagstring | nullfalseNew tag applied to items added by this rule.
samplingRatenumberfalseNew sampling rate (1–100).
delaynumberfalseNew idle delay in seconds.
triggerTraceCountnumberfalseSession rules only.
statusbooleanfalseSet to `false` to pause the rule without deleting it.
filtersOnlineEvalFilter[]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
nameOptional[str]falseNew rule name.
descriptionOptional[str]falseNew description. Pass `null` to clear it.
online_eval_enabledOptional[bool]falseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
dataset_enabledOptional[bool]falseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
dataset_idOptional[str]falseNew dataset id.
dataset_mapping_typeOptional[DatasetMappingType]falseNew dataset mapping type.
dataset_extraction_modeOptional[DatasetExtractionMode]falseNew dataset extraction mode.
output_observation_nameOptional[str]falseNew target observation name for extraction.
dataset_tagOptional[str]falseNew tag applied to items added by this rule.
sampling_rateOptional[int]falseNew sampling rate (1–100).
delayOptional[int]falseNew idle delay in seconds.
trigger_trace_countOptional[int]falseSession rules only.
statusOptional[bool]falseSet to `false` to pause the rule without deleting it.
filtersOptional[list[OnlineEvalFilterInput]]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
nameStringfalseNew rule name.
descriptionStringfalseNew description. Pass `null` to clear it.
onlineEvalEnabledBooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledBooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdStringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNameStringfalseNew target observation name for extraction.
datasetTagStringfalseNew tag applied to items added by this rule.
samplingRateIntegerfalseNew sampling rate (1–100).
delayIntegerfalseNew idle delay in seconds.
triggerTraceCountIntegerfalseSession rules only.
statusBooleanfalseSet to `false` to pause the rule without deleting it.
filtersList<OnlineEvalFilter>falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
Name*stringfalseNew rule name.
Description*stringfalseNew description. Pass `null` to clear it.
OnlineEvalEnabled*boolfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
DatasetEnabled*boolfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
DatasetId*stringfalseNew dataset id.
DatasetMappingType*DatasetMappingTypefalseNew dataset mapping type.
DatasetExtractionMode*DatasetExtractionModefalseNew dataset extraction mode.
OutputObservationName*stringfalseNew target observation name for extraction.
DatasetTag*stringfalseNew tag applied to items added by this rule.
SamplingRate*intfalseNew sampling rate (1–100).
Delay*intfalseNew idle delay in seconds.
TriggerTraceCount*intfalseSession rules only.
Status*boolfalseSet to `false` to pause the rule without deleting it.
Filters*[]OnlineEvalFilterfalseNew filter conditions. Pass an empty array to clear.
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.

Delete a rule

const deleteResult = await client.onlineEval.delete(rule.id);

Delete an online evaluation rule

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Analytics

Four read-only endpoints for pulling evaluation results into your own reports or dashboards.

Evaluator scores

Returns aggregated evaluator scores over a time window — one row per evaluator, per time bucket.

const scoresResult = await client.onlineEval.scores(ruleId, {  fromTimestamp: new Date(Date.now() - 24 * 60 * 60 * 1000),  toTimestamp: new Date(),  granularity: 'hour',});

Returns one score series per evaluator attached to the rule, over the time window you specify. If you pass `granularity`, the results are grouped into buckets of that width. Series come back as `NUMERIC` (a score timeline) or `CATEGORICAL` (per-bucket category counts). Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityOptional[str]falseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
Granularity*GranularityfalseBucket width. When omitted, points are returned ungrouped.

Observation metrics

const metricsResult = await client.onlineEval.metrics(ruleId, { granularity: 'hour' });

Returns cost and token usage over time for the observations this rule has evaluated, grouped by adapter, plus provider and model distribution breakdowns. Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseISO 8601. Defaults to server clock.
granularityOptional[str]falseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseISO 8601. Defaults to server clock.
Granularity*GranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.

Trace list (matched by a rule)

Lists the traces a specific rule has evaluated. You can filter by score, environment, tags, and more.

const tracesPage = await client.onlineEval.listTraces(ruleId, { page: 1, limit: 50 });

Lists the traces a rule has evaluated. Supports pagination and rich filtering — see the SDK docs for the filter DSL, allowed columns, and search options.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
pagenumberfalse1-indexed page number.
Default: 1
limitnumberfalsePage size, max 100.
Default: 50
searchQuerystringfalseSubstring match against the columns configured by `searchType`.
searchType('id' | 'content')[]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderBy{ column: TraceFilterColumnfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id.
pageOptional[int]false1-indexed page number.
Default: 1
limitOptional[int]falsePage size, max 100.
Default: 50
search_queryOptional[str]falseSubstring match against the columns configured by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOptional[str]falseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
order_byOptional[str]falseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id.
pageIntegerfalse1-indexed page number.
Default: 1
limitIntegerfalsePage size, max 100.
Default: 50
searchQueryStringfalseSubstring match against the columns configured by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterStringfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderByStringfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
Page*intfalse1-indexed page number.
Default: 1
Limit*intfalsePage size, max 100.
Default: 50
SearchQuery*stringfalseSubstring match against the columns configured by `searchType`.
SearchType[]ListTracesSearchTypefalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
Filter*OnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
OrderBy*ListTracesOrderByfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.

Trace detail (single trace + evaluator scores)

Returns a single trace with all its evaluator scores attached — the same view you'd see when expanding a row in the dashboard.

const traceDetail = await client.onlineEval.trace(traceId);

Fetches a single trace by id, along with its observations and scores. The trace doesn't need to belong to any specific rule — any trace id in your project works. Useful for chaining off the trace list.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).

Complete example

Every step above, stitched together into one block you can copy and adapt. The ruleId is grabbed off the create response; the traceId is picked from the first row of the list-traces response (fall back to a real trace id if the list is empty on a fresh rule).

// 1. Set up the clientimport { AISDK } from '@browserstack/ai-sdk';const publicKey = process.env.AISDK_PUBLIC_KEY!;const secretKey = process.env.AISDK_SECRET_KEY!;const client = new AISDK({  publicKey,  secretKey,});// 2. Per-run variablesconst name = 'Production faithfulness scoring';const evaluatorListId = 'YOUR_EVALUATOR_LIST_ID';// 3. Create a ruleconst rule = await client.onlineEval.create({  name,  samplingRate: 10,  delay: 60,  status: true,  evaluatorListIds: [evaluatorListId],});// 4. Grab the id for later stepsconst ruleId = rule.id;// 5. List rulesconst res = await client.onlineEval.list();// 6. Fetch a rule by idconst fetchedRule = await client.onlineEval.get(ruleId);// 7. Update the ruleconst updated = await client.onlineEval.update(ruleId, {  samplingRate: 80,  status: false,});// 8. Aggregated evaluator scoresconst scoresResult = await client.onlineEval.scores(ruleId, {  fromTimestamp: new Date(Date.now() - 24 * 60 * 60 * 1000),  toTimestamp: new Date(),  granularity: 'hour',});// 9. Observation metricsconst metricsResult = await client.onlineEval.metrics(ruleId, { granularity: 'hour' });// 10. Traces matched by a ruleconst tracesPage = await client.onlineEval.listTraces(ruleId, { page: 1, limit: 50 });// 11. Pick a traceId from the listconst traceId = tracesPage.data[0]?.id ?? '<TRACE_ID>';// 12. Trace detail with evaluator scoresconst traceDetail = await client.onlineEval.trace(traceId);// 13. Delete the ruleconst deleteResult = await client.onlineEval.delete(rule.id);

Setup

import osfrom browserstack_ai_sdk import AISDKclient = AISDK(    public_key=os.environ["AISDK_PUBLIC_KEY"],    secret_key=os.environ["AISDK_SECRET_KEY"],)

Create a rule

rule = client.online_eval.create(    name=name,    sampling_rate=10,    delay=60,    status=True,    evaluator_list_ids=[evaluator_list_id],)

Creates a new online-evaluation rule in your project. You can have up to 5 rules per project — going over that returns a 400 error.

ParamTypeRequiredDescription
namestringtrueHuman-readable name for the rule, 1-255 characters.
descriptionstring | nullfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdstringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNamestring | nullfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagstring | nullfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRatenumberfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delaynumberfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountnumberfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusbooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersOnlineEvalFilter[]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
namestrtrueHuman-readable name for the rule, 1-255 characters.
descriptionOptional[str]falseOptional free-text description shown alongside the rule in the UI.
source_typeOptional[EventSchedulerType]falseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
dataset_idOptional[str]falseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
dataset_mapping_typeOptional[DatasetMappingType]falseHow the trace becomes a dataset item.
dataset_extraction_modeOptional[DatasetExtractionMode]falseWhether to use the whole trace or a specific observation as the item.
output_observation_nameOptional[str]falseIf `extractionMode` targets a specific observation, this is its span name.
dataset_tagOptional[str]falseRequired when `datasetMappingType` is `LLM_OUTPUT`.
sampling_rateOptional[int]falsePercent of matching traces the rule fires on (1–100).
Default: 100
delayOptional[int]falseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
trigger_trace_countOptional[int]falseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusOptional[bool]falseSet to `false` to create the rule paused instead of active.
Default: true
filtersOptional[list[OnlineEvalFilterInput]]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
nameStringtrueHuman-readable name for the rule, 1-255 characters.
descriptionStringfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdStringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNameStringfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagStringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRateIntegerfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delayIntegerfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountIntegerfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusBooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersList<OnlineEvalFilter>falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
NamestringtrueHuman-readable name for the rule, 1-255 characters.
Description*stringfalseOptional free-text description shown alongside the rule in the UI.
SourceType*EventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
DatasetId*stringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
DatasetMappingType*DatasetMappingTypefalseHow the trace becomes a dataset item.
DatasetExtractionMode*DatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
OutputObservationName*stringfalseIf `extractionMode` targets a specific observation, this is its span name.
DatasetTag*stringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
SamplingRate*intfalsePercent of matching traces the rule fires on (1–100).
Default: 100
Delay*intfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
TriggerTraceCount*intfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
Status*boolfalseSet to `false` to create the rule paused instead of active.
Default: true
Filters*[]OnlineEvalFilterfalseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []

List rules

res = client.online_eval.list(page=1, limit=50)

Each row also includes trace_count — the number of distinct traces the rule has evaluated so far.

Lists the rules in your project, paginated. You can page through results and search by name — richer filtering isn't available on this endpoint.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
searchstringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
searchOptional[str]falseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
searchStringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
Search*stringfalseSubstring match on name + description (case-insensitive)

Get a rule by id

rule = client.online_eval.get(rule_id)

Get one online evaluation rule by id

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Update a rule

updated = client.online_eval.update(    rule_id, sampling_rate=80, status=False)

Updates the rule. Only the fields you send are changed — anything you leave out stays the same. To clear the description, pass `description: null`. You can't change `sourceType` after the rule is created. To point the rule at different evaluators or a different dataset, send the new `evaluatorListIds` or `datasetId`. To pause the rule without deleting it, set `status: false`.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
namestringfalseNew rule name.
descriptionstring | nullfalseNew description. Pass `null` to clear it.
onlineEvalEnabledbooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledbooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdstringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNamestring | nullfalseNew target observation name for extraction.
datasetTagstring | nullfalseNew tag applied to items added by this rule.
samplingRatenumberfalseNew sampling rate (1–100).
delaynumberfalseNew idle delay in seconds.
triggerTraceCountnumberfalseSession rules only.
statusbooleanfalseSet to `false` to pause the rule without deleting it.
filtersOnlineEvalFilter[]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
nameOptional[str]falseNew rule name.
descriptionOptional[str]falseNew description. Pass `null` to clear it.
online_eval_enabledOptional[bool]falseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
dataset_enabledOptional[bool]falseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
dataset_idOptional[str]falseNew dataset id.
dataset_mapping_typeOptional[DatasetMappingType]falseNew dataset mapping type.
dataset_extraction_modeOptional[DatasetExtractionMode]falseNew dataset extraction mode.
output_observation_nameOptional[str]falseNew target observation name for extraction.
dataset_tagOptional[str]falseNew tag applied to items added by this rule.
sampling_rateOptional[int]falseNew sampling rate (1–100).
delayOptional[int]falseNew idle delay in seconds.
trigger_trace_countOptional[int]falseSession rules only.
statusOptional[bool]falseSet to `false` to pause the rule without deleting it.
filtersOptional[list[OnlineEvalFilterInput]]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
nameStringfalseNew rule name.
descriptionStringfalseNew description. Pass `null` to clear it.
onlineEvalEnabledBooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledBooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdStringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNameStringfalseNew target observation name for extraction.
datasetTagStringfalseNew tag applied to items added by this rule.
samplingRateIntegerfalseNew sampling rate (1–100).
delayIntegerfalseNew idle delay in seconds.
triggerTraceCountIntegerfalseSession rules only.
statusBooleanfalseSet to `false` to pause the rule without deleting it.
filtersList<OnlineEvalFilter>falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
Name*stringfalseNew rule name.
Description*stringfalseNew description. Pass `null` to clear it.
OnlineEvalEnabled*boolfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
DatasetEnabled*boolfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
DatasetId*stringfalseNew dataset id.
DatasetMappingType*DatasetMappingTypefalseNew dataset mapping type.
DatasetExtractionMode*DatasetExtractionModefalseNew dataset extraction mode.
OutputObservationName*stringfalseNew target observation name for extraction.
DatasetTag*stringfalseNew tag applied to items added by this rule.
SamplingRate*intfalseNew sampling rate (1–100).
Delay*intfalseNew idle delay in seconds.
TriggerTraceCount*intfalseSession rules only.
Status*boolfalseSet to `false` to pause the rule without deleting it.
Filters*[]OnlineEvalFilterfalseNew filter conditions. Pass an empty array to clear.
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.

Delete a rule

result = client.online_eval.delete(rule_id)

Delete an online evaluation rule

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Analytics

Four read-only endpoints for pulling evaluation results into your own reports or dashboards.

Evaluator scores

Returns aggregated evaluator scores over a time window — one row per evaluator, per time bucket.

result = client.online_eval.scores(    rule_id,    from_timestamp=datetime.now(timezone.utc) - timedelta(days=1),    to_timestamp=datetime.now(timezone.utc),    granularity="hour",)

Returns one score series per evaluator attached to the rule, over the time window you specify. If you pass `granularity`, the results are grouped into buckets of that width. Series come back as `NUMERIC` (a score timeline) or `CATEGORICAL` (per-bucket category counts). Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityOptional[str]falseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
Granularity*GranularityfalseBucket width. When omitted, points are returned ungrouped.

Observation metrics

result = client.online_eval.metrics(    rule_id, granularity="hour")

Returns cost and token usage over time for the observations this rule has evaluated, grouped by adapter, plus provider and model distribution breakdowns. Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseISO 8601. Defaults to server clock.
granularityOptional[str]falseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseISO 8601. Defaults to server clock.
Granularity*GranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.

Trace list (matched by a rule)

Lists the traces a specific rule has evaluated. You can filter by score, environment, tags, and more.

result = client.online_eval.list_traces(    rule_id,    page=1, limit=10,    filter={        "must": [            {"fieldName": "name", "operator": "IN", "value": ["no-match-by-design"]},        ],    },)

Lists the traces a rule has evaluated. Supports pagination and rich filtering — see the SDK docs for the filter DSL, allowed columns, and search options.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
pagenumberfalse1-indexed page number.
Default: 1
limitnumberfalsePage size, max 100.
Default: 50
searchQuerystringfalseSubstring match against the columns configured by `searchType`.
searchType('id' | 'content')[]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderBy{ column: TraceFilterColumnfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id.
pageOptional[int]false1-indexed page number.
Default: 1
limitOptional[int]falsePage size, max 100.
Default: 50
search_queryOptional[str]falseSubstring match against the columns configured by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOptional[str]falseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
order_byOptional[str]falseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id.
pageIntegerfalse1-indexed page number.
Default: 1
limitIntegerfalsePage size, max 100.
Default: 50
searchQueryStringfalseSubstring match against the columns configured by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterStringfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderByStringfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
Page*intfalse1-indexed page number.
Default: 1
Limit*intfalsePage size, max 100.
Default: 50
SearchQuery*stringfalseSubstring match against the columns configured by `searchType`.
SearchType[]ListTracesSearchTypefalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
Filter*OnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
OrderBy*ListTracesOrderByfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.

Trace detail (single trace + evaluator scores)

Returns a single trace with all its evaluator scores attached — the same view you'd see when expanding a row in the dashboard.

trace_detail = client.online_eval.trace(trace_id)

Fetches a single trace by id, along with its observations and scores. The trace doesn't need to belong to any specific rule — any trace id in your project works. Useful for chaining off the trace list.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).

Complete example

Every step above, stitched together into one block you can copy and adapt. The rule_id is grabbed off the create response; the trace_id is picked from the first row of the list-traces response (fall back to a real trace id if the list is empty on a fresh rule).

# 1. Set up the clientimport osfrom browserstack_ai_sdk import AISDKclient = AISDK(    public_key=os.environ["AISDK_PUBLIC_KEY"],    secret_key=os.environ["AISDK_SECRET_KEY"],)# 2. Per-run variablesname = "Production faithfulness scoring"evaluator_list_id = "YOUR_EVALUATOR_LIST_ID"# 3. Create a rulerule = client.online_eval.create(    name=name,    sampling_rate=10,    delay=60,    status=True,    evaluator_list_ids=[evaluator_list_id],)# 4. Grab the id for later stepsrule_id = rule.id# 5. List rulesres = client.online_eval.list(page=1, limit=50)# 6. Fetch a rule by idrule = client.online_eval.get(rule_id)# 7. Update the ruleupdated = client.online_eval.update(    rule_id, sampling_rate=80, status=False)# 8. Aggregated evaluator scoresresult = client.online_eval.scores(    rule_id,    from_timestamp=datetime.now(timezone.utc) - timedelta(days=1),    to_timestamp=datetime.now(timezone.utc),    granularity="hour",)# 9. Observation metricsresult = client.online_eval.metrics(    rule_id, granularity="hour")# 10. Traces matched by a ruleresult = client.online_eval.list_traces(    rule_id,    page=1, limit=10,    filter={        "must": [            {"fieldName": "name", "operator": "IN", "value": ["no-match-by-design"]},        ],    },)# 11. Pick a trace_id from the listtrace_id = result.data[0].id if result.data else "<TRACE_ID>"# 12. Trace detail with evaluator scorestrace_detail = client.online_eval.trace(trace_id)# 13. Delete the ruleresult = client.online_eval.delete(rule_id)

Setup

import com.browserstack.aisdk.AISDK;import com.browserstack.aisdk.clients.online_eval.EvaluatorScoresResponse;import com.browserstack.aisdk.clients.online_eval.Granularity;import com.browserstack.aisdk.clients.online_eval.ListOnlineEvalTracesResponse;import com.browserstack.aisdk.clients.online_eval.ListTracesParams;import com.browserstack.aisdk.clients.online_eval.MetricsParams;import com.browserstack.aisdk.clients.online_eval.ObservationMetricsResponse;import com.browserstack.aisdk.clients.online_eval.OnlineEval;import com.browserstack.aisdk.clients.online_eval.OnlineEvalFiltersCustom;import com.browserstack.aisdk.clients.online_eval.ScoresParams;import java.time.Instant;import java.util.Arrays;import java.util.LinkedHashMap;import java.util.Map;AISDK sdk = AISDK.builder()    .publicKey(System.getenv("BROWSERSTACK_PUBLIC_KEY"))    .secretKey(System.getenv("BROWSERSTACK_SECRET_KEY"))    .build();OnlineEval onlineEval = sdk.onlineEval();

Create a rule

// Create an online-eval rule that scores 25% of production traces// against the "Faithfulness evaluator" list with a 120s delay.CreateOnlineEvalBody body = new CreateOnlineEvalBody();body.name = vars.name;body.description = "Score production traces on the faithfulness evaluator";body.sourceType = EventSchedulerType.TRACE;body.samplingRate = 25;body.delay = 120;body.triggerTraceCount = 0;body.status = true;body.filters = Collections.emptyList();body.evaluatorListIds = Collections.singletonList(vars.evaluatorListId);OnlineEvalConfig rule = onlineEval.create(body);

Creates a new online-evaluation rule in your project. You can have up to 5 rules per project — going over that returns a 400 error.

ParamTypeRequiredDescription
namestringtrueHuman-readable name for the rule, 1-255 characters.
descriptionstring | nullfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdstringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNamestring | nullfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagstring | nullfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRatenumberfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delaynumberfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountnumberfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusbooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersOnlineEvalFilter[]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
namestrtrueHuman-readable name for the rule, 1-255 characters.
descriptionOptional[str]falseOptional free-text description shown alongside the rule in the UI.
source_typeOptional[EventSchedulerType]falseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
dataset_idOptional[str]falseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
dataset_mapping_typeOptional[DatasetMappingType]falseHow the trace becomes a dataset item.
dataset_extraction_modeOptional[DatasetExtractionMode]falseWhether to use the whole trace or a specific observation as the item.
output_observation_nameOptional[str]falseIf `extractionMode` targets a specific observation, this is its span name.
dataset_tagOptional[str]falseRequired when `datasetMappingType` is `LLM_OUTPUT`.
sampling_rateOptional[int]falsePercent of matching traces the rule fires on (1–100).
Default: 100
delayOptional[int]falseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
trigger_trace_countOptional[int]falseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusOptional[bool]falseSet to `false` to create the rule paused instead of active.
Default: true
filtersOptional[list[OnlineEvalFilterInput]]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
nameStringtrueHuman-readable name for the rule, 1-255 characters.
descriptionStringfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdStringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNameStringfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagStringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRateIntegerfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delayIntegerfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountIntegerfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusBooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersList<OnlineEvalFilter>falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
NamestringtrueHuman-readable name for the rule, 1-255 characters.
Description*stringfalseOptional free-text description shown alongside the rule in the UI.
SourceType*EventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
DatasetId*stringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
DatasetMappingType*DatasetMappingTypefalseHow the trace becomes a dataset item.
DatasetExtractionMode*DatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
OutputObservationName*stringfalseIf `extractionMode` targets a specific observation, this is its span name.
DatasetTag*stringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
SamplingRate*intfalsePercent of matching traces the rule fires on (1–100).
Default: 100
Delay*intfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
TriggerTraceCount*intfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
Status*boolfalseSet to `false` to create the rule paused instead of active.
Default: true
Filters*[]OnlineEvalFilterfalseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []

List rules

ListOnlineEvalsParams params = new ListOnlineEvalsParams();params.page = 1;params.limit = 50;ListOnlineEvalsResponse page = onlineEval.list(params);java.util.List<OnlineEvalConfig> rules = page.data;

Each row also includes traceCount — the number of distinct traces the rule has evaluated so far.

Lists the rules in your project, paginated. You can page through results and search by name — richer filtering isn't available on this endpoint.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
searchstringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
searchOptional[str]falseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
searchStringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
Search*stringfalseSubstring match on name + description (case-insensitive)

Get a rule by id

OnlineEvalConfig rule = onlineEval.get(ruleId);

Get one online evaluation rule by id

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Update a rule

// Partial update — only non-null fields are sent on the wire.// sourceType is intentionally omitted from UpdateOnlineEvalBody// (immutable after creation).UpdateOnlineEvalBody update = new UpdateOnlineEvalBody();update.samplingRate = 80;update.status = false;OnlineEvalConfig updated = onlineEval.update(ruleId, update);

Updates the rule. Only the fields you send are changed — anything you leave out stays the same. To clear the description, pass `description: null`. You can't change `sourceType` after the rule is created. To point the rule at different evaluators or a different dataset, send the new `evaluatorListIds` or `datasetId`. To pause the rule without deleting it, set `status: false`.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
namestringfalseNew rule name.
descriptionstring | nullfalseNew description. Pass `null` to clear it.
onlineEvalEnabledbooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledbooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdstringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNamestring | nullfalseNew target observation name for extraction.
datasetTagstring | nullfalseNew tag applied to items added by this rule.
samplingRatenumberfalseNew sampling rate (1–100).
delaynumberfalseNew idle delay in seconds.
triggerTraceCountnumberfalseSession rules only.
statusbooleanfalseSet to `false` to pause the rule without deleting it.
filtersOnlineEvalFilter[]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
nameOptional[str]falseNew rule name.
descriptionOptional[str]falseNew description. Pass `null` to clear it.
online_eval_enabledOptional[bool]falseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
dataset_enabledOptional[bool]falseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
dataset_idOptional[str]falseNew dataset id.
dataset_mapping_typeOptional[DatasetMappingType]falseNew dataset mapping type.
dataset_extraction_modeOptional[DatasetExtractionMode]falseNew dataset extraction mode.
output_observation_nameOptional[str]falseNew target observation name for extraction.
dataset_tagOptional[str]falseNew tag applied to items added by this rule.
sampling_rateOptional[int]falseNew sampling rate (1–100).
delayOptional[int]falseNew idle delay in seconds.
trigger_trace_countOptional[int]falseSession rules only.
statusOptional[bool]falseSet to `false` to pause the rule without deleting it.
filtersOptional[list[OnlineEvalFilterInput]]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
nameStringfalseNew rule name.
descriptionStringfalseNew description. Pass `null` to clear it.
onlineEvalEnabledBooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledBooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdStringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNameStringfalseNew target observation name for extraction.
datasetTagStringfalseNew tag applied to items added by this rule.
samplingRateIntegerfalseNew sampling rate (1–100).
delayIntegerfalseNew idle delay in seconds.
triggerTraceCountIntegerfalseSession rules only.
statusBooleanfalseSet to `false` to pause the rule without deleting it.
filtersList<OnlineEvalFilter>falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
Name*stringfalseNew rule name.
Description*stringfalseNew description. Pass `null` to clear it.
OnlineEvalEnabled*boolfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
DatasetEnabled*boolfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
DatasetId*stringfalseNew dataset id.
DatasetMappingType*DatasetMappingTypefalseNew dataset mapping type.
DatasetExtractionMode*DatasetExtractionModefalseNew dataset extraction mode.
OutputObservationName*stringfalseNew target observation name for extraction.
DatasetTag*stringfalseNew tag applied to items added by this rule.
SamplingRate*intfalseNew sampling rate (1–100).
Delay*intfalseNew idle delay in seconds.
TriggerTraceCount*intfalseSession rules only.
Status*boolfalseSet to `false` to pause the rule without deleting it.
Filters*[]OnlineEvalFilterfalseNew filter conditions. Pass an empty array to clear.
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.

Delete a rule

DeleteOnlineEvalResponse res = onlineEval.delete(ruleId);

Delete an online evaluation rule

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Analytics

Four read-only endpoints for pulling evaluation results into your own reports or dashboards.

Evaluator scores

Returns aggregated evaluator scores over a time window — one row per evaluator, per time bucket.

// Fetch per-evaluator score time-series for an online-eval rule.// Server applies a last-24h default window when timestamps are omitted.ScoresParams params = new ScoresParams();params.fromTimestamp = Instant.parse("2026-06-24T00:00:00Z");params.toTimestamp = Instant.parse("2026-06-25T00:00:00Z");params.granularity = Granularity.hour;EvaluatorScoresResponse resp = onlineEval.scores(ruleId, params);

Returns one score series per evaluator attached to the rule, over the time window you specify. If you pass `granularity`, the results are grouped into buckets of that width. Series come back as `NUMERIC` (a score timeline) or `CATEGORICAL` (per-bucket category counts). Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityOptional[str]falseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
Granularity*GranularityfalseBucket width. When omitted, points are returned ungrouped.

Observation metrics

// Fetch cost/token/provider-distribution metrics for the rule's// sampled traces over the selected granularity bucket.MetricsParams params = new MetricsParams();params.granularity = Granularity.day;ObservationMetricsResponse resp = onlineEval.metrics(ruleId, params);

Returns cost and token usage over time for the observations this rule has evaluated, grouped by adapter, plus provider and model distribution breakdowns. Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseISO 8601. Defaults to server clock.
granularityOptional[str]falseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseISO 8601. Defaults to server clock.
Granularity*GranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.

Trace list (matched by a rule)

Lists the traces a specific rule has evaluated. You can filter by score, environment, tags, and more.

// Paginate the traces this online-eval rule has sampled.ListTracesParams params = new ListTracesParams();params.page = 1;params.limit = 50;ListOnlineEvalTracesResponse resp = onlineEval.listTraces(ruleId, params);

Lists the traces a rule has evaluated. Supports pagination and rich filtering — see the SDK docs for the filter DSL, allowed columns, and search options.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
pagenumberfalse1-indexed page number.
Default: 1
limitnumberfalsePage size, max 100.
Default: 50
searchQuerystringfalseSubstring match against the columns configured by `searchType`.
searchType('id' | 'content')[]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderBy{ column: TraceFilterColumnfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id.
pageOptional[int]false1-indexed page number.
Default: 1
limitOptional[int]falsePage size, max 100.
Default: 50
search_queryOptional[str]falseSubstring match against the columns configured by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOptional[str]falseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
order_byOptional[str]falseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id.
pageIntegerfalse1-indexed page number.
Default: 1
limitIntegerfalsePage size, max 100.
Default: 50
searchQueryStringfalseSubstring match against the columns configured by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterStringfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderByStringfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
Page*intfalse1-indexed page number.
Default: 1
Limit*intfalsePage size, max 100.
Default: 50
SearchQuery*stringfalseSubstring match against the columns configured by `searchType`.
SearchType[]ListTracesSearchTypefalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
Filter*OnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
OrderBy*ListTracesOrderByfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.

Trace detail (single trace + evaluator scores)

Returns a single trace with all its evaluator scores attached — the same view you'd see when expanding a row in the dashboard.

// Fetch the full trace payload for a scored trace surfaced by the// online-eval rule (delegates to the shared /api/public/traces facade).Object trace = onlineEval.trace(traceId);

Fetches a single trace by id, along with its observations and scores. The trace doesn't need to belong to any specific rule — any trace id in your project works. Useful for chaining off the trace list.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).

Complete example

Every step above, stitched together into one block you can copy and adapt. The ruleId is grabbed off the create response; the traceId is picked from the first row of the list-traces response (fall back to a real trace id if the list is empty on a fresh rule).

// 1. Set up the SDKimport com.browserstack.aisdk.AISDK;import com.browserstack.aisdk.clients.online_eval.EvaluatorScoresResponse;import com.browserstack.aisdk.clients.online_eval.Granularity;import com.browserstack.aisdk.clients.online_eval.ListOnlineEvalTracesResponse;import com.browserstack.aisdk.clients.online_eval.ListTracesParams;import com.browserstack.aisdk.clients.online_eval.MetricsParams;import com.browserstack.aisdk.clients.online_eval.ObservationMetricsResponse;import com.browserstack.aisdk.clients.online_eval.OnlineEval;import com.browserstack.aisdk.clients.online_eval.OnlineEvalFiltersCustom;import com.browserstack.aisdk.clients.online_eval.ScoresParams;import java.time.Instant;import java.util.Arrays;import java.util.LinkedHashMap;import java.util.Map;AISDK sdk = AISDK.builder()    .publicKey(System.getenv("BROWSERSTACK_PUBLIC_KEY"))    .secretKey(System.getenv("BROWSERSTACK_SECRET_KEY"))    .build();OnlineEval onlineEval = sdk.onlineEval();// 2. Per-run variablesString name = "Production faithfulness scoring";String evaluatorListId = "YOUR_EVALUATOR_LIST_ID";// 3. Create a rule// Create an online-eval rule that scores 25% of production traces// against the "Faithfulness evaluator" list with a 120s delay.CreateOnlineEvalBody body = new CreateOnlineEvalBody();body.name = vars.name;body.description = "Score production traces on the faithfulness evaluator";body.sourceType = EventSchedulerType.TRACE;body.samplingRate = 25;body.delay = 120;body.triggerTraceCount = 0;body.status = true;body.filters = Collections.emptyList();body.evaluatorListIds = Collections.singletonList(vars.evaluatorListId);OnlineEvalConfig rule = onlineEval.create(body);// 4. Grab the id for later stepsString ruleId = rule.id;// 5. List rulesListOnlineEvalsParams params = new ListOnlineEvalsParams();params.page = 1;params.limit = 50;ListOnlineEvalsResponse page = onlineEval.list(params);java.util.List<OnlineEvalConfig> rules = page.data;// 6. Fetch a rule by idOnlineEvalConfig rule = onlineEval.get(ruleId);// 7. Update the rule// Partial update — only non-null fields are sent on the wire.// sourceType is intentionally omitted from UpdateOnlineEvalBody// (immutable after creation).UpdateOnlineEvalBody update = new UpdateOnlineEvalBody();update.samplingRate = 80;update.status = false;OnlineEvalConfig updated = onlineEval.update(ruleId, update);// 8. Aggregated evaluator scores// Fetch per-evaluator score time-series for an online-eval rule.// Server applies a last-24h default window when timestamps are omitted.ScoresParams params = new ScoresParams();params.fromTimestamp = Instant.parse("2026-06-24T00:00:00Z");params.toTimestamp = Instant.parse("2026-06-25T00:00:00Z");params.granularity = Granularity.hour;EvaluatorScoresResponse resp = onlineEval.scores(ruleId, params);// 9. Observation metrics// Fetch cost/token/provider-distribution metrics for the rule's// sampled traces over the selected granularity bucket.MetricsParams params = new MetricsParams();params.granularity = Granularity.day;ObservationMetricsResponse resp = onlineEval.metrics(ruleId, params);// 10. Traces matched by a rule// Paginate the traces this online-eval rule has sampled.ListTracesParams params = new ListTracesParams();params.page = 1;params.limit = 50;ListOnlineEvalTracesResponse resp = onlineEval.listTraces(ruleId, params);// 11. Pick a traceId from the listString traceId = resp.data.isEmpty() ? "<TRACE_ID>" : resp.data.get(0).id;// 12. Trace detail with evaluator scores// Fetch the full trace payload for a scored trace surfaced by the// online-eval rule (delegates to the shared /api/public/traces facade).Object trace = onlineEval.trace(traceId);// 13. Delete the ruleDeleteOnlineEvalResponse res = onlineEval.delete(ruleId);

Setup

import (	"context"	"log"	aisdk "github.com/browserstack/ai-sdk-go")ctx := context.Background()sdk, err := aisdk.New(aisdk.WithCredentials(	"pk-lf-your-public-key",	"sk-lf-your-secret-key",))if err != nil {	log.Fatalf("aisdk.New: %v", err)}client := sdk.OnlineEval()

Create a rule

desc := "Score 25% of production traces on faithfulness evaluator"sr, delay := 25, 120status := truerule, err := client.Create(context.Background(), &CreateOnlineEvalBody{	Name:             vars.name,	Description:      &desc,	SamplingRate:     &sr,	Delay:            &delay,	Status:           &status,	Filters:          &[]OnlineEvalFilter{},	EvaluatorListIds: ptr([]string{evaluatorListID}),})

Creates a new online-evaluation rule in your project. You can have up to 5 rules per project — going over that returns a 400 error.

ParamTypeRequiredDescription
namestringtrueHuman-readable name for the rule, 1-255 characters.
descriptionstring | nullfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdstringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNamestring | nullfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagstring | nullfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRatenumberfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delaynumberfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountnumberfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusbooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersOnlineEvalFilter[]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
namestrtrueHuman-readable name for the rule, 1-255 characters.
descriptionOptional[str]falseOptional free-text description shown alongside the rule in the UI.
source_typeOptional[EventSchedulerType]falseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
dataset_idOptional[str]falseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
dataset_mapping_typeOptional[DatasetMappingType]falseHow the trace becomes a dataset item.
dataset_extraction_modeOptional[DatasetExtractionMode]falseWhether to use the whole trace or a specific observation as the item.
output_observation_nameOptional[str]falseIf `extractionMode` targets a specific observation, this is its span name.
dataset_tagOptional[str]falseRequired when `datasetMappingType` is `LLM_OUTPUT`.
sampling_rateOptional[int]falsePercent of matching traces the rule fires on (1–100).
Default: 100
delayOptional[int]falseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
trigger_trace_countOptional[int]falseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusOptional[bool]falseSet to `false` to create the rule paused instead of active.
Default: true
filtersOptional[list[OnlineEvalFilterInput]]falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
nameStringtrueHuman-readable name for the rule, 1-255 characters.
descriptionStringfalseOptional free-text description shown alongside the rule in the UI.
sourceTypeEventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
datasetIdStringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
datasetMappingTypeDatasetMappingTypefalseHow the trace becomes a dataset item.
datasetExtractionModeDatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
outputObservationNameStringfalseIf `extractionMode` targets a specific observation, this is its span name.
datasetTagStringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
samplingRateIntegerfalsePercent of matching traces the rule fires on (1–100).
Default: 100
delayIntegerfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
triggerTraceCountIntegerfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
statusBooleanfalseSet to `false` to create the rule paused instead of active.
Default: true
filtersList<OnlineEvalFilter>falseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []
ParamTypeRequiredDescription
NamestringtrueHuman-readable name for the rule, 1-255 characters.
Description*stringfalseOptional free-text description shown alongside the rule in the UI.
SourceType*EventSchedulerTypefalseDefaults to `TRACE` if you don't set it. You can't change this after the rule is created. Session rules unlock `triggerTraceCount` and support a smaller set of filter fields (see `OnlineEvalFilterField`).
DatasetId*stringfalseThe dataset to add matches to. Setting this turns on the dataset-addition action. If you use `LLM_OUTPUT` mapping, you also need to set `datasetTag`.
DatasetMappingType*DatasetMappingTypefalseHow the trace becomes a dataset item.
DatasetExtractionMode*DatasetExtractionModefalseWhether to use the whole trace or a specific observation as the item.
OutputObservationName*stringfalseIf `extractionMode` targets a specific observation, this is its span name.
DatasetTag*stringfalseRequired when `datasetMappingType` is `LLM_OUTPUT`.
SamplingRate*intfalsePercent of matching traces the rule fires on (1–100).
Default: 100
Delay*intfalseSeconds to wait before firing, so late-arriving spans can complete.
Default: 30
TriggerTraceCount*intfalseSession rules only. Set to `0` to disable (the rule fires on the idle `delay` instead). Passing a non-zero value on a trace rule returns an error.
Default: 0
Status*boolfalseSet to `false` to create the rule paused instead of active.
Default: true
Filters*[]OnlineEvalFilterfalseConditions that decide which traces the rule applies to. Leave empty to match every trace or session of this `sourceType`.
Default: []
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to run on matched traces. Each list bundles one or more evaluators — this is what the dashboard calls a "Metric". You can create and list them via the `/api/public/evaluator-lists` endpoint. Passing a non-empty array turns on the online-evaluation action.
Default: []

List rules

page, limit := 1, 1res, err := client.List(context.Background(), &ListOnlineEvalsParams{	Page:  &page,	Limit: &limit,})

Each row also includes TraceCount — the number of distinct traces the rule has evaluated so far.

Lists the rules in your project, paginated. You can page through results and search by name — richer filtering isn't available on this endpoint.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
searchstringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
searchOptional[str]falseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
searchStringfalseSubstring match on name + description (case-insensitive)
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
Search*stringfalseSubstring match on name + description (case-insensitive)

Get a rule by id

rule, err := client.Get(context.Background(), ruleID)

Get one online evaluation rule by id

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Update a rule

sr := 80status := falserule, err := client.Update(context.Background(), ruleID, &UpdateOnlineEvalBody{	SamplingRate: &sr,	Status:       &status,})

Updates the rule. Only the fields you send are changed — anything you leave out stays the same. To clear the description, pass `description: null`. You can't change `sourceType` after the rule is created. To point the rule at different evaluators or a different dataset, send the new `evaluatorListIds` or `datasetId`. To pause the rule without deleting it, set `status: false`.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
namestringfalseNew rule name.
descriptionstring | nullfalseNew description. Pass `null` to clear it.
onlineEvalEnabledbooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledbooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdstringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNamestring | nullfalseNew target observation name for extraction.
datasetTagstring | nullfalseNew tag applied to items added by this rule.
samplingRatenumberfalseNew sampling rate (1–100).
delaynumberfalseNew idle delay in seconds.
triggerTraceCountnumberfalseSession rules only.
statusbooleanfalseSet to `false` to pause the rule without deleting it.
filtersOnlineEvalFilter[]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsstring[]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
nameOptional[str]falseNew rule name.
descriptionOptional[str]falseNew description. Pass `null` to clear it.
online_eval_enabledOptional[bool]falseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
dataset_enabledOptional[bool]falseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
dataset_idOptional[str]falseNew dataset id.
dataset_mapping_typeOptional[DatasetMappingType]falseNew dataset mapping type.
dataset_extraction_modeOptional[DatasetExtractionMode]falseNew dataset extraction mode.
output_observation_nameOptional[str]falseNew target observation name for extraction.
dataset_tagOptional[str]falseNew tag applied to items added by this rule.
sampling_rateOptional[int]falseNew sampling rate (1–100).
delayOptional[int]falseNew idle delay in seconds.
trigger_trace_countOptional[int]falseSession rules only.
statusOptional[bool]falseSet to `false` to pause the rule without deleting it.
filtersOptional[list[OnlineEvalFilterInput]]falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluator_list_idsOptional[list[str]]falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
nameStringfalseNew rule name.
descriptionStringfalseNew description. Pass `null` to clear it.
onlineEvalEnabledBooleanfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
datasetEnabledBooleanfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
datasetIdStringfalseNew dataset id.
datasetMappingTypeDatasetMappingTypefalseNew dataset mapping type.
datasetExtractionModeDatasetExtractionModefalseNew dataset extraction mode.
outputObservationNameStringfalseNew target observation name for extraction.
datasetTagStringfalseNew tag applied to items added by this rule.
samplingRateIntegerfalseNew sampling rate (1–100).
delayIntegerfalseNew idle delay in seconds.
triggerTraceCountIntegerfalseSession rules only.
statusBooleanfalseSet to `false` to pause the rule without deleting it.
filtersList<OnlineEvalFilter>falseNew filter conditions. Pass an empty array to clear.
filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
evaluatorListIdsList<String>falseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
Name*stringfalseNew rule name.
Description*stringfalseNew description. Pass `null` to clear it.
OnlineEvalEnabled*boolfalseExplicitly pause or resume the online-evaluation action. If you leave it out, the server derives it from `evaluatorListIds` (when that's part of this update).
DatasetEnabled*boolfalseExplicitly pause or resume the dataset-addition action. If you leave it out, the server derives it from `datasetId` (when that's part of this update).
DatasetId*stringfalseNew dataset id.
DatasetMappingType*DatasetMappingTypefalseNew dataset mapping type.
DatasetExtractionMode*DatasetExtractionModefalseNew dataset extraction mode.
OutputObservationName*stringfalseNew target observation name for extraction.
DatasetTag*stringfalseNew tag applied to items added by this rule.
SamplingRate*intfalseNew sampling rate (1–100).
Delay*intfalseNew idle delay in seconds.
TriggerTraceCount*intfalseSession rules only.
Status*boolfalseSet to `false` to pause the rule without deleting it.
Filters*[]OnlineEvalFilterfalseNew filter conditions. Pass an empty array to clear.
Filters.fieldNameOnlineEvalFilterField | stringtrueOne of the trace / observation / session fields (see `OnlineEvalFilterField` for the list) or a custom `metadata.<key>` path. Invalid combinations for the rule's `sourceType` return `400`.
Filters.operator"EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH" | "REGEX" | "IN" | "NOT_IN" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY"trueThe comparison to run.
Filters.valuestringtrueWhat to compare against. For `IN` / `NOT_IN`, pass a comma-separated list. For `IS_EMPTY` / `IS_NOT_EMPTY`, this is ignored.
Filters.logicalOperator"AND" | "OR"falseHow this filter combines with the one before it.
Default: "AND"
EvaluatorListIds*[]stringfalseThe evaluator lists to attach — see the same field on the create body. This replaces what was there before; pass the full set you want, not a delta. Sending a non-empty array turns on online eval; an empty one turns it off.

Delete a rule

res, err := client.Delete(context.Background(), ruleID)

Delete an online evaluation rule

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id

Analytics

Four read-only endpoints for pulling evaluation results into your own reports or dashboards.

Evaluator scores

Returns aggregated evaluator scores over a time window — one row per evaluator, per time bucket.

from := time.Date(2026, 6, 24, 0, 0, 0, 0, time.UTC)to := time.Date(2026, 6, 25, 0, 0, 0, 0, time.UTC)granularity := Granularity("hour")resp, err := client.Scores(context.Background(), ruleID, &ScoresParams{	FromTimestamp: &from,	ToTimestamp:   &to,	Granularity:   &granularity,})

Returns one score series per evaluator attached to the rule, over the time window you specify. If you pass `granularity`, the results are grouped into buckets of that width. Series come back as `NUMERIC` (a score timeline) or `CATEGORICAL` (per-bucket category counts). Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityOptional[str]falseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
granularityGranularityfalseBucket width. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseInclusive lower bound, ISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseInclusive upper bound, ISO 8601. Defaults to the server clock at request time.
Granularity*GranularityfalseBucket width. When omitted, points are returned ungrouped.

Observation metrics

granularity := Granularity("day")resp, err := client.Metrics(context.Background(), ruleID, &MetricsParams{	Granularity: &granularity,})

Returns cost and token usage over time for the observations this rule has evaluated, grouped by adapter, plus provider and model distribution breakdowns. Both timestamps are optional. If you leave them out, you get the **last 24 hours** (`toTimestamp` defaults to now, `fromTimestamp` to 24 hours before that).

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
fromTimestampDate | stringfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampDate | stringfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id
from_timestampOptional[str]falseISO 8601. Defaults to `toTimestamp − 24h`.
to_timestampOptional[str]falseISO 8601. Defaults to server clock.
granularityOptional[str]falseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id
fromTimestampjava.time.InstantfalseISO 8601. Defaults to `toTimestamp − 24h`.
toTimestampjava.time.InstantfalseISO 8601. Defaults to server clock.
granularityGranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id
FromTimestamp*time.TimefalseISO 8601. Defaults to `toTimestamp − 24h`.
ToTimestamp*time.TimefalseISO 8601. Defaults to server clock.
Granularity*GranularityfalseBucket width for the timeseries. When omitted, points are returned ungrouped.

Trace list (matched by a rule)

Lists the traces a specific rule has evaluated. You can filter by score, environment, tags, and more.

filterSet := &OnlineEvalTraceFilterSet{	Must: &[]OnlineEvalTraceFilter{},	Any:  &[]OnlineEvalTraceFilter{},}_, err := client.ListTraces(context.Background(), ruleID, &ListTracesParams{	Filter: filterSet,})

Lists the traces a rule has evaluated. Supports pagination and rich filtering — see the SDK docs for the filter DSL, allowed columns, and search options.

ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
pagenumberfalse1-indexed page number.
Default: 1
limitnumberfalsePage size, max 100.
Default: 50
searchQuerystringfalseSubstring match against the columns configured by `searchType`.
searchType('id' | 'content')[]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderBy{ column: TraceFilterColumnfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
rule_idstrtrueThe rule's id.
pageOptional[int]false1-indexed page number.
Default: 1
limitOptional[int]falsePage size, max 100.
Default: 50
search_queryOptional[str]falseSubstring match against the columns configured by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterOptional[str]falseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
order_byOptional[str]falseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdStringtrueThe rule's id.
pageIntegerfalse1-indexed page number.
Default: 1
limitIntegerfalsePage size, max 100.
Default: 50
searchQueryStringfalseSubstring match against the columns configured by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
filterStringfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
orderByStringfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.
ParamTypeRequiredDescription
ruleIdstringtrueThe rule's id.
Page*intfalse1-indexed page number.
Default: 1
Limit*intfalsePage size, max 100.
Default: 50
SearchQuery*stringfalseSubstring match against the columns configured by `searchType`.
SearchType[]ListTracesSearchTypefalseJSON-encoded `TracingSearchType[]` — e.g. `["id"]`, `["content"]`, or both. `id` matches small identifier columns; `content` substring-matches input/output text.
Filter*OnlineEvalTraceFilterSetfalseJSON-encoded `OnlineEvalTraceFilterSet` — `{ must?, any? }`. See the schema in components for the shape.
OrderBy*ListTracesOrderByfalseJSON-encoded `{ column: TraceFilterColumn, order: "ASC" | "DESC" }`.

Trace detail (single trace + evaluator scores)

Returns a single trace with all its evaluator scores attached — the same view you'd see when expanding a row in the dashboard.

_, err := client.Trace(context.Background(), traceID)

Fetches a single trace by id, along with its observations and scores. The trace doesn't need to belong to any specific rule — any trace id in your project works. Useful for chaining off the trace list.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id (`.id` from a `listTraces` page or any other source in the project).

Complete example

Every step above, stitched together into one block you can copy and adapt. The ruleID is grabbed off the create response; the traceID is picked from the first row of the list-traces response (fall back to a real trace id if the list is empty on a fresh rule).

// 1. Set up the SDKimport (	"context"	"log"	aisdk "github.com/browserstack/ai-sdk-go")ctx := context.Background()sdk, err := aisdk.New(aisdk.WithCredentials(	"pk-lf-your-public-key",	"sk-lf-your-secret-key",))if err != nil {	log.Fatalf("aisdk.New: %v", err)}client := sdk.OnlineEval()// 2. Per-run variablesname := "Production faithfulness scoring"evaluatorListID := "YOUR_EVALUATOR_LIST_ID"// 3. Create a ruledesc := "Score 25% of production traces on faithfulness evaluator"sr, delay := 25, 120status := truerule, err := client.Create(context.Background(), &CreateOnlineEvalBody{	Name:             vars.name,	Description:      &desc,	SamplingRate:     &sr,	Delay:            &delay,	Status:           &status,	Filters:          &[]OnlineEvalFilter{},	EvaluatorListIds: ptr([]string{evaluatorListID}),})// 4. Grab the id for later stepsruleID := rule.Id// 5. List rulespage, limit := 1, 1res, err := client.List(context.Background(), &ListOnlineEvalsParams{	Page:  &page,	Limit: &limit,})// 6. Fetch a rule by idrule, err := client.Get(context.Background(), ruleID)// 7. Update the rulesr := 80status := falserule, err := client.Update(context.Background(), ruleID, &UpdateOnlineEvalBody{	SamplingRate: &sr,	Status:       &status,})// 8. Aggregated evaluator scoresfrom := time.Date(2026, 6, 24, 0, 0, 0, 0, time.UTC)to := time.Date(2026, 6, 25, 0, 0, 0, 0, time.UTC)granularity := Granularity("hour")resp, err := client.Scores(context.Background(), ruleID, &ScoresParams{	FromTimestamp: &from,	ToTimestamp:   &to,	Granularity:   &granularity,})// 9. Observation metricsgranularity := Granularity("day")resp, err := client.Metrics(context.Background(), ruleID, &MetricsParams{	Granularity: &granularity,})// 10. Traces matched by a rulefilterSet := &OnlineEvalTraceFilterSet{	Must: &[]OnlineEvalTraceFilter{},	Any:  &[]OnlineEvalTraceFilter{},}_, err := client.ListTraces(context.Background(), ruleID, &ListTracesParams{	Filter: filterSet,})// 11. Pick a traceID from the listtraceID := "<TRACE_ID>"if len(resp.Data) > 0 {	traceID = resp.Data[0].Id}// 12. Trace detail with evaluator scores_, err := client.Trace(context.Background(), traceID)// 13. Delete the ruleres, err := client.Delete(context.Background(), ruleID)

See also

  • Online Evaluations UI guide — how to create rules and inspect results in the dashboard.
  • Automation Rules SDK — the newer, unified rule model. New projects should prefer automation rules; existing online-eval rules continue to work.