Skip to main content
The Netra SDK exposes a usage client that lets you query:
  • Session-level usage (tokens, requests, cost)
  • Tenant-level usage
  • Lists of traces within a time range
  • Lists of 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

Session Usage

Use get_session_usage to fetch usage 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="2025-10-18T11:20:20.723Z",
    end_time="2025-11-30T11:20:20.723Z",
)

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)
get_session_usage(
    session_id: str,
    start_time: str,
    end_time: str,
) -> SessionUsageData | Any
Parameters
  • session_id: str
    Unique identifier of the session whose usage you want to retrieve.
  • start_time: str
    Start of the time window to consider for this session’s usage.
    Must be an ISO 8601 UTC timestamp (e.g. "2025-11-16T00:00:00Z").
  • end_time: str
    End of the time window to consider for this session’s usage.
    Must be an ISO 8601 UTC timestamp.

Tenant Usage

Use get_tenant_usage to fetch aggregated usage for a tenant.
from netra import Netra

Netra.init(app_name="sample-app")

tenant_usage = Netra.usage.get_tenant_usage(
    tenant_id="AceTech",
    start_time="2025-10-18T11:20:20.723Z",
    end_time="2025-11-30T11:20:20.723Z",
)

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)
get_tenant_usage(
    tenant_id: str,
    start_time: str,
    end_time: str,
) -> TenantUsageData | Any
Parameters
  • tenant_id: str
    Identifier of the tenant (e.g. customer organization or account).
  • start_time: str
    Start of the time window for aggregating tenant usage, in ISO 8601 UTC.
  • end_time: str
    End of the time window for aggregating tenant usage, in ISO 8601 UTC.

Listing Traces

Use list_traces to query traces for a time range with optional search and pagination.
from netra import Netra

Netra.init(app_name="sample-app")

traces_page = Netra.usage.list_traces(
    start_time="2025-10-18T11:20:20.723Z",
    end_time="2025-11-30T11:20:20.723Z",
    tenant_id="AceTech",
	user_id="Jerina",
	session_id="b8a359f8-f28c-4e88-839f-c5db103e9943"
    limit=10,                      # page size
    cursor=None,                   # first page
    direction="down",              # or "up"
    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)

if traces_page.has_next_page and page.next_cursor:
    next_page = Netra.usage.list_traces(
        start_time="2025-10-18T11:20:20.723Z",
        end_time="2025-11-30T11:20:20.723Z",
        tenant_id="AceTech",
		user_id="Jerina",
		session_id="b8a359f8-f28c-4e88-839f-c5db103e9943"
        limit=10,
        cursor=traces_page.next_cursor,
        direction="down",
        sort_field="start_time",
        sort_order="desc",
    )
list_traces(
    start_time: str,
    end_time: str,
    tenant_id: Optional[str] = None,
	user_id: Optional[str] = None,
	session_id: Optional[str] = None,
    limit: Optional[int] = None,
    cursor: Optional[str] = None,
    direction: Optional[Literal["up", "down"]] = "down",
    sort_field: Optional[str] = None,
    sort_order: Optional[Literal["asc", "desc"]] = None,
) -> TracesPage | Any
Parameters
  • start_time: str
    Required. Start of the time range to search for traces (ISO 8601 UTC).
  • end_time: str
    Required. End of the time range to search for traces (ISO 8601 UTC).
  • session_id: Optional[str]
    Optional session_id used to filter the list
  • user_id: Optional[str]
    Optional user_id used to filter the list
  • tenant_id: Optional[str]
    Optional tenant_id used to filter the list
  • limit: Optional[int]
    Maximum number of traces to return in this page.
    If None, the backend default is used.
  • cursor: Optional[str]
    Opaque pagination cursor from a previous page.
    Use None for the first page.
  • direction: Optional[Literal["up", "down"]]
    Pagination direction relative to the cursor:
    • "down": fetch newer/forward in time.
    • "up": fetch older/backwards in time.
      Defaults to "down".
  • sort_field: Optional[str]
    Name of the field used for sorting traces (e.g. "start_time").
    If None, backend default sorting is applied.
  • sort_order: Optional[Literal["asc", "desc"]]
    Sort order for sort_field: ascending or descending.
    If None, backend default order is used.
If you want to stream over all pages until completion, use the iterators.
for trace in Netra.usage.iter_traces(
    start_time="2025-10-18T11:20:20.723Z",
    end_time="2025-11-30T11:20:20.723Z",
    tenant_id="AceTech",
	user_id="Jerina",
	session_id="b8a359f8-f28c-4e88-839f-c5db103e9943"
    limit=10,              # per-page size
    direction="down",
    sort_field="start_time",
    sort_order="desc",
):
    
    print(trace.id, trace.name, trace.total_cost)
iter_traces(
    start_time: str,
    end_time: str,
    tenant_id: Optional[str] = None,
	user_id: Optional[str] = None,
	session_id: Optional[str] = None,
    limit: Optional[int] = None,
    cursor: Optional[str] = None,
    direction: Optional[Literal["up", "down"]] = "down",
    sort_field: Optional[str] = None,
    sort_order: Optional[Literal["asc", "desc"]] = None,
) -> Iterator[TraceSummary]
Parameters
  • start_time: str
    Required. Time window start (ISO 8601 UTC) for traces to iterate over.
  • end_time: str
    Required. Time window end (ISO 8601 UTC) for traces to iterate over.
  • session_id: Optional[str]
    Optional session_id used to filter the list
  • user_id: Optional[str]
    Optional user_id used to filter the list
  • tenant_id: Optional[str]
    Optional tenant_id used to filter the list
  • limit: Optional[int]
    Per‑page size when fetching traces.
    Controls how many traces are fetched in each backend call.
  • cursor: Optional[str]
    Optional starting cursor.
    • None: start from the first page.
    • Not‑None: resume from a specific position.
  • direction: Optional[Literal["up", "down"]]
    Pagination direction per page, as in
    list_traces.
  • sort_field: Optional[str]
    Field to sort by when fetching traces.
  • sort_order: Optional[Literal["asc", "desc"]]
    Sort order for sort_field.
  • Handles pagination automatically using TracesPage.has_next_page and TracesPage.next_cursor.
  • Stops when there are no more pages or if the backend returns an unexpected payload.

Listing Spans for a Trace

Use list_spans_by_trace_id to fetch spans within a single trace, with optional search 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)
list_spans_by_trace_id(
    trace_id: str,
    cursor: Optional[str] = None,
    direction: Optional[Literal["up", "down"]] = "down",
    limit: Optional[int] = None,
    search: Optional[str] = None,
) -> SpansPage | Any
Parameters
  • trace_id: str
    Required trace identifier whose spans should be listed.
  • cursor: Optional[str]
    Opaque pagination cursor from a previous spans page.
    Use None to start from the first page.
  • direction: Optional[Literal["up", "down"]]
    Pagination direction relative to cursor:
    • "down": move forward.
    • "up": move backward.
      Defaults to "down".
  • limit: Optional[int]
    Maximum number of spans to return in this page.
  • span_name: Optional[str]
    Optional span_name used to filter the list
Use iter_spans_by_trace_id to walk all spans of a given trace across multiple pages.
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(
        "Span:",span.id,
        "name=", span.name,
        "kind=", span.kind,
        "duration_ms=", span.latency_ms,
    )
iter_spans_by_trace_id(
    trace_id: str,
    cursor: Optional[str] = None,
    direction: Optional[Literal["up", "down"]] = "down",
    limit: Optional[int] = None,
    span_name: Optional[str] = None,
) -> Iterator[TraceSpan]
Parameters
  • trace_id: str
    Required. ID of the trace whose spans you want to iterate over.
  • cursor: Optional[str]
    Optional starting cursor for iteration.
    None means start from the first spans page.
  • direction: Optional[Literal["up", "down"]]
    Pagination direction on each page, as above.
  • limit: Optional[int]
    Per‑page span count when streaming spans.
  • span_name: Optional[str]
    Optional span_name used to filter the list

When to Use Which API

  • get_session_usage/ get_tenant_usage
    High-level reporting: tokens, requests, and cost per session or tenant.
  • list_traces/ iter_traces
    Explore what traces exist in a time window, optionally filtered by session, user, or tenant.
  • list_spans_by_trace_id/ iter_spans_by_trace_id
    Drill into a single trace to understand all spans (tools, generations, workflows, etc.) that occurred within it.
Together, these APIs give you a complete picture of usage and tracing data,.