Crush: an openai-compat provider in crushrc
Add uttapen to Crush with provider add --type openai-compat, register models with context-window and default-max-tokens, and set a cheap small model.
Updated: 22 Sep 2026
Crush is Charm's terminal coding agent. Recent versions configure it through crushrc, a Bash file that runs at startup and understands Crush's own builtin commands (the older crush.json is still read but deprecated). This page was checked against the official repository docs in September 2026.
crushrc
Use ~/.config/crush/crushrc globally, or .crushrc in the project root:
provider add uttapen \
--type openai-compat \
--base-url "https://api.uttapen.ir/v1" \
--api-key "$UTTAPEN_API_KEY"
model add uttapen/anthropic/claude-sonnet-5 \
--name "Claude Sonnet 5" \
--context-window 200000 \
--default-max-tokens 8192
model add uttapen/openai/gpt-5-nano \
--name "GPT-5 nano" \
--context-window 400000 \
--default-max-tokens 1024
model large uttapen/anthropic/claude-sonnet-5
model small uttapen/openai/gpt-5-nano
Then put the key in the environment — or, since this is Bash, read it from a password manager inside the file:
export UTTAPEN_API_KEY="sk-up-..."
Four details that decide your bill
- Always pass
--type openai-compat. Theopenaitype switches to the Responses API for any id matchinggpt-4throughgpt-9. uttapen doesn't serve that path, so those calls return404. - Register models by hand. With an empty model list Crush reads
GET /v1/models, keeps only the ids, and leavescontext_windowanddefault_max_tokensat zero: no output ceiling is sent, auto-summarising is disabled, and 400+ models flood the picker. --default-max-tokensis the ceiling we reserve against (pricing).8192is enough for code work; if you hit it, raise it for one session withmodel large … --max-tokens 16000.- Set
model small. Session titles run on the small model with a tiny ceiling; without it Crush uses the provider's first model for both slots.
Take ids from the model list; a / inside the id is fine, because Crush only treats the first / as the provider separator. For lighter work use qwen/qwen3-coder or deepseek/deepseek-v3.2, and for titles and small jobs openai/gpt-5-nano or google/gemini-2.5-flash-lite.
Checking that it works
Open Crush in a project, pick the model and ask something short; then find the two requests (title and message) in Dashboard → Usage.
Troubleshooting
| Error | Cause in Crush | Fix |
|---|---|---|
401 invalid_api_key | UTTAPEN_API_KEY is empty in the environment Crush started from | Export it and restart |
404 model_not_found | A wrong id in model add | Copy it from /en/models (the 404 also lists the closest ids it guessed, in uttapen.suggestions) |
404 not_found | The provider was created with --type openai | Recreate it with --type openai-compat |
402 insufficient_balance | Low balance, or an oversized hold because no ceiling was set | Set --default-max-tokens and top up |
429 | The key's rate or monthly limit (rate limits) | Wait, or raise the limit |
| Reply cut short | The model hit the output ceiling | Raise the large model's --max-tokens |
When the available balance can't cover the whole output ceiling, uttapen lowers it to what the balance allows (floor 1,024 tokens) and returns the granted value in the X-Uttapen-Max-Tokens header. 402 only appears when even that floor doesn't fit.
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 →