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. The openai type switches to the Responses API for any id matching gpt-4 through gpt-9. uttapen doesn't serve that path, so those calls return 404.
  • Register models by hand. With an empty model list Crush reads GET /v1/models, keeps only the ids, and leaves context_window and default_max_tokens at zero: no output ceiling is sent, auto-summarising is disabled, and 400+ models flood the picker.
  • --default-max-tokens is the ceiling we reserve against (pricing). 8192 is enough for code work; if you hit it, raise it for one session with model 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

ErrorCause in CrushFix
401 invalid_api_keyUTTAPEN_API_KEY is empty in the environment Crush started fromExport it and restart
404 model_not_foundA wrong id in model addCopy it from /en/models (the 404 also lists the closest ids it guessed, in uttapen.suggestions)
404 not_foundThe provider was created with --type openaiRecreate it with --type openai-compat
402 insufficient_balanceLow balance, or an oversized hold because no ceiling was setSet --default-max-tokens and top up
429The key's rate or monthly limit (rate limits)Wait, or raise the limit
Reply cut shortThe model hit the output ceilingRaise 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.

No API key yet?

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 →