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.
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

ParameterTypeDescription
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

FieldTypeDescription
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

ParameterTypeDescription
tenantIdstringIdentifier of the tenant (e.g., customer organization)
startTimestringStart of time window (ISO 8601 UTC)
endTimestringEnd of time window (ISO 8601 UTC)

Response: TenantUsageData

FieldTypeDescription
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)

ParameterTypeDescription
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

FieldTypeDescription
tracesTraceSummary[]List of trace summaries
hasNextPagebooleanWhether more pages exist
nextCursorstring?Cursor for next page
FieldTypeDescription
idstringUnique trace identifier
namestringTrace name
totalTokensnumberTotal tokens in trace
totalCostnumberTotal cost in USD
startTimestringTrace start timestamp
endTimestringTrace end timestamp
ValueDescription
"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)

ParameterTypeDescription
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

FieldTypeDescription
spansTraceSpan[]List of span objects
hasNextPagebooleanWhether more pages exist
nextCursorstring?Cursor for next page
FieldTypeDescription
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

Last modified on February 10, 2026