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

# Observability

> Per-session cost and token usage, a usage event before every idle, and a full trace of every turn, tool call, and model request.

Every session carries its own running cost and token usage on the object itself, emits a usage snapshot before it yields control, and records a full turn/tool/model span tree you can read back from the event history.

## Cost and usage on the session

Every [session](/docs/concepts/sessions) exposes what it has spent and consumed so far, without a separate billing call. Money is always **integer micro-USD** on the wire (`1 USD = 1,000,000 micro-USD`); clients convert for display.

<CodeGroup>
  ```bash CLI theme={"system"}
  vetta session get $SID    # includes consumed_micro_usd + token_usage
  ```

  ```typescript TypeScript theme={"system"}
  const s = await vetta.sessions.get(sessionId);
  console.log(s.consumed_micro_usd);  // e.g. 410000  → $0.41
  console.log(s.token_usage);         // 5-tier breakdown, below
  ```
</CodeGroup>

Token usage is metered in **five tiers**, billed and reported separately, because they price very differently:

| Tier          | What it counts                                                  |
| ------------- | --------------------------------------------------------------- |
| `input`       | Fresh prompt tokens sent to the model.                          |
| `cache_write` | Tokens written into the prompt cache.                           |
| `cache_read`  | Tokens served from the prompt cache (cheapest).                 |
| `output`      | Tokens the model generated.                                     |
| `reasoning`   | Hidden reasoning/thinking tokens, when the model produces them. |

The session object carries `consumed_micro_usd`, `token_usage` (the five tiers above), `started_at`, `ended_at?`, `stop_reason?`, `deployment_id?`, `agent_version`, and `last_seq` — enough to attribute cost per run, per deployment, and per agent version.

## The `session.usage` event

Before a session transitions to **idle** or any terminal state, the runtime emits a `session.usage` event carrying the cumulative snapshot. Because it precedes every yield, a stream consumer always sees the final cost of a turn before it sees the turn end.

```json theme={"system"}
{
  "id": "evt_5c...",
  "type": "session.usage",
  "seq": 142,
  "data": {
    "session_id": "ses_4a...",
    "consumed_micro_usd": 410000,
    "token_usage": {
      "input": 18240,
      "cache_write": 4096,
      "cache_read": 51200,
      "output": 3110,
      "reasoning": 900
    },
    "active_seconds": 37,
    "tool_calls": 12
  }
}
```

* `active_seconds` is metered running time — paused/idle time is excluded, matching how the [computer](/docs/capabilities/computer) bills.
* `tool_calls` is the count of tool invocations in the run so far.
* The event rides the ordinary [`seq` cursor](/docs/concepts/events-and-streaming), so it is replayable like any other event.

<Tip>
  Reading `session.usage` on the idle event pairs naturally with outcomes: report cost per *completed and passing* task, not just cost per attempt.
</Tip>

## The span model

Every session records a full trace of its turns, tool calls, and model requests — read it with `vetta session events --session $SID`. The spans follow the OpenTelemetry [GenAI semantic conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/), so they line up with any tooling that already understands agent traces:

| Vetta concept   | OTel span / attribute                                     |
| --------------- | --------------------------------------------------------- |
| Session         | trace, with `gen_ai.conversation.id` = the session id     |
| Agent           | `gen_ai.agent.id` and `gen_ai.agent.version` on the spans |
| Each turn       | an `invoke_agent` span                                    |
| Each tool call  | an `execute_tool` span (child of the turn)                |
| Each model call | a `chat` span carrying the five token tiers + cost        |

A single turn therefore nests as `invoke_agent` → (`chat`, `execute_tool`, `execute_tool`, …), so you can see exactly which tool call or model request drove a turn's latency and cost.

**Coming soon:** OTLP export of these spans to an OpenTelemetry-compatible collector you control.

<Card title="Next: deployments" icon="clock" href="/docs/capabilities/deployments">
  Run an agent on a schedule and collect every fire's cost and result.
</Card>
