Add a custom OpenAI-compatible provider to Zed.
Updated 2026-07-16
Zed reads custom providers straight from settings.json. Declare a language_models.openai_compatible block with api_url set to https://api.apisrouter.com/v1, list the model ids you want, and every one of them appears in the agent panel model picker under a single key.
Quick answer: one block in settings.json.
Zed supports custom OpenAI-compatible providers natively. Add a provider entry under language_models.openai_compatible in settings.json, set api_url to https://api.apisrouter.com/v1, and declare each model you want under available_models with its name and context size. The models show up in the agent panel model dropdown immediately. The API key deliberately does not go in settings.json. Zed stores it in the system keychain when you enter it through the provider settings UI, or reads it from an environment variable derived from your provider key: a provider named apisrouter reads APISROUTER_API_KEY. Environment variables take precedence over keychain values.
{
"language_models": {
"openai_compatible": {
"apisrouter": {
"api_url": "https://api.apisrouter.com/v1",
"available_models": [
{
"name": "claude-sonnet-4-6",
"display_name": "Claude Sonnet 4.6",
"max_tokens": 200000
}
]
}
}
}
}How Zed resolves custom providers and models.
Zed (zed-industries on GitHub, roughly 87K stars) is a high-performance editor with an agent panel that plans, edits files, and runs tools. Its openai_compatible provider type speaks the standard /v1/chat/completions protocol, which is exactly what a multi-vendor gateway serves, so no plugin or extension sits between the editor and the endpoint. The provider key you choose ("apisrouter" above) does double duty. It names the provider in the agent panel settings, and it generates the environment variable Zed checks for the key, upper-snake-cased with an _API_KEY suffix. That naming rule is worth internalizing before debugging anything: rename the provider and the expected variable name changes with it. available_models is an allowlist. Zed cannot enumerate a custom endpoint on its own, so only the ids you declare become selectable, each one an exact string including any version suffix. When the endpoint behind api_url serves Claude, GPT, Gemini, and Kimi ids side by side, one provider block turns the agent panel picker into a cross-vendor switchboard behind one key. One scope note: Zed's edit predictions feature uses its own dedicated models and is configured separately; a custom provider powers the agent panel and inline assistant, not edit predictions.
Full setup: models, context sizes, and capabilities.
Each available_models entry takes more than a name. max_tokens declares the model's context window, and max_output_tokens caps generation length; Zed uses these figures to manage long agent threads, so declaring a long-context model with a small max_tokens quietly wastes the model's headroom. The capabilities object tells Zed what the model supports: set tools to true for anything you plan to drive the agent panel with, and enable images only for models that genuinely accept image input. For the key, the reliable path on a desktop editor is the provider settings UI, which stores the value in the system keychain. The environment-variable path also works, with one caveat covered in the debugging section: GUI applications launched from the dock do not inherit your shell profile.
{
"language_models": {
"openai_compatible": {
"apisrouter": {
"api_url": "https://api.apisrouter.com/v1",
"available_models": [
{
"name": "claude-sonnet-4-6",
"display_name": "Claude Sonnet 4.6",
"max_tokens": 200000,
"max_output_tokens": 64000,
"capabilities": { "tools": true, "images": false }
},
{
"name": "claude-opus-4-7",
"display_name": "Claude Opus 4.7",
"max_tokens": 200000,
"capabilities": { "tools": true }
},
{ "name": "gpt-5.5", "display_name": "GPT-5.5", "max_tokens": 200000 },
{ "name": "kimi-k2.7-code", "display_name": "Kimi K2.7 Code", "max_tokens": 200000 }
]
}
}
}
}Choosing models for the agent panel.
Because every declared model sits in the same picker, the practical workflow is comparison on real work rather than benchmarks: run the same kind of task through two candidates on different days and let the per-key usage log price each one. A model change in Zed is a dropdown selection, so the cost of the experiment is zero setup.
- The agent panel carries real engineering: reading files, planning multi-step edits, running tools over long threads. A frontier coding model (claude-sonnet-4-6, claude-opus-4-7, gpt-5.5) belongs in this slot.
- Coding-tuned ids like kimi-k2.7-code are worth declaring even when they are not your default; switching for a refactor-heavy session is one picker selection, not a config edit.
- Long-context models such as gemini-3.1-pro-preview earn their place when threads routinely pull large files or whole-module context into a single conversation.
- Inline assist is shorter-lived than agent threads, so a fast mid-tier id keeps single-shot transformations snappy without burning frontier tokens on one-line rewrites.
Pay-as-you-go · transparent per-model pricing
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| Model | Official Price | Our Price |
|---|---|---|
| Claude Sonnet 4.6 | $3.00 / $15.00 per M | $2.40 / $12.00 per M |
| Claude Opus 4.7 | $5.00 / $25.00 per M | $4.00 / $20.00 per M |
| GPT-5.5 | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| Kimi K2.7 Code | $0.95 / $4.00 per M | $0.85 / $3.60 per M |
| Gemini 3.1 Pro Preview | $2.00 / $12.00 per M | $1.60 / $9.60 per M |
The failure modes specific to Zed custom providers.
The key is in settings.json and nothing works. Zed does not read API keys from settings.json by design. Enter the key in the provider settings UI, or export the derived environment variable; a key pasted into the JSON is ignored. The environment variable is set but Zed still asks for a key. The variable name is derived from the provider key, upper-snake-cased with _API_KEY appended, so a provider named apisrouter needs APISROUTER_API_KEY, not OPENAI_API_KEY. And on macOS, an app launched from the dock never sources your shell profile, so profile exports are invisible to it. Launch Zed from a terminal with the zed command, or use the keychain path and skip the problem entirely. A model is missing from the picker. available_models is an allowlist; an id you assumed but never declared simply does not exist. Ids are exact strings including version suffixes, and the gateway's /v1/models listing is the authoritative spelling to copy from. The agent cannot use tools. If a model's capabilities block says tools is false, Zed will not offer tool use with it. Declare capabilities to match what the model actually supports. api_url without /v1. The client appends route paths like /chat/completions to the base you give it, so https://api.apisrouter.com/v1 is correct and the bare host is not. A 404-shaped failure on an otherwise correct block is almost always this.
Who routes Zed through a gateway.
- Developers who live in the editor and want Claude, GPT, and Kimi in one agent panel picker instead of maintaining separate provider credentials per vendor.
- Engineers comparing coding models on real edits. Every candidate is one declared entry and one dropdown selection; no new accounts per experiment.
- Teams standardizing one secret. A single APISROUTER_API_KEY in onboarding docs replaces a per-vendor key checklist, and per-key usage shows what each seat spends.
- Users pairing a frontier agent model with a fast inline-assist model from a different vendor, which single-vendor configs cannot express.
- Developers without access to a given vendor's billing. Top-up based access with no card requirement removes the sign-up dependency per provider.
Verify the endpoint and debug the first thread.
Before starting an agent thread, list what the gateway serves. The ids returned by /v1/models are exactly the strings your available_models entries must use. First-thread failures are consistent. A 401 means the key Zed resolved is wrong or absent: check the keychain entry in provider settings, or confirm the derived environment variable is visible to the Zed process rather than just to your terminal. A model-not-found error from the gateway means a declared name does not match a served id, version suffix included. If the provider block does not appear in settings at all, validate the JSON; settings.json tolerates comments but not structural errors. Once requests flow, the APIsRouter console shows per-request model, token counts, and spend. Agent threads are long-context, many-turn workloads, and seeing which threads and which models consume the tokens is how you decide whether your default model is earning its slot.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50FAQ
Can Zed use Claude, GPT, and Kimi models through one custom provider?
Yes. A custom provider is an api_url plus an available_models allowlist. When the endpoint serves multiple vendors, declare one entry per id and every declared model appears in the agent panel picker under the same provider and key, switchable per thread.
Where does the API key go for a Zed custom provider?
Not in settings.json. Enter it in the provider settings UI, which stores it in the system keychain, or export the environment variable derived from your provider key: a provider named apisrouter reads APISROUTER_API_KEY. Environment variables take precedence over keychain values.
Why does Zed ignore the API key I exported in my shell profile?
GUI apps launched from the dock never source your shell profile, so the export is invisible to them. Launch Zed from a terminal with the zed command so it inherits the variable, or use the settings UI and let the keychain hold the key.
Why is my model missing from the agent panel picker?
Custom-provider models must be declared explicitly; Zed cannot enumerate a custom endpoint. Check that available_models contains the exact id string, including version suffixes, and copy ids from the gateway's /v1/models response rather than typing them from memory.
What do max_tokens and max_output_tokens control in available_models?
max_tokens declares the model's context window and max_output_tokens caps generation length. Zed uses these to manage long agent threads, so set max_tokens to what the model genuinely supports; understating it wastes context the model actually has.
Does a custom provider change Zed's edit predictions?
No. Edit predictions run on Zed's own dedicated models and are configured separately. A custom OpenAI-compatible provider powers the agent panel and inline assistant, which is where the /v1/chat/completions traffic goes.