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.
from netra import Netra
Netra.init( app_name = "sample-app" )
# Access the usage client
Netra.usage.get_session_usage( ... )
Netra.usage.get_tenant_usage( ... )
Netra.usage.list_traces( ... )
Netra.usage.list_spans_by_trace_id( ... )
get_session_usage
Fetch usage metrics for a single session between a start and end time.
from netra import Netra
Netra.init( app_name = "sample-app" )
session_usage = Netra.usage.get_session_usage(
session_id = "b8a359f8-f28c-4e88-839f-c5db103e9943" ,
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
)
if session_usage:
print ( "Session:" , session_usage.session_id)
print ( "Tokens:" , session_usage.token_count)
print ( "Requests:" , session_usage.request_count)
print ( "Total cost (USD):" , session_usage.total_cost)
Parameters
Parameter Type Description session_idstrUnique identifier of the session start_timestrStart of time window (ISO 8601 UTC, e.g., "2026-01-01T00:00:00.000Z") end_timestrEnd of time window (ISO 8601 UTC)
Response: SessionUsageData
Field Type Description session_idstrThe session identifier token_countintTotal tokens used request_countintNumber of requests total_costfloatTotal cost in USD
get_tenant_usage
Fetch aggregated usage metrics for a tenant across all sessions.
from netra import Netra
Netra.init( app_name = "sample-app" )
tenant_usage = Netra.usage.get_tenant_usage(
tenant_id = "AceTech" ,
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
)
if tenant_usage:
print ( "Tenant:" , tenant_usage.tenant_id)
print ( "Org:" , tenant_usage.organisation_id)
print ( "Tokens:" , tenant_usage.token_count)
print ( "Requests:" , tenant_usage.request_count)
print ( "Sessions:" , tenant_usage.session_count)
print ( "Total cost (USD):" , tenant_usage.total_cost)
Parameters
Parameter Type Description tenant_idstrIdentifier of the tenant (e.g., customer organization) start_timestrStart of time window (ISO 8601 UTC) end_timestrEnd of time window (ISO 8601 UTC)
Response: TenantUsageData
Field Type Description tenant_idstrThe tenant identifier organisation_idstrOrganization identifier token_countintTotal tokens used request_countintNumber of requests session_countintNumber of sessions total_costfloatTotal cost in USD
list_traces
Query traces for a time range with optional filtering and pagination.
from netra import Netra
Netra.init( app_name = "sample-app" )
traces_page = Netra.usage.list_traces(
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
tenant_id = "AceTech" ,
user_id = "Jerina" ,
session_id = "b8a359f8-f28c-4e88-839f-c5db103e9943" ,
limit = 10 ,
cursor = None ,
direction = "down" ,
sort_field = "start_time" ,
sort_order = "desc" ,
)
for trace in traces_page.traces:
print (trace.id, trace.name, trace.total_tokens, trace.total_cost)
print ( "Has next page?" , traces_page.has_next_page)
print ( "Next cursor:" , traces_page.next_cursor)
# Pagination
if traces_page.has_next_page:
next_page = Netra.usage.list_traces(
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
tenant_id = "AceTech" ,
limit = 10 ,
cursor = traces_page.next_cursor,
direction = "down" ,
)
Parameters
Parameter Type Description start_timestrStart of time range (ISO 8601 UTC) end_timestrEnd of time range (ISO 8601 UTC) tenant_idstr?Filter by tenant ID user_idstr?Filter by user ID session_idstr?Filter by session ID limitint?Maximum traces per page cursorstr?Pagination cursor from previous page direction"up" | "down"Pagination direction (default: "down") sort_fieldstr?Field to sort by (e.g., "start_time") sort_order"asc" | "desc"Sort order
Response: TracesPage
Field Type Description traceslist[TraceSummary]List of trace summaries has_next_pageboolWhether more pages exist next_cursorstr?Cursor for next page
Field Type Description idstrUnique trace identifier namestrTrace name total_tokensintTotal tokens in trace total_costfloatTotal cost in USD start_timestrTrace start timestamp end_timestrTrace end timestamp
Value Description "down"Fetch newer/forward in time "up"Fetch older/backwards in time
iter_traces
Iterator that automatically handles pagination when streaming through all traces.
from netra import Netra
Netra.init( app_name = "sample-app" )
for trace in Netra.usage.iter_traces(
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
tenant_id = "AceTech" ,
user_id = "Jerina" ,
session_id = "b8a359f8-f28c-4e88-839f-c5db103e9943" ,
limit = 10 ,
direction = "down" ,
sort_field = "start_time" ,
sort_order = "desc" ,
):
print (trace.id, trace.name, trace.total_cost)
Parameters
Parameter Type Description start_timestrStart of time range (ISO 8601 UTC) end_timestrEnd of time range (ISO 8601 UTC) tenant_idstr?Filter by tenant ID user_idstr?Filter by user ID session_idstr?Filter by session ID limitint?Per-page size when fetching cursorstr?Optional starting cursor direction"up" | "down"Pagination direction sort_fieldstr?Field to sort by sort_order"asc" | "desc"Sort order
The iterator handles pagination automatically using TracesPage.has_next_page and TracesPage.next_cursor. It stops when there are no more pages.
list_spans_by_trace_id
Fetch spans within a single trace with optional filtering and pagination.
from netra import Netra
Netra.init( app_name = "sample-app" )
spans_page = Netra.usage.list_spans_by_trace_id(
trace_id = "728c1de6fa4c53de143a7d7fef33ff91" ,
direction = "down" ,
limit = 10 ,
span_name = "openai.chat" ,
)
for span in spans_page.spans:
print (span.id, span.name, span.kind, span.latency_ms)
print ( "Has next page?" , spans_page.has_next_page)
print ( "Next cursor:" , spans_page.next_cursor)
Parameters
Parameter Type Description trace_idstrID of the trace to fetch spans from cursorstr?Pagination cursor from previous page direction"up" | "down"Pagination direction (default: "down") limitint?Maximum spans per page span_namestr?Filter by span name
Response: SpansPage
Field Type Description spanslist[TraceSpan]List of span objects has_next_pageboolWhether more pages exist next_cursorstr?Cursor for next page
Field Type Description idstrUnique span identifier namestrSpan name kindstrSpan type (e.g., "generation", "tool") latency_msfloatDuration in milliseconds start_timestrSpan start timestamp end_timestrSpan end timestamp
iter_spans_by_trace_id
Iterator that automatically handles pagination when walking through all spans of a trace.
from netra import Netra
Netra.init( app_name = "sample-app" )
for span in Netra.usage.iter_spans_by_trace_id(
trace_id = "728c1de6fa4c53de143a7d7fef33ff91" ,
direction = "down" ,
limit = 100 ,
span_name = "generation_pipeline" ,
):
print ( f "Span: { span.id } , name= { span.name } , kind= { span.kind } , duration_ms= { span.latency_ms } " )
Parameters
Parameter Type Description trace_idstrID of the trace to iterate spans from cursorstr?Optional starting cursor direction"up" | "down"Pagination direction limitint?Per-page span count span_namestr?Filter by span name
When to Use Which API
Usage APIs get_session_usage / get_tenant_usageHigh-level reporting: tokens, requests, and cost per session or tenant. Use for billing dashboards and cost analysis.
Traces APIs list_traces / iter_tracesExplore what traces exist in a time window, optionally filtered by session, user, or tenant. Use for debugging and monitoring.
Spans APIs list_spans_by_trace_id / iter_spans_by_trace_idDrill 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
from netra import Netra
# Initialize the SDK
Netra.init(
app_name = "analytics-app" ,
headers = "x-api-key=your-api-key" ,
)
# Get session-level usage
session_usage = Netra.usage.get_session_usage(
session_id = "session-123" ,
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
)
print ( f "Session cost: $ { session_usage.total_cost :.4f} " )
# Get tenant-level usage
tenant_usage = Netra.usage.get_tenant_usage(
tenant_id = "AceTech" ,
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
)
print ( f "Tenant total: { tenant_usage.session_count } sessions, $ { tenant_usage.total_cost :.4f} " )
# Iterate through all traces for a tenant
for trace in Netra.usage.iter_traces(
start_time = "2026-01-01T00:00:00.000Z" ,
end_time = "2026-01-31T23:59:59.000Z" ,
tenant_id = "AceTech" ,
sort_field = "start_time" ,
sort_order = "desc" ,
):
print ( f "Trace { trace.id } : { trace.name } - $ { trace.total_cost :.4f} " )
# Drill into spans for each trace
for span in Netra.usage.iter_spans_by_trace_id( trace_id = trace.id):
print ( f " └─ { span.name } ( { span.kind } ): { span.latency_ms } ms" )
Next Steps