BrowserStack AI Evals
Tracing

Manage Traces

List, fetch, tag, publish, and add traces to datasets from the SDK across TypeScript, Python, Java, and Go.

Manage Traces

The rest of this section covers emitting traces — auto-instrumentation for OpenAI, Anthropic and others, or manual tracing for spans you build by hand. This page covers the other direction: reading and managing traces that have already been saved — listing them, fetching one by id, tagging, publishing, and adding them to datasets.

Setup

Put your public and secret keys in your environment, then create one client and reuse it for every call on this page.

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,});

List traces

const listResp = await client.traces.list();

Lists the traces in your project, paginated. You can narrow the results using simple filters like `userId`, `name`, `tags`, `environment`, `sessionId`, `version`, `release`, `fromTimestamp`, and `toTimestamp`, or with the richer params: - `searchQuery` — a free-text substring, matched against whichever columns you pick in `searchType` (defaults to `["id"]`). - `filter` — a JSON-encoded `TraceFilterSet` (same shape as the bulk endpoints). Combined with the simple filters using AND. Note: `filter.any` (OR-combined) isn't supported on this endpoint yet — use `filter.must` for AND, or paginate.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
userIdstringfalseFilter by user id.
namestringfalseFilter by trace name (exact match).
tagsstringfalseMatch any-of.
environmentstringfalseMatch any-of.
sessionIdstringfalseFilter by session id.
versionstringfalseFilter by trace version tag (application version).
releasestringfalseFilter by trace release tag.
fromTimestampstringfalseInclusive lower bound, ISO 8601.
toTimestampstringfalseExclusive upper bound, ISO 8601.
orderBystringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQuerystringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypestringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterstringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
user_idOptional[str]falseFilter by user id.
nameOptional[str]falseFilter by trace name (exact match).
tagsOptional[str]falseMatch any-of.
environmentOptional[str]falseMatch any-of.
session_idOptional[str]falseFilter by session id.
versionOptional[str]falseFilter by trace version tag (application version).
releaseOptional[str]falseFilter by trace release tag.
from_timestampOptional[str]falseInclusive lower bound, ISO 8601.
to_timestampOptional[str]falseExclusive upper bound, ISO 8601.
order_byOptional[str]falsee.g. `timestamp.desc`, `timestamp.asc`.
search_queryOptional[str]falseFree-text substring; matched against columns selected by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterOptional[str]falseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
userIdStringfalseFilter by user id.
nameStringfalseFilter by trace name (exact match).
tagsStringfalseMatch any-of.
environmentStringfalseMatch any-of.
sessionIdStringfalseFilter by session id.
versionStringfalseFilter by trace version tag (application version).
releaseStringfalseFilter by trace release tag.
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601.
toTimestampjava.time.InstantfalseExclusive upper bound, ISO 8601.
orderByStringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQueryStringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterStringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
UserId*stringfalseFilter by user id.
Name*stringfalseFilter by trace name (exact match).
Tags*stringfalseMatch any-of.
Environment*stringfalseMatch any-of.
SessionId*stringfalseFilter by session id.
Version*stringfalseFilter by trace version tag (application version).
Release*stringfalseFilter by trace release tag.
FromTimestamp*stringfalseInclusive lower bound, ISO 8601.
ToTimestamp*stringfalseExclusive upper bound, ISO 8601.
OrderBy*stringfalsee.g. `timestamp.desc`, `timestamp.asc`.
SearchQuery*stringfalseFree-text substring; matched against columns selected by `searchType`.
SearchType*stringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
Filter*stringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).

Get a trace by id

Returns the full trace — its observations (spans, generations, events) and any scores attached to it. You'll need a traceId — pull one out of the list you just fetched, or grab one from a trace you emitted with manual tracing or auto-instrumentation.

const got = await client.traces.get(traceId);

Returns the full trace — every observation attached to it (spans, generations, events), every score, the token-usage rollup (`promptTokens` + `completionTokens` + `totalTokens`), total cost, and end-to-end latency in seconds. You get the full observation and score objects, not just their ids.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id

Tag a trace

tag() replaces the trace's tag list — it doesn't merge with what's already there. Pass an empty array to clear all tags.

const taggedTrace = await client.traces.tag(traceId, {  tags: newTags,});

Replaces the trace's tag set with the array you send — it's not additive. Pass `[]` to clear all tags. Safe to call more than once with the same body.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
tagsstring[]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
tagslist[str]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
tagsList<String>trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
Tags[]stringtrueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.

Publish (make public)

Flips the trace's isPublic flag. Public traces have a shareable link that anyone can open without signing in.

const publishedTrace = await client.traces.publish(traceId, { isPublic: true });

Sets the trace's public-share state. Pass `public: true` to mint a public share URL (or keep the existing one), or `public: false` to withdraw it. Safe to call more than once — the body replaces the current state.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
isPublicbooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
is_publicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
isPublicBooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
IsPublicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.

Add traces to a dataset

Add one or more traces to a dataset as new items. A common use case: building a golden dataset from real production traffic. You'll need a datasetId — see the Datasets docs for how to create one or look up an existing one.

const addToDatasetResp = await client.traces.addToDataset({  traceIds: [traceId],  datasetId,});

Queues traces to be added to a dataset. Pass exactly one of `traceIds` (to add specific traces) or `filter` (to add every trace that matches your filter). `datasetId` is always required; `datasetTag` and `mappingType` are optional. Returns `202` with the number of traces queued. There's no job handle to poll — the enqueue is fire-and-forget.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target dataset id — must belong to your project.
datasetTagstring | nullfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
"EXPECTED_OUTPUT" | "LLM_OUTPUT"
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target dataset id — must belong to your project.
dataset_tagOptional[str]falseAn optional label applied to every item added by this call.
mapping_typeOptional[AddToDatasetBodyMappingType]
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target dataset id — must belong to your project.
datasetTagStringfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target dataset id — must belong to your project.
DatasetTag*stringfalseAn optional label applied to every item added by this call.
MappingType*AddToDatasetBodyMappingType
AddToDatasetBodyMappingTypeEXPECTED_OUTPUT, AddToDatasetBodyMappingTypeLLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"

Add traces to an eval dataset

Same as adding to a regular dataset, but the target is an eval dataset — the kind you use for offline evaluation runs, where every item gets scored by an evaluator list.

const addToEvalDatasetResp = await client.traces.addToEvalDataset({  traceIds: [traceId],  datasetId: evalDatasetId,});

Same body shape as `/dataset-items`. Adds traces to an eval dataset — the kind used for offline evaluation runs, where every item gets scored by an evaluator list. One extra check applies: - When you pass `traceIds`, every trace must have an `output`. If any are missing, the call returns `400` with the ids listed. - When you pass `filter`, the check happens when the worker processes each trace — items without an `output` are skipped and logged, and the enqueue itself still succeeds.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target eval dataset id — must belong to your project.

Complete example

Every step above, stitched together into one block you can copy and adapt.

// 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 newTags = ['production', 'checkout', 'p95-latency'];// 3. List tracesconst listResp = await client.traces.list();// 4. Grab a trace id// Grab a trace id — from the list you just fetched, or from a trace// you emitted with the tracing SDK. See the Tracing docs for how to// send traces from your app.const traceId = listResp.data[0]!.id;// 5. Fetch a trace by idconst got = await client.traces.get(traceId);// 6. Tag a traceconst taggedTrace = await client.traces.tag(traceId, {  tags: newTags,});// 7. Publish (make public)const publishedTrace = await client.traces.publish(traceId, { isPublic: true });// 8. Pick or create a dataset// Create a regular dataset — or fetch an existing one by name. See the// Datasets docs for the full API.const regularDatasetName = `traces-example-dataset-${Date.now()}`;const regularDataset = (await client.datasets.create(  regularDatasetName,  undefined,  undefined,  'REGULAR',)) as any;const datasetId = regularDataset.id as string;// 9. Add traces to a datasetconst addToDatasetResp = await client.traces.addToDataset({  traceIds: [traceId],  datasetId,});// 10. Pick or create an eval dataset// Create an evaluation dataset — pass kind='EVALUATION'. See the Datasets// docs for the full API.const evalDatasetName = `traces-example-eval-dataset-${Date.now()}`;const evalDataset = (await client.datasets.create(  evalDatasetName,  undefined,  undefined,  'EVALUATION',)) as any;const evalDatasetId = evalDataset.id as string;// 11. Add traces to an eval datasetconst addToEvalDatasetResp = await client.traces.addToEvalDataset({  traceIds: [traceId],  datasetId: evalDatasetId,});

Setup

Put your public and secret keys in your environment, then create one client and reuse it for every call on this page.

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

List traces

list_resp = client.traces.list()

Lists the traces in your project, paginated. You can narrow the results using simple filters like `userId`, `name`, `tags`, `environment`, `sessionId`, `version`, `release`, `fromTimestamp`, and `toTimestamp`, or with the richer params: - `searchQuery` — a free-text substring, matched against whichever columns you pick in `searchType` (defaults to `["id"]`). - `filter` — a JSON-encoded `TraceFilterSet` (same shape as the bulk endpoints). Combined with the simple filters using AND. Note: `filter.any` (OR-combined) isn't supported on this endpoint yet — use `filter.must` for AND, or paginate.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
userIdstringfalseFilter by user id.
namestringfalseFilter by trace name (exact match).
tagsstringfalseMatch any-of.
environmentstringfalseMatch any-of.
sessionIdstringfalseFilter by session id.
versionstringfalseFilter by trace version tag (application version).
releasestringfalseFilter by trace release tag.
fromTimestampstringfalseInclusive lower bound, ISO 8601.
toTimestampstringfalseExclusive upper bound, ISO 8601.
orderBystringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQuerystringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypestringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterstringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
user_idOptional[str]falseFilter by user id.
nameOptional[str]falseFilter by trace name (exact match).
tagsOptional[str]falseMatch any-of.
environmentOptional[str]falseMatch any-of.
session_idOptional[str]falseFilter by session id.
versionOptional[str]falseFilter by trace version tag (application version).
releaseOptional[str]falseFilter by trace release tag.
from_timestampOptional[str]falseInclusive lower bound, ISO 8601.
to_timestampOptional[str]falseExclusive upper bound, ISO 8601.
order_byOptional[str]falsee.g. `timestamp.desc`, `timestamp.asc`.
search_queryOptional[str]falseFree-text substring; matched against columns selected by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterOptional[str]falseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
userIdStringfalseFilter by user id.
nameStringfalseFilter by trace name (exact match).
tagsStringfalseMatch any-of.
environmentStringfalseMatch any-of.
sessionIdStringfalseFilter by session id.
versionStringfalseFilter by trace version tag (application version).
releaseStringfalseFilter by trace release tag.
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601.
toTimestampjava.time.InstantfalseExclusive upper bound, ISO 8601.
orderByStringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQueryStringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterStringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
UserId*stringfalseFilter by user id.
Name*stringfalseFilter by trace name (exact match).
Tags*stringfalseMatch any-of.
Environment*stringfalseMatch any-of.
SessionId*stringfalseFilter by session id.
Version*stringfalseFilter by trace version tag (application version).
Release*stringfalseFilter by trace release tag.
FromTimestamp*stringfalseInclusive lower bound, ISO 8601.
ToTimestamp*stringfalseExclusive upper bound, ISO 8601.
OrderBy*stringfalsee.g. `timestamp.desc`, `timestamp.asc`.
SearchQuery*stringfalseFree-text substring; matched against columns selected by `searchType`.
SearchType*stringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
Filter*stringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).

Get a trace by id

Returns the full trace — its observations (spans, generations, events) and any scores attached to it. You'll need a trace_id — pull one out of the list you just fetched, or grab one from a trace you emitted with manual tracing or auto-instrumentation.

trace = client.traces.get(trace_id)

Returns the full trace — every observation attached to it (spans, generations, events), every score, the token-usage rollup (`promptTokens` + `completionTokens` + `totalTokens`), total cost, and end-to-end latency in seconds. You get the full observation and score objects, not just their ids.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id

Tag a trace

tag() replaces the trace's tag list — it doesn't merge with what's already there. Pass an empty list to clear all tags.

tagged_trace = client.traces.tag(trace_id, tags=new_tags)

Replaces the trace's tag set with the array you send — it's not additive. Pass `[]` to clear all tags. Safe to call more than once with the same body.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
tagsstring[]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
tagslist[str]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
tagsList<String>trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
Tags[]stringtrueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.

Publish (make public)

Flips the trace's is_public flag. Public traces have a shareable link that anyone can open without signing in.

published_trace = client.traces.publish(trace_id, is_public=True)

Sets the trace's public-share state. Pass `public: true` to mint a public share URL (or keep the existing one), or `public: false` to withdraw it. Safe to call more than once — the body replaces the current state.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
isPublicbooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
is_publicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
isPublicBooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
IsPublicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.

Add traces to a dataset

Add one or more traces to a dataset as new items. A common use case: building a golden dataset from real production traffic. You'll need a dataset_id — see the Datasets docs for how to create one or look up an existing one.

add_to_dataset_resp = client.traces.add_to_dataset(    dataset_id=dataset_id,    trace_ids=[trace_id],    mapping_type="EXPECTED_OUTPUT",)

Queues traces to be added to a dataset. Pass exactly one of `traceIds` (to add specific traces) or `filter` (to add every trace that matches your filter). `datasetId` is always required; `datasetTag` and `mappingType` are optional. Returns `202` with the number of traces queued. There's no job handle to poll — the enqueue is fire-and-forget.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target dataset id — must belong to your project.
datasetTagstring | nullfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
"EXPECTED_OUTPUT" | "LLM_OUTPUT"
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target dataset id — must belong to your project.
dataset_tagOptional[str]falseAn optional label applied to every item added by this call.
mapping_typeOptional[AddToDatasetBodyMappingType]
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target dataset id — must belong to your project.
datasetTagStringfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target dataset id — must belong to your project.
DatasetTag*stringfalseAn optional label applied to every item added by this call.
MappingType*AddToDatasetBodyMappingType
AddToDatasetBodyMappingTypeEXPECTED_OUTPUT, AddToDatasetBodyMappingTypeLLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"

Add traces to an eval dataset

Same as adding to a regular dataset, but the target is an eval dataset — the kind you use for offline evaluation runs, where every item gets scored by an evaluator list.

add_to_eval_dataset_resp = client.traces.add_to_eval_dataset(    dataset_id=eval_dataset_id,    trace_ids=[trace_id],)

Same body shape as `/dataset-items`. Adds traces to an eval dataset — the kind used for offline evaluation runs, where every item gets scored by an evaluator list. One extra check applies: - When you pass `traceIds`, every trace must have an `output`. If any are missing, the call returns `400` with the ids listed. - When you pass `filter`, the check happens when the worker processes each trace — items without an `output` are skipped and logged, and the enqueue itself still succeeds.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target eval dataset id — must belong to your project.

Complete example

Every step above, stitched together into one block you can copy and adapt.

# 1. Set up the clientimport osimport timefrom browserstack_ai_sdk import AISDKclient = AISDK(    public_key=os.environ["AISDK_PUBLIC_KEY"],    secret_key=os.environ["AISDK_SECRET_KEY"],)# 2. Per-run variablesnew_tags = ["production", "checkout", "p95-latency"]# 3. List traceslist_resp = client.traces.list()# 4. Grab a trace id# Grab a trace id — from the list you just fetched, or from a trace# you emitted with the tracing SDK. See the Tracing docs for how to# send traces from your app.trace_id = list_resp.data[0].id# 5. Fetch a trace by idtrace = client.traces.get(trace_id)# 6. Tag a tracetagged_trace = client.traces.tag(trace_id, tags=new_tags)# 7. Publish (make public)published_trace = client.traces.publish(trace_id, is_public=True)# 8. Pick or create a dataset# Create a regular dataset — or pass an existing dataset's name. See# the Datasets docs for the full API.regular_dataset_name = f"traces-example-dataset-{int(time.time() * 1000)}"regular_dataset = client.datasets.create(name=regular_dataset_name, kind="REGULAR")dataset_id = regular_dataset["id"] if isinstance(regular_dataset, dict) else regular_dataset.id# 9. Add traces to a datasetadd_to_dataset_resp = client.traces.add_to_dataset(    dataset_id=dataset_id,    trace_ids=[trace_id],    mapping_type="EXPECTED_OUTPUT",)# 10. Pick or create an eval dataset# Create an evaluation dataset — pass kind='EVALUATION'. See the# Datasets docs for the full API.eval_dataset_name = f"traces-example-eval-dataset-{int(time.time() * 1000)}"eval_dataset = client.datasets.create(name=eval_dataset_name, kind="EVALUATION")eval_dataset_id = eval_dataset["id"] if isinstance(eval_dataset, dict) else eval_dataset.id# 11. Add traces to an eval datasetadd_to_eval_dataset_resp = client.traces.add_to_eval_dataset(    dataset_id=eval_dataset_id,    trace_ids=[trace_id],)

Setup

Put your public and secret keys in your environment, then create one SDK instance and reuse it for every call on this page.

import com.browserstack.aisdk.AISDK;import com.browserstack.aisdk.clients.traces.AddToDatasetBody;import com.browserstack.aisdk.clients.traces.AddToEvalDatasetBody;import com.browserstack.aisdk.clients.traces.EnqueueDatasetItemsResponse;import com.browserstack.aisdk.clients.traces.FilterOperator;import com.browserstack.aisdk.clients.traces.ListTracesParams;import com.browserstack.aisdk.clients.traces.ListTracesResponse;import com.browserstack.aisdk.clients.traces.PublishTraceBody;import com.browserstack.aisdk.clients.traces.Trace;import com.browserstack.aisdk.clients.traces.TraceDetail;import com.browserstack.aisdk.clients.traces.TraceFilter;import com.browserstack.aisdk.clients.traces.TraceFilterSet;import com.browserstack.aisdk.clients.traces.Traces;import com.browserstack.aisdk.clients.traces.UpdateTraceTagsBody;import java.util.Arrays;import java.util.Collections;AISDK sdk = AISDK.builder()    .publicKey(System.getenv("BROWSERSTACK_PUBLIC_KEY"))    .secretKey(System.getenv("BROWSERSTACK_SECRET_KEY"))    .build();Traces traces = sdk.traces();

List traces

ListTracesResponse listResp = client.list(null);

Lists the traces in your project, paginated. You can narrow the results using simple filters like `userId`, `name`, `tags`, `environment`, `sessionId`, `version`, `release`, `fromTimestamp`, and `toTimestamp`, or with the richer params: - `searchQuery` — a free-text substring, matched against whichever columns you pick in `searchType` (defaults to `["id"]`). - `filter` — a JSON-encoded `TraceFilterSet` (same shape as the bulk endpoints). Combined with the simple filters using AND. Note: `filter.any` (OR-combined) isn't supported on this endpoint yet — use `filter.must` for AND, or paginate.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
userIdstringfalseFilter by user id.
namestringfalseFilter by trace name (exact match).
tagsstringfalseMatch any-of.
environmentstringfalseMatch any-of.
sessionIdstringfalseFilter by session id.
versionstringfalseFilter by trace version tag (application version).
releasestringfalseFilter by trace release tag.
fromTimestampstringfalseInclusive lower bound, ISO 8601.
toTimestampstringfalseExclusive upper bound, ISO 8601.
orderBystringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQuerystringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypestringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterstringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
user_idOptional[str]falseFilter by user id.
nameOptional[str]falseFilter by trace name (exact match).
tagsOptional[str]falseMatch any-of.
environmentOptional[str]falseMatch any-of.
session_idOptional[str]falseFilter by session id.
versionOptional[str]falseFilter by trace version tag (application version).
releaseOptional[str]falseFilter by trace release tag.
from_timestampOptional[str]falseInclusive lower bound, ISO 8601.
to_timestampOptional[str]falseExclusive upper bound, ISO 8601.
order_byOptional[str]falsee.g. `timestamp.desc`, `timestamp.asc`.
search_queryOptional[str]falseFree-text substring; matched against columns selected by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterOptional[str]falseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
userIdStringfalseFilter by user id.
nameStringfalseFilter by trace name (exact match).
tagsStringfalseMatch any-of.
environmentStringfalseMatch any-of.
sessionIdStringfalseFilter by session id.
versionStringfalseFilter by trace version tag (application version).
releaseStringfalseFilter by trace release tag.
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601.
toTimestampjava.time.InstantfalseExclusive upper bound, ISO 8601.
orderByStringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQueryStringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterStringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
UserId*stringfalseFilter by user id.
Name*stringfalseFilter by trace name (exact match).
Tags*stringfalseMatch any-of.
Environment*stringfalseMatch any-of.
SessionId*stringfalseFilter by session id.
Version*stringfalseFilter by trace version tag (application version).
Release*stringfalseFilter by trace release tag.
FromTimestamp*stringfalseInclusive lower bound, ISO 8601.
ToTimestamp*stringfalseExclusive upper bound, ISO 8601.
OrderBy*stringfalsee.g. `timestamp.desc`, `timestamp.asc`.
SearchQuery*stringfalseFree-text substring; matched against columns selected by `searchType`.
SearchType*stringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
Filter*stringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).

Get a trace by id

Returns the full trace — its observations (spans, generations, events) and any scores attached to it. You'll need a traceId — pull one out of the list you just fetched, or grab one from a trace you emitted with manual tracing or auto-instrumentation.

TraceDetail got = client.get(traceId);

Returns the full trace — every observation attached to it (spans, generations, events), every score, the token-usage rollup (`promptTokens` + `completionTokens` + `totalTokens`), total cost, and end-to-end latency in seconds. You get the full observation and score objects, not just their ids.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id

Tag a trace

tag() replaces the trace's tag list — it doesn't merge with what's already there. Pass an empty list to clear all tags.

UpdateTraceTagsBody tagBody = new UpdateTraceTagsBody();tagBody.tags = newTags;Trace taggedTrace = client.tag(traceId, tagBody);

Replaces the trace's tag set with the array you send — it's not additive. Pass `[]` to clear all tags. Safe to call more than once with the same body.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
tagsstring[]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
tagslist[str]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
tagsList<String>trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
Tags[]stringtrueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.

Publish (make public)

Flips the trace's isPublic flag. Public traces have a shareable link that anyone can open without signing in.

PublishTraceBody publishBody = new PublishTraceBody();publishBody.isPublic = true;Trace publishedTrace = client.publish(traceId, publishBody);

Sets the trace's public-share state. Pass `public: true` to mint a public share URL (or keep the existing one), or `public: false` to withdraw it. Safe to call more than once — the body replaces the current state.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
isPublicbooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
is_publicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
isPublicBooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
IsPublicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.

Add traces to a dataset

Add one or more traces to a dataset as new items. A common use case: building a golden dataset from real production traffic. You'll need a datasetId — see the Datasets docs for how to create one or look up an existing one.

AddToDatasetBody addToDatasetBody = new AddToDatasetBody();addToDatasetBody.traceIds = Arrays.asList(traceId1, traceId2);addToDatasetBody.datasetId = datasetId;EnqueueDatasetItemsResponse addToDatasetResp = client.addToDataset(addToDatasetBody);

Queues traces to be added to a dataset. Pass exactly one of `traceIds` (to add specific traces) or `filter` (to add every trace that matches your filter). `datasetId` is always required; `datasetTag` and `mappingType` are optional. Returns `202` with the number of traces queued. There's no job handle to poll — the enqueue is fire-and-forget.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target dataset id — must belong to your project.
datasetTagstring | nullfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
"EXPECTED_OUTPUT" | "LLM_OUTPUT"
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target dataset id — must belong to your project.
dataset_tagOptional[str]falseAn optional label applied to every item added by this call.
mapping_typeOptional[AddToDatasetBodyMappingType]
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target dataset id — must belong to your project.
datasetTagStringfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target dataset id — must belong to your project.
DatasetTag*stringfalseAn optional label applied to every item added by this call.
MappingType*AddToDatasetBodyMappingType
AddToDatasetBodyMappingTypeEXPECTED_OUTPUT, AddToDatasetBodyMappingTypeLLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"

Add traces to an eval dataset

Same as adding to a regular dataset, but the target is an eval dataset — the kind you use for offline evaluation runs, where every item gets scored by an evaluator list.

AddToEvalDatasetBody addToEvalDatasetBody = new AddToEvalDatasetBody();addToEvalDatasetBody.traceIds = Collections.singletonList(traceId);addToEvalDatasetBody.datasetId = evalDatasetId;EnqueueDatasetItemsResponse addToEvalDatasetResp = client.addToEvalDataset(addToEvalDatasetBody);

Same body shape as `/dataset-items`. Adds traces to an eval dataset — the kind used for offline evaluation runs, where every item gets scored by an evaluator list. One extra check applies: - When you pass `traceIds`, every trace must have an `output`. If any are missing, the call returns `400` with the ids listed. - When you pass `filter`, the check happens when the worker processes each trace — items without an `output` are skipped and logged, and the enqueue itself still succeeds.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target eval dataset id — must belong to your project.

Complete example

Every step above, stitched together into one block you can copy and adapt. Fill in traceId / datasetId / evalDatasetId where a later step needs the id.

// 1. Set up the SDKimport com.browserstack.aisdk.AISDK;import com.browserstack.aisdk.clients.traces.AddToDatasetBody;import com.browserstack.aisdk.clients.traces.AddToEvalDatasetBody;import com.browserstack.aisdk.clients.traces.EnqueueDatasetItemsResponse;import com.browserstack.aisdk.clients.traces.FilterOperator;import com.browserstack.aisdk.clients.traces.ListTracesParams;import com.browserstack.aisdk.clients.traces.ListTracesResponse;import com.browserstack.aisdk.clients.traces.PublishTraceBody;import com.browserstack.aisdk.clients.traces.Trace;import com.browserstack.aisdk.clients.traces.TraceDetail;import com.browserstack.aisdk.clients.traces.TraceFilter;import com.browserstack.aisdk.clients.traces.TraceFilterSet;import com.browserstack.aisdk.clients.traces.Traces;import com.browserstack.aisdk.clients.traces.UpdateTraceTagsBody;import java.util.Arrays;import java.util.Collections;AISDK sdk = AISDK.builder()    .publicKey(System.getenv("BROWSERSTACK_PUBLIC_KEY"))    .secretKey(System.getenv("BROWSERSTACK_SECRET_KEY"))    .build();Traces traces = sdk.traces();// 2. Per-run variablesjava.util.List<String> newTags = java.util.Arrays.asList(    "production", "checkout", "p95-latency");// 3. List tracesListTracesResponse listResp = client.list(null);// 4. Grab a trace id// Grab a trace id — from the list you just fetched, or from a trace// you emitted with the tracing SDK. See the Tracing docs for how to// send traces from your app.String traceId = "trace_get_target";// 5. Fetch a trace by idTraceDetail got = client.get(traceId);// 6. Tag a traceUpdateTraceTagsBody tagBody = new UpdateTraceTagsBody();tagBody.tags = newTags;Trace taggedTrace = client.tag(traceId, tagBody);// 7. Publish (make public)PublishTraceBody publishBody = new PublishTraceBody();publishBody.isPublic = true;Trace publishedTrace = client.publish(traceId, publishBody);// 8. Pick or create a dataset// Pick a regular dataset — or create one. See the Datasets docs for// the full API.String datasetId = "dataset_regular_target";// 9. Add traces to a datasetAddToDatasetBody addToDatasetBody = new AddToDatasetBody();addToDatasetBody.traceIds = Arrays.asList(traceId1, traceId2);addToDatasetBody.datasetId = datasetId;EnqueueDatasetItemsResponse addToDatasetResp = client.addToDataset(addToDatasetBody);// 10. Pick or create an eval dataset// Pick an evaluation dataset — or create one. Pass kind="EVALUATION"// when creating. See the Datasets docs for the full API.String evalDatasetId = "dataset_eval_target";// 11. Add traces to an eval datasetAddToEvalDatasetBody addToEvalDatasetBody = new AddToEvalDatasetBody();addToEvalDatasetBody.traceIds = Collections.singletonList(traceId);addToEvalDatasetBody.datasetId = evalDatasetId;EnqueueDatasetItemsResponse addToEvalDatasetResp = client.addToEvalDataset(addToEvalDatasetBody);

Setup

Put your public and secret keys in your environment, then create one SDK instance and reuse it for every call on this page.

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.Traces()

List traces

listResp, err := client.List(context.Background(), nil)

Lists the traces in your project, paginated. You can narrow the results using simple filters like `userId`, `name`, `tags`, `environment`, `sessionId`, `version`, `release`, `fromTimestamp`, and `toTimestamp`, or with the richer params: - `searchQuery` — a free-text substring, matched against whichever columns you pick in `searchType` (defaults to `["id"]`). - `filter` — a JSON-encoded `TraceFilterSet` (same shape as the bulk endpoints). Combined with the simple filters using AND. Note: `filter.any` (OR-combined) isn't supported on this endpoint yet — use `filter.must` for AND, or paginate.

ParamTypeRequiredDescription
pagenumberfalse1-indexed page number (default 1)
Default: 1
limitnumberfalsePage size, max 100 (default 50)
Default: 50
userIdstringfalseFilter by user id.
namestringfalseFilter by trace name (exact match).
tagsstringfalseMatch any-of.
environmentstringfalseMatch any-of.
sessionIdstringfalseFilter by session id.
versionstringfalseFilter by trace version tag (application version).
releasestringfalseFilter by trace release tag.
fromTimestampstringfalseInclusive lower bound, ISO 8601.
toTimestampstringfalseExclusive upper bound, ISO 8601.
orderBystringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQuerystringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypestringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterstringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageOptional[int]false1-indexed page number (default 1)
Default: 1
limitOptional[int]falsePage size, max 100 (default 50)
Default: 50
user_idOptional[str]falseFilter by user id.
nameOptional[str]falseFilter by trace name (exact match).
tagsOptional[str]falseMatch any-of.
environmentOptional[str]falseMatch any-of.
session_idOptional[str]falseFilter by session id.
versionOptional[str]falseFilter by trace version tag (application version).
releaseOptional[str]falseFilter by trace release tag.
from_timestampOptional[str]falseInclusive lower bound, ISO 8601.
to_timestampOptional[str]falseExclusive upper bound, ISO 8601.
order_byOptional[str]falsee.g. `timestamp.desc`, `timestamp.asc`.
search_queryOptional[str]falseFree-text substring; matched against columns selected by `searchType`.
search_typeOptional[str]falseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterOptional[str]falseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
pageIntegerfalse1-indexed page number (default 1)
Default: 1
limitIntegerfalsePage size, max 100 (default 50)
Default: 50
userIdStringfalseFilter by user id.
nameStringfalseFilter by trace name (exact match).
tagsStringfalseMatch any-of.
environmentStringfalseMatch any-of.
sessionIdStringfalseFilter by session id.
versionStringfalseFilter by trace version tag (application version).
releaseStringfalseFilter by trace release tag.
fromTimestampjava.time.InstantfalseInclusive lower bound, ISO 8601.
toTimestampjava.time.InstantfalseExclusive upper bound, ISO 8601.
orderByStringfalsee.g. `timestamp.desc`, `timestamp.asc`.
searchQueryStringfalseFree-text substring; matched against columns selected by `searchType`.
searchTypeStringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
filterStringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).
ParamTypeRequiredDescription
Page*intfalse1-indexed page number (default 1)
Default: 1
Limit*intfalsePage size, max 100 (default 50)
Default: 50
UserId*stringfalseFilter by user id.
Name*stringfalseFilter by trace name (exact match).
Tags*stringfalseMatch any-of.
Environment*stringfalseMatch any-of.
SessionId*stringfalseFilter by session id.
Version*stringfalseFilter by trace version tag (application version).
Release*stringfalseFilter by trace release tag.
FromTimestamp*stringfalseInclusive lower bound, ISO 8601.
ToTimestamp*stringfalseExclusive upper bound, ISO 8601.
OrderBy*stringfalsee.g. `timestamp.desc`, `timestamp.asc`.
SearchQuery*stringfalseFree-text substring; matched against columns selected by `searchType`.
SearchType*stringfalseJSON-encoded `TracingSearchType[]` — `["id"]`, `["content"]`, or both. Default (omitted) applies as `["id"]`.
Filter*stringfalseJSON-encoded `TraceFilterSet` — `{ must?, any? }`. `must` = AND-combined; `any` = OR-combined. Currently only `must` is honored on this endpoint (v1 limitation).

Get a trace by id

Returns the full trace — its observations (spans, generations, events) and any scores attached to it. You'll need a traceID — pull one out of the list you just fetched, or grab one from a trace you emitted with manual tracing or auto-instrumentation.

got, err := client.Get(context.Background(), traceID)

Returns the full trace — every observation attached to it (spans, generations, events), every score, the token-usage rollup (`promptTokens` + `completionTokens` + `totalTokens`), total cost, and end-to-end latency in seconds. You get the full observation and score objects, not just their ids.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id

Tag a trace

Tag() replaces the trace's tag list — it doesn't merge with what's already there. Pass an empty slice to clear all tags.

taggedTrace, err := client.Tag(context.Background(), traceID, &UpdateTraceTagsBody{Tags: newTags})

Replaces the trace's tag set with the array you send — it's not additive. Pass `[]` to clear all tags. Safe to call more than once with the same body.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
tagsstring[]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
tagslist[str]trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
tagsList<String>trueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
Tags[]stringtrueThe new tag set — this replaces whatever was there before. Pass `[]` to clear all tags.

Publish (make public)

Flips the trace's IsPublic flag. Public traces have a shareable link that anyone can open without signing in.

publishedTrace, err := client.Publish(context.Background(), traceID, &PublishTraceBody{IsPublic: true})

Sets the trace's public-share state. Pass `public: true` to mint a public share URL (or keep the existing one), or `public: false` to withdraw it. Safe to call more than once — the body replaces the current state.

ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
isPublicbooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
trace_idstrtrueThe trace's id
is_publicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdStringtrueThe trace's id
isPublicBooleantrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.
ParamTypeRequiredDescription
traceIdstringtrueThe trace's id
IsPublicbooltrueWhether the trace should have a public share URL. `true` mints one; `false` withdraws it.

Add traces to a dataset

Add one or more traces to a dataset as new items. A common use case: building a golden dataset from real production traffic. You'll need a datasetID — see the Datasets docs for how to create one or look up an existing one.

addToDatasetResp, err := client.AddToDataset(context.Background(), &AddToDatasetBody{	TraceIds:  &[]string{traceID},	DatasetId: datasetID,})

Queues traces to be added to a dataset. Pass exactly one of `traceIds` (to add specific traces) or `filter` (to add every trace that matches your filter). `datasetId` is always required; `datasetTag` and `mappingType` are optional. Returns `202` with the number of traces queued. There's no job handle to poll — the enqueue is fire-and-forget.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target dataset id — must belong to your project.
datasetTagstring | nullfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
"EXPECTED_OUTPUT" | "LLM_OUTPUT"
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target dataset id — must belong to your project.
dataset_tagOptional[str]falseAn optional label applied to every item added by this call.
mapping_typeOptional[AddToDatasetBodyMappingType]
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target dataset id — must belong to your project.
datasetTagStringfalseAn optional label applied to every item added by this call.
mappingTypeAddToDatasetBodyMappingType
AddToDatasetBodyMappingType.EXPECTED_OUTPUT, AddToDatasetBodyMappingType.LLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target dataset id — must belong to your project.
DatasetTag*stringfalseAn optional label applied to every item added by this call.
MappingType*AddToDatasetBodyMappingType
AddToDatasetBodyMappingTypeEXPECTED_OUTPUT, AddToDatasetBodyMappingTypeLLM_OUTPUT
falseHow the trace becomes a dataset item.
Default: "EXPECTED_OUTPUT"

Add traces to an eval dataset

Same as adding to a regular dataset, but the target is an eval dataset — the kind you use for offline evaluation runs, where every item gets scored by an evaluator list.

addToEvalDatasetResp, err := client.AddToEvalDataset(context.Background(), &AddToEvalDatasetBody{	TraceIds:  &[]string{traceID},	DatasetId: evalDatasetID,})

Same body shape as `/dataset-items`. Adds traces to an eval dataset — the kind used for offline evaluation runs, where every item gets scored by an evaluator list. One extra check applies: - When you pass `traceIds`, every trace must have an `output`. If any are missing, the call returns `400` with the ids listed. - When you pass `filter`, the check happens when the worker processes each trace — items without an `output` are skipped and logged, and the enqueue itself still succeeds.

ParamTypeRequiredDescription
traceIdsstring[]falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdstringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
trace_idsOptional[list[str]]falseThe specific trace ids to add. Can't be combined with `filter`.
filterOptional[TraceFilterSet]falseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
dataset_idstrtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
traceIdsList<String>falseThe specific trace ids to add. Can't be combined with `filter`.
filterTraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
datasetIdStringtrueThe target eval dataset id — must belong to your project.
ParamTypeRequiredDescription
TraceIds*[]stringfalseThe specific trace ids to add. Can't be combined with `filter`.
Filter*TraceFilterSetfalseA filter that picks the traces to add. Can't be combined with `traceIds`.
Filter.mustTraceFilter[]falseEvery entry must match (combined with AND).
Filter.anyTraceFilter[]falseAt least one entry must match (combined with OR). Not supported yet on `GET /traces` or the bulk add-to-dataset endpoints — use `must` for now.
DatasetIdstringtrueThe target eval dataset id — must belong to your project.

Complete example

Every step above, stitched together into one block you can copy and adapt. Fill in traceID / datasetID / evalDatasetID where a later step needs the id.

// 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.Traces()// 2. Per-run variablesnewTags := []string{"production", "checkout", "p95-latency"}// 3. List traceslistResp, err := client.List(context.Background(), nil)// 4. Grab a trace id// Grab a trace id — from the list you just fetched, or from a trace// you emitted with the tracing SDK. See the Tracing docs for how to// send traces from your app.traceID := "trace_get_target"// 5. Fetch a trace by idgot, err := client.Get(context.Background(), traceID)// 6. Tag a tracetaggedTrace, err := client.Tag(context.Background(), traceID, &UpdateTraceTagsBody{Tags: newTags})// 7. Publish (make public)publishedTrace, err := client.Publish(context.Background(), traceID, &PublishTraceBody{IsPublic: true})// 8. Pick or create a dataset// Pick a regular dataset — or create one. See the Datasets docs for// the full API.datasetID := "dataset_1"// 9. Add traces to a datasetaddToDatasetResp, err := client.AddToDataset(context.Background(), &AddToDatasetBody{	TraceIds:  &[]string{traceID},	DatasetId: datasetID,})// 10. Pick or create an eval dataset// Pick an evaluation dataset — or create one. Pass kind="EVALUATION"// when creating. See the Datasets docs for the full API.evalDatasetID := "eval_dataset_1"// 11. Add traces to an eval datasetaddToEvalDatasetResp, err := client.AddToEvalDataset(context.Background(), &AddToEvalDatasetBody{	TraceIds:  &[]string{traceID},	DatasetId: evalDatasetID,})

See also