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.

Coding agents and desktop clients

Point Zed at TokenTriage
Two fields, two different roots.

Zed has one endpoint field per dialect family, and they take different roots. Set both. A wrong root is relayed unparsed and never priced.

{ "language_models": {
  // OpenAI dialect. The root PLUS /v1.
  "openai_compatible": { "tokentriage": {
    "api_url": "http://127.0.0.1:8787/v1",
    "available_models": [{ "name": "gpt-4o-mini", "max_tokens": 128000 }] } },
  // Anthropic dialect. The BARE root. Zed adds /v1/messages itself.
  "anthropic_compatible": { "tokentriage-anthropic": {
    "api_url": "http://127.0.0.1:8787",
    "available_models": [{ "name": "claude-sonnet-4-5", "max_tokens": 200000 }] } }
} }
Both providers point at the same gateway. The OpenAI-family key carries /v1; the Anthropic-family key does not. Zed derives the API key variable from each provider id, so these two want TOKENTRIAGE_API_KEY and TOKENTRIAGE_ANTHROPIC_API_KEY.
The setting
language_models.<dialect>_compatible.<id>.api_url
The base URL
http://127.0.0.1:8787/v1 for OpenAI · http://127.0.0.1:8787 for Anthropic

How to tell it worked

Send one message through each provider in the model picker. Then read the last two ledger rows. Each must name a dialect. An empty dialect is the root mistake.

tail -n 2 ~/.tokentriage/decisions.jsonl | jq -c '{p:.http.path, d:.http.dialect}'

What you should see

{"p":"/v1/chat/completions","d":"openai"} · {"p":"/v1/messages","d":"anthropic"}

How sure we are

Follows from the wire

It speaks a dialect we accept, so it works by the same contract every such client uses. Nothing tests this one specifically.

Verified against Zed 1.16.2 on

The OpenAI and Anthropic dialect contracts

The gotcha

The two api_url fields take opposite roots

Zed appends /chat/completions to one and /v1/messages to the other. Copy a root across and the path matches no dialect. TokenTriage relays it onward with the path you sent, so what you see is your upstream answering. The row shows an empty dialect.

// WRONG. Zed sends /v1/v1/messages, which matches no dialect.
"anthropic_compatible": { "tokentriage-anthropic": {
  "api_url": "http://127.0.0.1:8787/v1" } }

// RIGHT. The bare root. Zed appends /v1/messages.
"anthropic_compatible": { "tokentriage-anthropic": {
  "api_url": "http://127.0.0.1:8787" } }

“Use an Anthropic-compatible endpoint when a service implements Anthropic's Messages API (/v1/messages) and gives you a custom base URL, model ID, and API key.”

zed.dev/docs/ai/use-api-access#anthropic-compatible · read 2026-08-25

What you get now

What the ledger holds once a message arrives.

Three things that start the first time a message arrives. Each links its evidence. None of them is a claim about Zed.

2 endpoint fields
one per dialect family, in adjacent objects
1 gateway port
both providers point at the same listener
0 runs of Zed here
nobody on this side has opened the editor
2 open questions
a key on a local endpoint, and a plain http root

What does not carry across

Six things to know before you paste it.

Six of them, and the first two are about our evidence rather than about Zed. Read those first. The rest are traps in the settings file.

  • Nobody here has driven Zed

    The settings and the URL forms come from Zed’s own current documentation, read on the date beside the chip. No Zed session exists. The two gateway paths were driven by hand from other clients, not from this editor.

  • Two questions only a hand-run can settle

    Zed never says whether a custom provider may have an empty API key. And every api_url in its documentation is https, so a plain http root is unconfirmed. Both stay open here.

  • anthropic_compatible is not the anthropic key

    They are two separate top-level entries. Edit language_models.anthropic and you retarget Zed’s built-in Anthropic provider instead. The custom provider you meant to add is simply not in the file.

  • Nothing rescues a failed call for you

    TokenTriage does not retry and does not hedge: no retry chain, no failover, no health probes. Zed receives the failure itself. Cooldown protects the next call, not that one.

    What routing does not do
  • The API key is not in settings.json

    Zed derives the variable name from the provider id, upper snake case plus _API_KEY. Two providers mean two variables. Keys typed into Zed go to the system keychain instead.

  • A Responses-only model leaves the chat path

    Zed posts to the Responses endpoint for any model whose capabilities.chat_completions is false. That is a third path. Check the row before you decide the base URL is what broke.

    Which endpoints are registered

Paste it, then send one message.

Open the file with agent: open settings, or use Add Provider under Settings, AI, LLM Providers. Then send one message. Then read the row.

Also: What the ledger is forWhich paths are registeredEvery integration