GitHubBook a demoStart routing
Browse docs

Quickstart

Point one base URL at TokenTriage, send a request, and read back exactly what that request cost — in about five minutes, in pure observation mode, with nothing about your responses changed.

Last updated

On this page

TokenTriage starts as a ledger: it observes and costs every request and changes nothing about the response. You climb to routing later, once the evidence says it’s safe. This page gets you from install to a costed request you can see the dollar amount for — without touching your application logic beyond one base-URL swap.

1. Install

TokenTriage is a single source-available (FSL) Go binary — no CGO, no sidecar runtime. Build it from source (a prebuilt release binary works too):

git clone https://github.com/inferops/tokentriage.git
cd tokentriage

# One static binary; the pricing table is compiled in via go:embed.
CGO_ENABLED=0 go build -o dist/tokentriage ./cmd/tokentriage

Confirm the build and the embedded pricing snapshot:

$ tokentriage version
tokentriage dev (commit none, built unknown)
pricing snapshot: litellm@2026-07-14#179affb

See Installation for the container image and cross-compile targets.

2. Run a ledger proxy

The fastest start is a zero-config ledger proxy for an Anthropic upstream (ideal for Claude Code). It costs every request and mutates nothing:

$ tokentriage run --anthropic

This listens on 127.0.0.1:8787 (the data plane — your traffic) and 127.0.0.1:9090 (the admin plane/health, /metrics, /tt/api/status, and, when enabled, the dashboard at /ui/).

3. Point your app at the proxy

Swap only the base URL. Nothing else in your code changes. The OpenAI dialect lives under /v1 (so /v1/chat/completions); the Anthropic SDK takes the proxy root and appends /v1/messages itself.

from openai import OpenAI

# The one change: base_url points at the proxy's /v1 dialect prefix.
client = OpenAI(base_url="http://127.0.0.1:8787/v1")

resp = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Summarize this ticket."}],
)

curl

$ curl http://127.0.0.1:8787/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-5",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Using the Anthropic SDK instead? Give it the proxy root — it appends /v1/messages on its own:

from anthropic import Anthropic
client = Anthropic(base_url="http://127.0.0.1:8787")   # root, NOT /v1

For Claude Code specifically, wrap sets ANTHROPIC_BASE_URL for you and injects a fresh x-tt-trace-id (plus x-tt-agent), so every request in that session groups into one trace:

$ tokentriage wrap --agent claude -- claude

4. See what that one request cost

This is the payoff: a 200 OK is not the finish line — the dollar is. TokenTriage stamps one response header on every proxied request, x-tt-request-id, which is the join key into the costed ledger row. (In ledger mode that’s the only x-tt-* response header; decision headers appear once you climb to shadow/route.)

Re-run the curl call with -i to see the header the proxy added:

$ curl -i http://127.0.0.1:8787/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{"model":"gpt-5","messages":[{"role":"user","content":"Hello"}]}'
HTTP/1.1 200 OK
content-type: application/json
x-tt-request-id: tt_d5k7ntwm6utqbk4eigg3am3udm     # ← the join key (illustrative id)
...

Read the dollar back — three ways

A. From the terminal (top). Roll up the ledger — attributed by model, agent, MCP tool, trace, or step-class. Values below are illustrative:

$ tokentriage top --by model
MODEL         REQS  INPUT  OUTPUT  CACHE-R  CACHE-W  REASON  CACHE-SAV  COST       P50        P90        P99
gpt-5         1     88     40      32       0        0       0.0%       $0.000514  $0.000514  $0.000514  $0.000514
TOTAL         1     88     40      32       0        0       0.0%       $0.000514

That $0.000514 under COST is real accounting, not a placeholder: it is 88·$1.25e-6 + 40·$1e-5 + 32·$1.25e-7 from the embedded price table for openai/gpt-5 (INPUT·OUTPUT·CACHE-R tokens), stamped with the pricing snapshot. P50/P90/P99 are the per-request cost percentiles for the group; with one request they collapse to that single figure. (You can also roll up --by agent, --by tool, --by step-class, or drill into one run with --trace <ID>; window with --since 24h.)

B. From the Python SDK. The zero-dependency instrumentation SDK reads back the receipt the proxy stamped, then pulls the honest dollar from your own admin plane by the join key (it forwards and reads; it never computes the price itself):

import tokentriage as tt

tt.init(base_url="http://127.0.0.1:8787")

# Ask the OpenAI SDK for the raw response so the x-tt-* headers are visible.
raw = client.chat.completions.with_raw_response.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Summarize this ticket."}],
)
rcpt = tt.receipt(raw)               # typed, read-only view of the response headers
print(rcpt.request_id)               # -> "tt_d5k7ntwm6utqbk4eigg3am3udm"

# Pull the costed row from the admin plane (default http://127.0.0.1:9090).
row = tt.ledger.fetch(rcpt)          # or tt.ledger.fetch(rcpt.request_id)
print(row.cost.render())             # -> "$0.000514 (snapshot litellm@2026-07-14#179affb)"

The cost you get back is a closed three-state value — PRICED, UNPRICED, or absent — so a request the server could not price renders as UNPRICED (...), never a fabricated $0.00. (The TypeScript SDK exposes the same ledger.fetch under sdk/ts.)

C. From the dashboard. Prefer a web view? Enable the dashboard (dashboard.enabled: true) and open http://127.0.0.1:9090/ui/, or boot the whole thing against a watermarked synthetic ledger with no API key:

$ tokentriage demo
dashboard: http://127.0.0.1:<PORT>/ui/   # <PORT> is chosen dynamically — open the URL your terminal prints

You should now see your spend attributed on the Cost surface — the same dollar the top CLI and the SDK read back, now on a chart:

Demo dataThe dashboard Cost surface attributing spend by model, each row carrying a priced dollar.
The Cost surface — every dollar attributed, priced or explicitly UNPRICED (real dashboard, demo mode).

5. Climb the trust ladder

You’ve done the first rung — a request costed and read back. When you’re ready to cut spend, you don’t flip routing on and hope. You climb one rung at a time and let the evidence promote you:

  • ledger — where you are now. Observe and cost, zero mutation.
  • shadow — also compute the would-route decision and its counterfactual cost, so report shows the savings you’d get without touching a response.
  • route — enforce decisions once the honesty verdict says the cheaper path is genuinely as good.

The next tutorial walks all four rungs hands-on, with the real command output at each: Your first routing rollout.