Integrations
Connect your stack to the release control plane.
Start where your requests originate. Connect an SDK, framework, or coding client to TokenTriage, then inspect the traffic that reaches the gateway. Each entry shows the setup, its constraints, and the evidence behind the connection.
Connection support is specific to each client. The verification levels below describe the integration evidence; they do not imply that every client supports every evaluation or rollout mode.
Know what has been verified.
- Verified3 integrations
- A named test in the product repo exercises this integration and asserts the result. What it drives is our side of it: no test here installs the third-party client.
- Reproduced7 integrations
- A person ran it by hand against a real gateway on a stated date, and the transcript is on the page.
- Follows from the wire12 integrations
- It speaks a dialect we accept, so it works by the same contract every such client uses. Nothing tests this one specifically.
1 member above carries no level: /claude-code shipped before this register existed and states none rather than being assigned one after the fact.
The level is a fact about our evidence, not about the integration. An entry at Follows from the wire is not worse than one at Verified; it is less separately attested. It speaks a dialect TokenTriage accepts, so it works by the same contract every such client uses — what nobody has done is drive that particular client and publish the run. An entry moves up when somebody runs it, and never because we think better of it.
Gateways you already run
5 integrationsYou have a config, and you want to know what survives the move.
LiteLLM
tokentriage migrate --from litellm config.yaml reads your config and names every blocker. Then the base URL moves from :4000 to :8787/v1.
Verifiedtokentriage migrate --from litellmBifrost
tokentriage migrate --from bifrost config.json imports the config and buckets every construct: imported, approximated, not expressible, or a blocker.
Verifiedtokentriage migrate --from bifrostOpenRouter
Set the base URL to http://127.0.0.1:8787/v1. The :nitro and :floor slug suffixes and the provider{} object have no wire equivalent — map them to tiers.
Follows from the wirebase URLPortkey
Set the base URL to http://127.0.0.1:8787/v1 and drop every x-portkey-* header. x-portkey-virtual-key has no equivalent; mint a TokenTriage key instead.
Follows from the wirebase URLHelicone
Set the base URL to http://127.0.0.1:8787/v1 and drop the Helicone-Auth header. What survives the swap, what does not, and where the comparison lives.
Follows from the wirebase URL
SDKs
3 integrationsYou have one constructor argument to change.
OpenAI Python SDK
OpenAI Python SDK (openai)
Set base_url="http://127.0.0.1:8787/v1" on the OpenAI client. The /v1 is required: the gateway matches /v1/chat/completions as an exact path, not a prefix.
Reproducedbase_urlOpenAI Node SDK
OpenAI Node/TypeScript SDK (openai)
Set baseURL: "http://127.0.0.1:8787/v1" on new OpenAI(). The /v1 is required: the gateway matches /v1/chat/completions as an exact path, not a prefix.
ReproducedbaseURLAnthropic SDK
Anthropic SDK (Python and TypeScript)
Set base_url="http://127.0.0.1:8787" — the bare root. An Anthropic client given a /v1 base calls /v1/v1/messages, which no dialect matches.
Reproducedbase_url
Agent frameworks
5 integrationsYou have a client to construct and steps to attribute.
LangChain
LangChain / LangGraph (Python)
Set base_url on ChatOpenAI to http://127.0.0.1:8787/v1 and every call is priced. The optional TTCallbackHandler adds a per-node agent and step id.
Reproducedbase_urlLlamaIndex
Set api_base on OpenAILike, never base_url. LlamaIndex reads OPENAI_API_BASE and never OPENAI_BASE_URL, so tokentriage wrap cannot repoint it.
Reproducedapi_baseAI SDK
AI SDK (Vercel)
createOpenAI({ baseURL }) and createAnthropic({ baseURL }) both want http://127.0.0.1:8787/v1 — the reverse of the official Anthropic SDK.
ReproducedbaseURLLangChain.js
Set configuration.baseURL to http://127.0.0.1:8787/v1 on ChatOpenAI. There is no JS callback adapter — per-step ids ride on defaultHeaders instead.
Follows from the wireconfiguration.baseURLCrewAI
The [crewai] extra ships instrument_crew, which stamps x-tt-agent with each agent's role. It never changes the LLM base_url — that half is still yours.
Follows from the wire
Coding agents and desktop clients
6 integrationsYou have a settings file or an environment variable.
Claude Code
One command puts a proxy in front of Claude Code, and every request it makes writes its own priced line in a file you own.
ANTHROPIC_BASE_URLZed
language_models.openai_compatible takes the root plus /v1; anthropic_compatible takes the bare root. What Zed sends, and what the ledger records.
Follows from the wireapi_urlContinue
Set apiBase in ~/.continue/config.yaml to http://127.0.0.1:8787/v1 and every completion writes a priced row you can attribute.
Follows from the wireapiBaseCline
Choose the OpenAI Compatible provider and set the base-URL field to http://127.0.0.1:8787/v1. Per-task cost, from the wire.
Follows from the wireBase URLRoo Code
Choose the OpenAI Compatible provider and set the base-URL field to http://127.0.0.1:8787/v1. Per-mode cost, from the wire.
Follows from the wireBase URLAider
Set OPENAI_API_BASE (or --openai-api-base) to http://127.0.0.1:8787/v1 and every edit request is priced against a dated table.
Follows from the wireOPENAI_API_BASE
Self-hosted runtimes
4 integrationsYou are pointing TokenTriage at something you host.
Ollama
Point TokenTriage at Ollama: base_url http://127.0.0.1:11434, provider ollama, auth none. Local models land in the same ledger as hosted ones.
Verifiedupstreams.<name>.base_urlOpen WebUI
Add an OpenAI-API connection with the URL field set to http://127.0.0.1:8787/v1. Every chat turn lands in a priced ledger.
ReproducedOPENAI_API_BASE_URLn8n
Set the credential's base-URL field to http://127.0.0.1:8787/v1. Every node using that credential lands in one priced ledger.
Follows from the wireBase URLFlowise
Set the ChatOpenAI node's Base Path field to http://127.0.0.1:8787/v1, and every chain step writes a priced row.
Follows from the wireBase Path
Not a fit, and why
6 entriesYou want a straight answer. Each entry names what stops it, and where the stop was read. Several of these are one vendor decision away from becoming a page — the trigger is on the record, and this list is re-read on the same cycle as the rest.
Cursor
Cursor's own documentation names no custom base-URL setting, and states that "all requests are routed through Cursor's servers for final prompt building". A gateway on 127.0.0.1:8787 is not one.
Dify
Dify's documentation names no endpoint field and shows no example URL for a model provider, and its own reference calls OPENAI_API_BASE a legacy variable. The /v1-versus-root question is unanswerable.
Ollama's native API (inbound)
The gateway serves no /api/chat, /api/generate or /api/tags. A client speaking Ollama-native takes the unmatched-path passthrough: it reaches the upstream, but nothing parses, prices or routes it.
Langfuse
An observability layer, not a gateway — there is no base URL to swap. It is a comparison, and the observability page already carries a card for it.
The OpenAI Realtime API
/v1/realtime is recognition-only. The bidirectional WebSocket transport is refused, so anything using the Realtime API will not work through the gateway as a WebSocket.
The OpenAI Assistants API
/v1/assistants is never registered, on the provider's own deprecation. It still relays and is still logged; it is not recognized, priced or claimed. Its replacement /v1/responses is first-class.
What this page can't tell you. It lists 23 integrations and 6 entries on the not-a-fit list, counted from the registry rather than from a list kept by hand. 12 integrations have a page and the remaining 11 are rows here and nothing more. An entry with no page is the answer rather than a gap: where an integration needs nothing typed that another entry does not already cover, a separate page would be that page with the nouns swapped, so the row carries the setting and the base-URL form, which is the part that differs. A tool nobody here has read against its own current documentation is absent altogether, because a row for a setting we have not read is a guess with a chip on it.