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

# Usage and metering

What B3OS meters, which unit each operation bills, and how to read your usage as totals or as the individual records behind them.

The node that does the work records the usage, one record per billable unit of work, and reports it to the edge within seconds. Each operation bills one unit you can see, whatever happened inside it: a scrape bills one `vision.page` whether the cache, a plain fetch or a browser served it.

## Units

| Unit | Product | Counts | What it measures |
|---|---|---|---|
| `vision.page` | vision | pages | One page fetched and converted, whichever tier served it (cache, fetch, browser). |
| `vision.browser_ms` | vision | milliseconds | Wall time of a browser session, from claim to close. |
| `render.screenshot` | render | screenshots | One captured screenshot; extra variants of the same capture count once each. |
| `render.video_s` | render | seconds | Seconds of output video, rounded up per video. |
| `infer.input_tokens` | infer | tokens | Prompt tokens. |
| `infer.output_tokens` | infer | tokens | Generated tokens. |
| `infer.audio_chars` | infer | characters | Characters of text synthesized to speech. |
| `sandboxes.vcpu_ms` | sandboxes | vCPU milliseconds | CPU time used, sampled from the sandbox cgroup cpu.stat. |
| `sandboxes.gib_ms` | sandboxes | GiB milliseconds | Allocated memory times wall time while running. |
| `routines.effect_step` | routines | steps | A routine step with effects that has no product meter of its own (core/http, core/wait, …). |
| `actions.call` | actions | calls | One action execution. |
| `egress.bytes` | platform | bytes | Bytes of customer-steered egress, recorded by the egress guard for every operation. |

A few rules follow from "one unit per operation":

- `vision.browser_ms` applies to browser sessions only. Scrapes that used a browser bill `vision.page` and nothing else.
- A routine step bills its product's unit: a `vision/scrape@1` step bills `vision.page`. Only steps with no product meter of their own, such as `core/http@1`, bill `routines.effect_step`.
- A paused sandbox bills no CPU time. Whether it bills memory while paused is still being settled for the beta; the sandbox's `usage` shows what it was charged.
- A map bills one `vision.page` per request, however many URLs it returns. An extraction bills its pages plus the model's tokens.
- Work done before a cancel stays billed: scraped pages, encoded video seconds, tokens already generated.

Inference is free in the beta, within each model's token-per-minute limit. Your organization's credit balance is in the [dashboard](https://beta.b3os.org/app).

## Totals

`GET /v1/usage` adds up usage between `start` and `end` (default: this calendar month so far), grouped by any of `product`, `unit`, `key`, `project` and `day`:

```bash
curl -s "https://beta-api.b3os.org/v1/usage?group_by=product,unit" \
  -H "Authorization: Bearer $B3OS_API_KEY"
```

```json
{
  "object": "usage_summary",
  "start": "2026-10-01T00:00:00.000Z",
  "end": "2026-10-25T22:00:00.000Z",
  "group_by": ["product", "unit"],
  "rows": [
    { "product": "vision", "unit": "vision.page", "qty": 18204 },
    { "product": "sandboxes", "unit": "sandboxes.vcpu_ms", "qty": 9120330 },
    { "product": "infer", "unit": "infer.output_tokens", "qty": 4410920 }
  ]
}
```

The values are illustrative. The last minute of usage may still change as nodes report.

## Records

`GET /v1/usage/records` lists the individual records, newest first, and filters by product, unit, key and request. Every record names the request that produced it, so you can tie a charge to a call:

```json
{
  "id": "use_01m5t5tmscqev5tf32q87tr1v5",
  "object": "usage_record",
  "ts": "2026-10-25T21:30:00.120Z",
  "key_id": "key_01m5t5csy2wt4e3er052chyf1x",
  "sandbox_id": null,
  "node": "n1",
  "product": "vision",
  "unit": "vision.page",
  "qty": 1,
  "request_id": "req_01m5t4yg394wegr3j4y01qb363",
  "meta": { "tier": "fetch" }
}
```

This example is abridged. Calls made from inside a sandbox carry its `sandbox_id`, and they bill the key that created the sandbox.

## Caps

A key can carry a spend cap in USD (`spend_cap_usd`). When the key reaches it, its requests fail with [`spend_cap_exceeded`](/errors#spend_cap_exceeded) until you raise the cap. A sandbox's `api.spend_cap_usd` caps the calls made from inside that sandbox. When the organization runs out of credits, requests fail with [`credits_exhausted`](/errors#credits_exhausted). The node enforces caps with its own counters, so calls that never pass through the edge are capped too.