The Netra SDK exposes a usage client that lets you query:
Session-level usage - tokens, requests, and cost per session
Tenant-level usage - aggregated metrics across a tenant
Traces - list and iterate through traces within a time range
Spans - drill into individual spans for a given trace
This page shows how to use netra.usage to retrieve usage and tracing data and how to work efficiently with pagination.
Getting Started
The usage client is available on the main Netra entry point after initialization.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({
apiKey: "your-api-key" ,
});
// Access the usage client
await client . usage . getSessionUsage ( ... );
await client . usage . getTenantUsage ( ... );
await client . usage . listTraces ( ... );
await client . usage . listSpansByTraceId ( ... );
getSessionUsage
Fetch usage metrics for a single session between a start and end time.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({ apiKey: "..." });
const sessionUsage = await client . usage . getSessionUsage (
"b8a359f8-f28c-4e88-839f-c5db103e9943" , // sessionId
"2026-01-01T00:00:00.000Z" , // startTime
"2026-01-31T23:59:59.000Z" // endTime
);
if ( sessionUsage ) {
console . log ( "Session:" , sessionUsage . sessionId );
console . log ( "Tokens:" , sessionUsage . tokenCount );
console . log ( "Requests:" , sessionUsage . requestCount );
console . log ( "Total cost (USD):" , sessionUsage . totalCost );
}
Parameters
Parameter Type Description sessionIdstringUnique identifier of the session startTimestringStart of time window (ISO 8601 UTC, e.g., "2026-01-01T00:00:00.000Z") endTimestringEnd of time window (ISO 8601 UTC)
Response: SessionUsageData
Field Type Description sessionIdstringThe session identifier tokenCountnumberTotal tokens used requestCountnumberNumber of requests totalCostnumberTotal cost in USD
getTenantUsage
Fetch aggregated usage metrics for a tenant across all sessions.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({ apiKey: "..." });
const tenantUsage = await client . usage . getTenantUsage (
"AceTech" , // tenantId
"2026-01-01T00:00:00.000Z" , // startTime
"2026-01-31T23:59:59.000Z" // endTime
);
if ( tenantUsage ) {
console . log ( "Tenant:" , tenantUsage . tenantId );
console . log ( "Org:" , tenantUsage . organisationId );
console . log ( "Tokens:" , tenantUsage . tokenCount );
console . log ( "Requests:" , tenantUsage . requestCount );
console . log ( "Sessions:" , tenantUsage . sessionCount );
console . log ( "Total cost (USD):" , tenantUsage . totalCost );
}
Parameters
Parameter Type Description tenantIdstringIdentifier of the tenant (e.g., customer organization) startTimestringStart of time window (ISO 8601 UTC) endTimestringEnd of time window (ISO 8601 UTC)
Response: TenantUsageData
Field Type Description tenantIdstringThe tenant identifier organisationIdstringOrganization identifier tokenCountnumberTotal tokens used requestCountnumberNumber of requests sessionCountnumberNumber of sessions totalCostnumberTotal cost in USD
listTraces
Query traces for a time range with optional filtering and pagination.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({ apiKey: "..." });
const tracesPage = await client . usage . listTraces ({
startTime: "2026-01-01T00:00:00.000Z" ,
endTime: "2026-01-31T23:59:59.000Z" ,
tenantId: "AceTech" ,
userId: "Jerina" ,
sessionId: "b8a359f8-f28c-4e88-839f-c5db103e9943" ,
limit: 10 ,
// cursor: undefined,
direction: "down" ,
sortField: "start_time" ,
sortOrder: "desc" ,
});
if ( tracesPage ) {
for ( const trace of tracesPage . traces ) {
console . log ( trace . id , trace . name , trace . totalTokens , trace . totalCost );
}
console . log ( "Has next page?" , tracesPage . hasNextPage );
console . log ( "Next cursor:" , tracesPage . nextCursor );
// Pagination
if ( tracesPage . hasNextPage && tracesPage . nextCursor ) {
const nextPage = await client . usage . listTraces ({
startTime: "2026-01-01T00:00:00.000Z" ,
endTime: "2026-01-31T23:59:59.000Z" ,
tenantId: "AceTech" ,
limit: 10 ,
cursor: tracesPage . nextCursor ,
direction: "down" ,
});
}
}
Parameters (ListTracesParams)
Parameter Type Description startTimestringStart of time range (ISO 8601 UTC) endTimestringEnd of time range (ISO 8601 UTC) tenantIdstring?Filter by tenant ID userIdstring?Filter by user ID sessionIdstring?Filter by session ID limitnumber?Maximum traces per page cursorstring?Pagination cursor from previous page direction"up" | "down"Pagination direction (default: "down") sortFieldstring?Field to sort by (e.g., "start_time") sortOrder"asc" | "desc"Sort order
Response: TracesPage
Field Type Description tracesTraceSummary[]List of trace summaries hasNextPagebooleanWhether more pages exist nextCursorstring?Cursor for next page
Field Type Description idstringUnique trace identifier namestringTrace name totalTokensnumberTotal tokens in trace totalCostnumberTotal cost in USD startTimestringTrace start timestamp endTimestringTrace end timestamp
Value Description "down"Fetch newer/forward in time "up"Fetch older/backwards in time
iterTraces
Iterator that automatically handles pagination when streaming through all traces.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({ apiKey: "..." });
const iterator = client . usage . iterTraces ({
startTime: "2026-01-01T00:00:00.000Z" ,
endTime: "2026-01-31T23:59:59.000Z" ,
tenantId: "AceTech" ,
userId: "Jerina" ,
sessionId: "b8a359f8-f28c-4e88-839f-c5db103e9943" ,
limit: 10 ,
direction: "down" ,
sortField: "start_time" ,
sortOrder: "desc" ,
});
for await ( const trace of iterator ) {
console . log ( trace . id , trace . name , trace . totalCost );
}
Parameters
Same as listTraces (ListTracesParams).
The iterator handles pagination automatically using TracesPage.hasNextPage and TracesPage.nextCursor. It stops when there are no more pages.
listSpansByTraceId
Fetch spans within a single trace with optional filtering and pagination.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({ apiKey: "..." });
const spansPage = await client . usage . listSpansByTraceId ({
traceId: "728c1de6fa4c53de143a7d7fef33ff91" ,
direction: "down" ,
limit: 10 ,
spanName: "openai.chat" ,
});
if ( spansPage ) {
for ( const span of spansPage . spans ) {
console . log ( span . id , span . name , span . kind , span . latencyMs );
}
console . log ( "Has next page?" , spansPage . hasNextPage );
console . log ( "Next cursor:" , spansPage . nextCursor );
}
Parameters (ListSpansParams)
Parameter Type Description traceIdstringID of the trace to fetch spans from cursorstring?Pagination cursor from previous page direction"up" | "down"Pagination direction (default: "down") limitnumber?Maximum spans per page spanNamestring?Filter by span name
Response: SpansPage
Field Type Description spansTraceSpan[]List of span objects hasNextPagebooleanWhether more pages exist nextCursorstring?Cursor for next page
Field Type Description idstringUnique span identifier namestringSpan name kindstringSpan type (e.g., "generation", "tool") latencyMsnumberDuration in milliseconds startTimeMsstringSpan start timestamp endTimeMsstringSpan end timestamp
iterSpansByTraceId
Iterator that automatically handles pagination when walking through all spans of a trace.
import { Netra } from "netra-sdk-js" ;
const client = new Netra ({ apiKey: "..." });
const iterator = client . usage . iterSpansByTraceId ({
traceId: "728c1de6fa4c53de143a7d7fef33ff91" ,
direction: "down" ,
limit: 100 ,
spanName: "generation_pipeline" ,
});
for await ( const span of iterator ) {
console . log (
`Span: ${ span . id } , name= ${ span . name } , kind= ${ span . kind } , duration_ms= ${ span . latencyMs } `
);
}
Parameters
Same as listSpansByTraceId (ListSpansParams).
When to Use Which API
Usage APIs getSessionUsage / getTenantUsageHigh-level reporting: tokens, requests, and cost per session or tenant. Use for billing dashboards and cost analysis.
Traces APIs listTraces / iterTracesExplore what traces exist in a time window, optionally filtered by session, user, or tenant. Use for debugging and monitoring.
Spans APIs listSpansByTraceId / iterSpansByTraceIdDrill into a single trace to understand all spans (tools, generations, workflows) that occurred. Use for detailed trace analysis.
Iterators iter* methodsWhen you need to process all results without manually handling pagination. The iterator fetches pages on-demand.
Complete Example
import { Netra } from "netra-sdk-js" ;
async function main () {
// Initialize the SDK
const client = new Netra ({
apiKey: "your-api-key" ,
});
// Get session-level usage
const sessionUsage = await client . usage . getSessionUsage (
"session-123" ,
"2026-01-01T00:00:00.000Z" ,
"2026-01-31T23:59:59.000Z"
);
if ( sessionUsage ) {
console . log ( `Session cost: $ ${ sessionUsage . totalCost . toFixed ( 4 ) } ` );
}
// Get tenant-level usage
const tenantUsage = await client . usage . getTenantUsage (
"AceTech" ,
"2026-01-01T00:00:00.000Z" ,
"2026-01-31T23:59:59.000Z"
);
if ( tenantUsage ) {
console . log (
`Tenant total: ${ tenantUsage . sessionCount } sessions, $ ${ tenantUsage . totalCost . toFixed ( 4 ) } `
);
}
// Iterate through all traces for a tenant
const tracesIterator = client . usage . iterTraces ({
startTime: "2026-01-01T00:00:00.000Z" ,
endTime: "2026-01-31T23:59:59.000Z" ,
tenantId: "AceTech" ,
sortField: "start_time" ,
sortOrder: "desc" ,
});
for await ( const trace of tracesIterator ) {
console . log ( `Trace ${ trace . id } : ${ trace . name } - $ ${ ( trace . totalCost || 0 ). toFixed ( 4 ) } ` );
// Drill into spans for each trace
const spansIterator = client . usage . iterSpansByTraceId ({
traceId: trace . id
});
for await ( const span of spansIterator ) {
console . log ( ` └─ ${ span . name } ( ${ span . kind } ): ${ span . latencyMs } ms` );
}
}
}
main ();
Next Steps