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

# Usage metering API

> Query aggregated usage data with dimensional filters and time-series aggregation.

# Usage Metering API

Query usage and metering data for billing attribution and cost visibility. The usage pipeline records discrete billable events (run creation, task completion, tool invocation) and exposes them through a customer-scoped query API with dimensional filters and time-series aggregation.

***

## GET /v1/usage — Query usage data

Returns aggregated usage summaries scoped to the authenticated customer.

| Item   | Value       |
| ------ | ----------- |
| Method | GET         |
| Path   | `/v1/usage` |
| Auth   | Required    |

### Query parameters

All parameters are optional. When `start` and `end` are omitted, the server defaults to the start of the current UTC month through now.

| Parameter      | Type   | Description                                                                                    |
| -------------- | ------ | ---------------------------------------------------------------------------------------------- |
| `workspace_id` | string | Filter usage to a specific workspace                                                           |
| `subject_id`   | string | Filter usage to a specific user/actor                                                          |
| `event_type`   | string | Filter by event type (e.g. `run.created`, `task.completed`, `tool.invoked`, `tokens.consumed`) |
| `start`        | string | ISO 8601 datetime with timezone offset (e.g. `2026-03-01T00:00:00+00:00`)                      |
| `end`          | string | ISO 8601 datetime with timezone offset                                                         |
| `granularity`  | string | Aggregation period: `hour`, `day` (default), or `month`                                        |

### Response (200)

```json  theme={null}
{
  "usage": [
    {
      "event_type": "run.created",
      "count": 42,
      "total_quantity": 42,
      "period": "2026-03-25",
      "workspace_id": "ws_engineering",
      "subject_id": null
    },
    {
      "event_type": "task.completed",
      "count": 156,
      "total_quantity": 156,
      "period": "2026-03-25",
      "workspace_id": "ws_engineering",
      "subject_id": null
    },
    {
      "event_type": "tool.invoked",
      "count": 89,
      "total_quantity": 89,
      "period": "2026-03-25",
      "workspace_id": "ws_engineering",
      "subject_id": null
    }
  ],
  "period": {
    "start": "2026-03-25T00:00:00.000Z",
    "end": "2026-03-26T00:00:00.000Z"
  },
  "granularity": "day",
  "request_id": "uuid"
}
```

### Response fields

**Top-level:**

| Field         | Type   | Description                                        |
| ------------- | ------ | -------------------------------------------------- |
| `usage`       | array  | Aggregated usage rows                              |
| `period`      | object | `{ start, end }` — effective time range (ISO 8601) |
| `granularity` | string | Aggregation granularity used                       |
| `request_id`  | string | Correlation ID                                     |

**Each `usage` element:**

| Field            | Type         | Description                                                                        |
| ---------------- | ------------ | ---------------------------------------------------------------------------------- |
| `event_type`     | string       | Billable event type                                                                |
| `count`          | integer      | Number of events in this period                                                    |
| `total_quantity` | integer      | Total quantity (may differ from count for quantity-bearing events)                 |
| `period`         | string       | Time bucket label (e.g. `2026-03-25` for daily, `2026-03-25T14:00:00Z` for hourly) |
| `workspace_id`   | string\|null | Workspace attribution (null if not filtered or not attributed)                     |
| `subject_id`     | string\|null | Subject attribution (null if not filtered or not attributed)                       |

### Error responses

| Status | Reason code                                | Meaning                                                             |
| :----: | ------------------------------------------ | ------------------------------------------------------------------- |
|   400  | `USAGE_QUERY_PARAMS_INVALID`               | Invalid query parameter (bad date format, unknown granularity, etc) |
|   401  | See [authentication.md](authentication.md) | Auth failure                                                        |
|   403  | See [authentication.md](authentication.md) | Authorization denied                                                |

***

## Event types

The usage pipeline records these billable event types:

| Event type        | Emitted when                                        | Quantity basis                                                  |
| ----------------- | --------------------------------------------------- | --------------------------------------------------------------- |
| `run.created`     | A new run is created                                | 1 per run                                                       |
| `task.completed`  | A task/step finishes execution                      | 1 per task                                                      |
| `tool.invoked`    | A tool is called during execution                   | 1 per invocation                                                |
| `tokens.consumed` | After each LLM completion (when usage is available) | Accumulated **total tokens per run** (cumulative, not per-call) |

The **`tokens.consumed`** event records cumulative LLM token usage per run. Unlike count-based events (where `total_quantity` often tracks discrete event counts), **`tokens.consumed`** uses **`total_quantity`** as the accumulated token total for that run in the aggregation row. Use `event_type=tokens.consumed` to query per-run token consumption for cost monitoring.

**Note:** **`tokens.consumed`** powers the server's internal cost ceiling enforcement. Clients may use it for per-run token visibility and budget alerting.

***

## Attribution model

Usage events carry three attribution dimensions from the run they belong to:

| Dimension      | Source                                        |          Required         |
| -------------- | --------------------------------------------- | :-----------------------: |
| `customer_id`  | From authenticated API key (server-validated) |    Yes (always present)   |
| `workspace_id` | From `workspace_id` on `POST /v1/runs`        | No (null if not provided) |
| `subject_id`   | From `subject_id` on `POST /v1/runs`          | No (null if not provided) |

`customer_id` scoping is automatic — you always see only your own data. Use `workspace_id` and `subject_id` as query filters to drill into your organizational structure.

***

## Example queries

### All usage for the current day

```
GET /v1/usage?start=2026-03-25T00:00:00+00:00&end=2026-03-26T00:00:00+00:00&granularity=day
```

### Usage for a specific workspace, hourly

```
GET /v1/usage?workspace_id=ws_engineering&start=2026-03-25T00:00:00+00:00&end=2026-03-26T00:00:00+00:00&granularity=hour
```

### Run creation events for a specific user

```
GET /v1/usage?subject_id=user_42&event_type=run.created&start=2026-03-01T00:00:00+00:00&end=2026-04-01T00:00:00+00:00&granularity=day
```

### Monthly summary for billing

```
GET /v1/usage?start=2026-03-01T00:00:00+00:00&end=2026-04-01T00:00:00+00:00&granularity=month
```

***

## TypeScript example

```typescript  theme={null}
interface UsageRow {
  event_type: string;
  count: number;
  total_quantity: number;
  period: string;
  workspace_id: string | null;
  subject_id: string | null;
}

interface UsageResponse {
  usage: UsageRow[];
  period: { start: string; end: string };
  granularity: "hour" | "day" | "month";
  request_id: string;
}

async function queryUsage(
  apiBase: string,
  apiKey: string,
  opts?: {
    workspaceId?: string;
    subjectId?: string;
    eventType?: string;
    start?: string;
    end?: string;
    granularity?: "hour" | "day" | "month";
  },
): Promise<UsageResponse> {
  const params = new URLSearchParams();
  if (opts?.workspaceId) params.set("workspace_id", opts.workspaceId);
  if (opts?.subjectId) params.set("subject_id", opts.subjectId);
  if (opts?.eventType) params.set("event_type", opts.eventType);
  if (opts?.start) params.set("start", opts.start);
  if (opts?.end) params.set("end", opts.end);
  if (opts?.granularity) params.set("granularity", opts.granularity);

  const res = await fetch(`${apiBase}/v1/usage?${params}`, {
    headers: { Authorization: `Bearer ${apiKey}` },
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(`Usage query failed: ${err.reason_code}`);
  }

  return res.json();
}
```

***

## Billing boundary

The usage API delivers **metering data** — counts and quantities per dimension per period. It feeds **Stripe**, which handles all payment processing, invoicing, and subscription management. The usage API does not itself compute prices, generate invoices, or manage subscriptions — those are Stripe's responsibility.


Built with [Mintlify](https://mintlify.com).