Choosing a coding model: a filter, not a ranking
27 text models across four lineups, from $0.050 to $4.00 per million input tokens. Four constraints narrow that to a shortlist you can test in an afternoon.
Start with the route, because it costs code
The catalog holds 27 text models. Before comparing any of them on quality or price, split them by the endpoint they answer on, because that is the only difference that makes switching expensive.
13 answer on /v1/messages — every Claude id, plus stable-gpt-6-astra. They take x-api-key and anthropic-version headers, a messages array, and a required max_tokens. Six answer on /v1/responses: gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.4, gpt-5.4-mini. They take Authorization: Bearer and an input field. Eight answer on /v1/chat/completions: grok-4.6, grok-4.5, grok-composer-2.5-fast and the five Gemini ids, also on Authorization: Bearer.
If you are already integrated against one of these shapes, moving inside it is a one-field change and moving across it is a small project. That is a real cost, and it belongs in the comparison rather than being discovered afterwards. If you are starting fresh, no route is privileged — pick on the other three constraints and let the route follow.
Then the two ceilings, because they eliminate
Context is how much you can send in one request. If you paste whole files, long stack traces or a repository index, measure a real prompt before shortlisting. The tiers: 200,000 tokens on claude-sonnet-4-6, stable-claude-sonnet-4-6, stable-claude-haiku-4-5 and grok-composer-2.5-fast; 272,000 on gpt-5.5, gpt-5.4 and gpt-5.4-mini; 372,000 on the three gpt-5.6 ids; 500,000 on grok-4.6 and grok-4.5; 1,000,000 on nine Claude ids and all five Gemini ids; 1,050,000 on stable-gpt-6-astra.
Output ceiling is how much can come back in one response, and it is the constraint people forget. Every Gemini id caps at 65,536 tokens (65,535 on gemini-3.1-pro-low), as do grok-4.6 and grok-4.5. grok-composer-2.5-fast caps at 32,768. gpt-5.5, gpt-5.4, gpt-5.4-mini, claude-sonnet-4-6, stable-claude-sonnet-4-6 and stable-claude-haiku-4-5 cap at 64,000. The 128,000-token ceiling belongs to the Claude 1M family, the three gpt-5.6 ids and stable-gpt-6-astra.
Generating a large file or a wide refactor in one response is where the output ceiling bites. Reading a large codebase and answering briefly is where only the context ceiling matters. Most coding work is the second kind, which is why the cheap high-context ids stay in contention longer than people expect.
Then price, computed rather than guessed
Consumer price is the official per-token rate times that model’s multiplier, so never compare multipliers directly — they are applied to different base rates. gpt-5.6-luna is 0.3× and bills $0.06 per million input; gpt-5.4-mini is 0.1× and bills $0.075. The higher multiplier is the cheaper model.
Effective input and output rates per million, for the ids most people shortlist for coding: gemini-3-flash $0.050/$0.30, gpt-5.6-luna $0.06/$0.36, gemini-3.7-flash-high and gemini-3.6-flash-high $0.075/$0.375, gpt-5.4-mini $0.075/$0.45, grok-composer-2.5-fast $0.15/$0.75, gemini-3.8-flash $0.15/$0.75, grok-4.6 and grok-4.5 $0.20/$0.60, gpt-5.6-terra $0.20/$1.20, gemini-3.1-pro-low $0.20/$1.20, gpt-5.4 $0.25/$1.50, claude-sonnet-5 $0.30/$1.50, stable-claude-haiku-4-5 $0.40/$2.00, claude-opus-5 $0.50/$2.50, gpt-5.6-sol $0.50/$3.00, gpt-5.5 $0.50/$3.00.
Two structural notes. Output costs 3× to 6× input on every model in the catalog, so anything that lengthens responses lands on the expensive side — grok-4.6 and grok-4.5 have the narrowest ratio at 3×, the six gpt-5.x ids and two of the Gemini ids the widest at 6×. And a stable-* id is a dedicated lane on our own key rather than the shared pool: same weights, no pool failover, and a higher multiplier. claude-sonnet-5 is $0.30/$1.50; stable-claude-sonnet-5 is $0.80/$4.00. That is a routing choice, independent of which model you picked.
The last constraint is the one you have to measure
Three filters leave you two or three candidates. The remaining question — which one is actually good at your code — is not in models.json and cannot be. The catalog records capabilities, ceilings and rates; it does not record whether a model understands your build system or writes the kind of tests your reviewers accept.
A test that fits in an afternoon: collect fifteen to twenty tasks you have already completed and can grade objectively — a bug with a known fix, a refactor you shipped, a function with a test suite. Run each through your shortlist with the same prompt, and score the failures rather than the wins. Anyone can produce plausible code; the difference shows up in what happens when the task is underspecified.
Then convert quality into money. Read input and output token counts from each response’s usage block and multiply by that model’s effective rates. This is where a per-token ranking regularly inverts: a model at $0.50/$3.00 that solves a task in one attempt with a short answer can cost less than one at $0.075/$0.45 that needs three attempts and explains itself at length. Run the numbers on your own tasks, and re-run them when you change the prompt — the answer is a property of your workload, not of the models.
TASK="Here is a failing test and the function under test. Fix the function."
# /v1/messages — claude-sonnet-5 ($0.30 / $1.50 per M)
curl -sS https://token-share.app/v1/messages \
-H "x-api-key: $TOKEN_SHARE_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d "{\"model\":\"claude-sonnet-5\",\"max_tokens\":2048,\"messages\":[{\"role\":\"user\",\"content\":\"$TASK\"}]}" \
| jq '{model: "claude-sonnet-5", usage}'
# /v1/responses — gpt-5.6-terra ($0.20 / $1.20 per M)
curl -sS https://token-share.app/v1/responses \
-H "Authorization: Bearer $TOKEN_SHARE_KEY" \
-H "content-type: application/json" \
-d "{\"model\":\"gpt-5.6-terra\",\"input\":\"$TASK\"}" \
| jq '{model: "gpt-5.6-terra", usage}'
# /v1/chat/completions — grok-4.6 ($0.20 / $0.60 per M)
curl -sS https://token-share.app/v1/chat/completions \
-H "Authorization: Bearer $TOKEN_SHARE_KEY" \
-H "content-type: application/json" \
-d "{\"model\":\"grok-4.6\",\"messages\":[{\"role\":\"user\",\"content\":\"$TASK\"}]}" \
| jq '{model: "grok-4.6", usage}'