> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnetra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage & Traces

> Query token usage, costs, traces and spans using the Netra Usage API

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.

```python theme={null}
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.

<CodeGroup>
  ```python Usage theme={null}
  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)
  ```

  ```python Signature theme={null}
  get_session_usage(
      session_id: str,
      start_time: str,
      end_time: str,
  ) -> SessionUsageData | Any
  ```
</CodeGroup>

### Parameters

| Parameter    | Type  | Description                                                             |
| ------------ | ----- | ----------------------------------------------------------------------- |
| `session_id` | `str` | Unique identifier of the session                                        |
| `start_time` | `str` | Start of time window (ISO 8601 UTC, e.g., `"2026-01-01T00:00:00.000Z"`) |
| `end_time`   | `str` | End of time window (ISO 8601 UTC)                                       |

### Response: SessionUsageData

| Field           | Type    | Description            |
| --------------- | ------- | ---------------------- |
| `session_id`    | `str`   | The session identifier |
| `token_count`   | `int`   | Total tokens used      |
| `request_count` | `int`   | Number of requests     |
| `total_cost`    | `float` | Total cost in USD      |

***

## get\_tenant\_usage

Fetch aggregated usage metrics for a tenant across all sessions.

<CodeGroup>
  ```python Usage theme={null}
  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)
  ```

  ```python Signature theme={null}
  get_tenant_usage(
      tenant_id: str,
      start_time: str,
      end_time: str,
  ) -> TenantUsageData | Any
  ```
</CodeGroup>

### Parameters

| Parameter    | Type  | Description                                            |
| ------------ | ----- | ------------------------------------------------------ |
| `tenant_id`  | `str` | Identifier of the tenant (e.g., customer organization) |
| `start_time` | `str` | Start of time window (ISO 8601 UTC)                    |
| `end_time`   | `str` | End of time window (ISO 8601 UTC)                      |

### Response: TenantUsageData

| Field             | Type    | Description             |
| ----------------- | ------- | ----------------------- |
| `tenant_id`       | `str`   | The tenant identifier   |
| `organisation_id` | `str`   | Organization identifier |
| `token_count`     | `int`   | Total tokens used       |
| `request_count`   | `int`   | Number of requests      |
| `session_count`   | `int`   | Number of sessions      |
| `total_cost`      | `float` | Total cost in USD       |

***

## list\_traces

Query traces for a time range with optional filtering and pagination.

<CodeGroup>
  ```python Usage theme={null}
  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",
      )
  ```

  ```python Signature theme={null}
  list_traces(
      start_time: str,
      end_time: str,
      trace_id: Optional[str] = None,
      session_id: Optional[str] = None,
      user_id: Optional[str] = None,
      tenant_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
  ```
</CodeGroup>

### Parameters

| Parameter    | Type              | Description                              |
| ------------ | ----------------- | ---------------------------------------- |
| `start_time` | `str`             | Start of time range (ISO 8601 UTC)       |
| `end_time`   | `str`             | End of time range (ISO 8601 UTC)         |
| `trace_id`   | `str?`            | Filter by trace ID                       |
| `session_id` | `str?`            | Filter by session ID                     |
| `user_id`    | `str?`            | Filter by user ID                        |
| `tenant_id`  | `str?`            | Filter by tenant ID                      |
| `limit`      | `int?`            | Maximum traces per page                  |
| `cursor`     | `str?`            | Pagination cursor from previous page     |
| `direction`  | `"up" \| "down"`  | Pagination direction (default: `"down"`) |
| `sort_field` | `str?`            | Field to sort by (e.g., `"start_time"`)  |
| `sort_order` | `"asc" \| "desc"` | Sort order                               |

### Response: TracesPage

| Field           | Type                 | Description              |
| --------------- | -------------------- | ------------------------ |
| `traces`        | `list[TraceSummary]` | List of trace summaries  |
| `has_next_page` | `bool`               | Whether more pages exist |
| `next_cursor`   | `str?`               | Cursor for next page     |

<AccordionGroup>
  <Accordion title="TraceSummary Fields" icon="list">
    | Field          | Type    | Description             |
    | -------------- | ------- | ----------------------- |
    | `id`           | `str`   | Unique trace identifier |
    | `name`         | `str`   | Trace name              |
    | `total_tokens` | `int`   | Total tokens in trace   |
    | `total_cost`   | `float` | Total cost in USD       |
    | `start_time`   | `str`   | Trace start timestamp   |
    | `end_time`     | `str`   | Trace end timestamp     |
  </Accordion>

  <Accordion title="Direction Values" icon="arrows-up-down">
    | Value    | Description                   |
    | -------- | ----------------------------- |
    | `"down"` | Fetch newer/forward in time   |
    | `"up"`   | Fetch older/backwards in time |
  </Accordion>
</AccordionGroup>

***

## iter\_traces

Iterator that automatically handles pagination when streaming through all traces.

<CodeGroup>
  ```python Usage theme={null}
  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",
      trace_id="45a32b90-f28c-4e88-839f-c5db103e9943",
      limit=10,
      direction="down",
      sort_field="start_time",
      sort_order="desc",
  ):
      print(trace.id, trace.name, trace.total_cost)
  ```

  ```python Signature theme={null}
  iter_traces(
      start_time: str,
      end_time: str,
      trace_id: Optional[str] = None,
      session_id: Optional[str] = None,
      user_id: Optional[str] = None,
      tenant_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]
  ```
</CodeGroup>

### Parameters

| Parameter    | Type              | Description                        |
| ------------ | ----------------- | ---------------------------------- |
| `start_time` | `str`             | Start of time range (ISO 8601 UTC) |
| `end_time`   | `str`             | End of time range (ISO 8601 UTC)   |
| `trace_id`   | `str?`            | Filter by trace ID                 |
| `session_id` | `str?`            | Filter by session ID               |
| `user_id`    | `str?`            | Filter by user ID                  |
| `tenant_id`  | `str?`            | Filter by tenant ID                |
| `limit`      | `int?`            | Per-page size when fetching        |
| `cursor`     | `str?`            | Optional starting cursor           |
| `direction`  | `"up" \| "down"`  | Pagination direction               |
| `sort_field` | `str?`            | Field to sort by                   |
| `sort_order` | `"asc" \| "desc"` | Sort order                         |

<Tip>
  The iterator handles pagination automatically using `TracesPage.has_next_page` and `TracesPage.next_cursor`. It stops when there are no more pages.
</Tip>

***

## list\_spans\_by\_trace\_id

Fetch spans within a single trace with optional filtering and pagination.

<CodeGroup>
  ```python Usage theme={null}
  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)
  ```

  ```python Signature theme={null}
  list_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,
  ) -> SpansPage | Any
  ```
</CodeGroup>

### Parameters

| Parameter   | Type             | Description                              |
| ----------- | ---------------- | ---------------------------------------- |
| `trace_id`  | `str`            | ID of the trace to fetch spans from      |
| `cursor`    | `str?`           | Pagination cursor from previous page     |
| `direction` | `"up" \| "down"` | Pagination direction (default: `"down"`) |
| `limit`     | `int?`           | Maximum spans per page                   |
| `span_name` | `str?`           | Filter by span name                      |

### Response: SpansPage

| Field           | Type              | Description              |
| --------------- | ----------------- | ------------------------ |
| `spans`         | `list[TraceSpan]` | List of span objects     |
| `has_next_page` | `bool`            | Whether more pages exist |
| `next_cursor`   | `str?`            | Cursor for next page     |

<AccordionGroup>
  <Accordion title="TraceSpan Fields" icon="diagram-project">
    | Field        | Type    | Description                                |
    | ------------ | ------- | ------------------------------------------ |
    | `id`         | `str`   | Unique span identifier                     |
    | `name`       | `str`   | Span name                                  |
    | `kind`       | `str`   | Span type (e.g., `"generation"`, `"tool"`) |
    | `latency_ms` | `float` | Duration in milliseconds                   |
    | `start_time` | `str`   | Span start timestamp                       |
    | `end_time`   | `str`   | Span end timestamp                         |
  </Accordion>
</AccordionGroup>

***

## iter\_spans\_by\_trace\_id

Iterator that automatically handles pagination when walking through all spans of a trace.

<CodeGroup>
  ```python Usage theme={null}
  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}")
  ```

  ```python Signature theme={null}
  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]
  ```
</CodeGroup>

### Parameters

| Parameter   | Type             | Description                           |
| ----------- | ---------------- | ------------------------------------- |
| `trace_id`  | `str`            | ID of the trace to iterate spans from |
| `cursor`    | `str?`           | Optional starting cursor              |
| `direction` | `"up" \| "down"` | Pagination direction                  |
| `limit`     | `int?`           | Per-page span count                   |
| `span_name` | `str?`           | Filter by span name                   |

***

## When to Use Which API

<CardGroup cols={2}>
  <Card title="Usage APIs" icon="gauge">
    **`get_session_usage` / `get_tenant_usage`**

    High-level reporting: tokens, requests, and cost per session or tenant. Use for billing dashboards and cost analysis.
  </Card>

  <Card title="Traces APIs" icon="route">
    **`list_traces` / `iter_traces`**

    Explore what traces exist in a time window, optionally filtered by session, user, or tenant. Use for debugging and monitoring.
  </Card>

  <Card title="Spans APIs" icon="diagram-project">
    **`list_spans_by_trace_id` / `iter_spans_by_trace_id`**

    Drill into a single trace to understand all spans (tools, generations, workflows) that occurred. Use for detailed trace analysis.
  </Card>

  <Card title="Iterators" icon="arrows-repeat">
    **`iter_*` methods**

    When you need to process all results without manually handling pagination. The iterator fetches pages on-demand.
  </Card>
</CardGroup>

***

## Complete Example

```python theme={null}
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

* [Dashboard Query](/sdk-reference/dashboard-query/python) - Query dashboard metrics and session stats
* [Python SDK Reference](/sdk-reference/sdk/python) - Complete SDK documentation
* [Traces Overview](/Observability/Traces/overview) - Understanding traces
* [Sessions](/Observability/Session) - Session management
