Search

↑↓ to move↵ to openesc to closetop 6 documentation results

Book a demoTry TokenTriage

In development · Explore the product preview. Join the launch list or book a walkthrough.

Browse docs

Migrate from OpenAI or Anthropic SDKs

Point the official OpenAI or Anthropic SDK at TokenTriage with one base-URL change — your code, calls, and keys stay put.

How-to guideLast updated

On this page

If your app already calls the model provider through the official OpenAI or Anthropic SDK, this is the smallest possible migration: change the SDK’s base URL to point at a TokenTriage proxy. You keep the same SDK, the same calls, the same API keys — the proxy speaks each provider’s native dialect, so the request and response bytes are unchanged.

The one change

TokenTriage’s data plane listens on 127.0.0.1:8787 by default. Each SDK gets a different base URL because each speaks a different dialect:

  • OpenAI SDK → the proxy’s /v1 prefix (http://127.0.0.1:8787/v1). The SDK appends /chat/completions, so requests land on /v1/chat/completions, which the OpenAI dialect owns.
  • Anthropic SDK → the proxy root (http://127.0.0.1:8787). The Anthropic SDK appends /v1/messages itself, and the Anthropic dialect owns /v1/messages — so you give it the root, not /v1.

Migrate the OpenAI SDK

First run a ledger proxy with an OpenAI upstream. Drop this into tokentriage.yaml:

version: 1
mode: ledger                    # observe and cost every request; mutate nothing
upstreams:
  openai:
    base_url: https://api.openai.com   # host only — your client already sends /v1
    dialect: openai
    api_key_env: OPENAI_API_KEY
$ tokentriage run -c tokentriage.yaml

Then change one line in your app.

from openai import OpenAI

# BEFORE: client = OpenAI()                                  # talks straight to api.openai.com
# AFTER  — the only 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"}]}'

Migrate the Anthropic SDK

For an Anthropic upstream (ideal for Claude Code), the zero-config quickstart is enough — no config file needed:

$ tokentriage run --anthropic

Then point the Anthropic SDK at the proxy root:

from anthropic import Anthropic

# BEFORE: client = Anthropic()                               # talks straight to api.anthropic.com
# AFTER  — the only change: base_url is the proxy ROOT, not /v1. The SDK appends /v1/messages.
client = Anthropic(base_url="http://127.0.0.1:8787")

resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=256,
    messages=[{"role": "user", "content": "Summarize this ticket."}],
)

curl

$ curl http://127.0.0.1:8787/v1/messages \
  -H "Content-Type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-sonnet-4-6","max_tokens":256,"messages":[{"role":"user","content":"Hello"}]}'

What you get for the one-line change

Nothing about your responses changed — but now every request is on the ledger:

  • A costed row per request. TokenTriage stamps an x-tt-request-id response header on every proxied call; that’s the join key into a ledger row with the real dollar cost, computed from the compiled-in pricing snapshot. Roll it up from the terminal:

    $ tokentriage top --by model

    A model the server can’t price shows a - in the COST column, with a footnote stating how many rows were excluded because no price resolved — never a fabricated $0.

  • Optional trace grouping. Add x-tt-trace-id / x-tt-agent headers later to group a run or split spend by sub-agent. They’re optional — a request with no x-tt-* headers is still fully costed; it just lands as a standalone row.

  • A path to savings with zero further code change. Everything above is ledger mode: pure observation. When the evidence says a cheaper model is genuinely as good, you climb to shadow and then route — enforcing routing decisions in the proxy config, without touching your application again.