Skip to main content
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

ParameterTypeDescription
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

FieldTypeDescription
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

ParameterTypeDescription
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

FieldTypeDescription
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

ParameterTypeDescription
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

FieldTypeDescription
traceslist[TraceSummary]List of trace summaries
has_next_pageboolWhether more pages exist
next_cursorstr?Cursor for next page
FieldTypeDescription
idstrUnique trace identifier
namestrTrace name
total_tokensintTotal tokens in trace
total_costfloatTotal cost in USD
start_timestrTrace start timestamp
end_timestrTrace end timestamp
ValueDescription
"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

ParameterTypeDescription
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

ParameterTypeDescription
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

FieldTypeDescription
spanslist[TraceSpan]List of span objects
has_next_pageboolWhether more pages exist
next_cursorstr?Cursor for next page
FieldTypeDescription
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

ParameterTypeDescription
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

Last modified on January 28, 2026