Zed: openai_compatible provider in settings.json
Add uttapen to Zed with an openai_compatible block in settings.json: model list, max_output_tokens to keep holds small, cheap models for commit messages.
Updated: 22 Sep 2026
The Zed editor has an "OpenAI API Compatible" provider type built for exactly this. This page was checked against the docs for version 1.20.
Adding the provider
From the UI: Settings → AI → LLM Providers → Add Provider, which asks for a name, API URL, model id and context size. Or edit settings.json directly:
{
"language_models": {
"openai_compatible": {
"uttapen": {
"api_url": "https://api.uttapen.ir/v1",
"available_models": [
{
"name": "anthropic/claude-sonnet-5",
"display_name": "Claude Sonnet 5",
"max_tokens": 200000,
"max_output_tokens": 8192,
"capabilities": { "tools": true, "images": true }
},
{
"name": "openai/gpt-5-nano",
"display_name": "GPT-5 nano",
"max_tokens": 400000,
"max_output_tokens": 1024
}
]
}
}
}
}
nameis the id we receive; a/in it is fine.max_tokensis the context window, not the output ceiling. That is Zed's naming, and it's where everyone trips up first.- Always set
max_output_tokens. Without it Zed sends no output ceiling at all, so our hold falls back to a default estimate; if the model writes more, the real amount is still deducted in full and the balance can dip negative (pricing). capabilities.toolsis on by default,imagesis off. Turn images on for a model that really accepts them (vision).
The API key
Don't put the key in settings.json. Either enter it in Zed's provider screen, where it goes to the system keychain, or set an environment variable named after the provider id in upper snake case plus _API_KEY. For the id uttapen:
export UTTAPEN_API_KEY="sk-up-..."
Models and roles
Take ids from the model list: anthropic/claude-sonnet-5, openai/gpt-5, qwen/qwen3-coder or deepseek/deepseek-v3.2 for coding.
Zed also picks models for side jobs, all under the agent key as a provider-and-model pair:
{
"agent": {
"default_model": { "provider": "uttapen", "model": "anthropic/claude-sonnet-5" },
"commit_message_model": { "provider": "uttapen", "model": "openai/gpt-5-nano" },
"thread_summary_model": { "provider": "uttapen", "model": "openai/gpt-5-nano" }
}
}
inline_assistant_model, compaction_model and subagent_model follow the same shape and fall back to default_model when unset. Commit messages and thread summaries are tiny jobs; sending them to something cheap like openai/gpt-5-nano keeps background spend near zero.
Edit prediction (inline completion) is configured separately and uses the /v1/completions path. If you enable it, keep its max_output_tokens small — it fires as you type.
Checking that it works
Open the Agent panel, select the uttapen model, ask something short, then find the request in Dashboard → Usage.
Troubleshooting
| Error | Cause in Zed | Fix |
|---|---|---|
401 invalid_api_key | No key entered, or the env var name doesn't match the provider id | Enter it in the UI, or export UTTAPEN_API_KEY |
404 model_not_found | name doesn't match a real id | Copy it from /en/models (the 404 also lists the closest ids it guessed, in uttapen.suggestions) |
404 not_found | The block sits under the built-in openai provider with a custom api_url | Move it under openai_compatible |
402 insufficient_balance | Balance below the required hold | Top up, and lower max_output_tokens |
429 | The key's rate or monthly limit (rate limits) | Wait, or raise the limit |
| Reply cut short | The model hit max_output_tokens | Raise it |
When the available balance can't cover the whole output ceiling, uttapen lowers it to fit (floor 1,024 tokens) and returns the granted value in the X-Uttapen-Max-Tokens header. 402 is only for the case where even that floor is unaffordable.
Other tools are in integrations; error codes are in errors.
Sign up with a phone number, top up your wallet from 100,000 toman and create a key. Free models work without a top-up — up to 50 requests a day. Create an API key →