id: PX-RESEARCH-8WQ4KZ2M
type: research
title: OpenCode Free Tier Lock
OpenCode Free Tier Lock
Why opencode/zen cannot be a gratis backend. Complements Kilo Gateway Free Access.
All probes 2026, live HTTP and public source; no secrets involved.
Facts
Two surfaces exist and must not be conflated: opencode free (zero-setup models inside the OpenCode TUI) and Zen (the opencode.ai/zen/v1 gateway with console API keys). In OpenCode's own source and models.dev, provider opencode = "OpenCode Zen" (env OPENCODE_API_KEY); Zen catalog on models.dev lists ~15 free models (big-pickle, grok-code, *-free, muse-spark-*-contributor-free, …).
Live probe: GET /zen/v1/models anonymous → 200, but zero free IDs in the public response; free roster is not publicly listed.
Live probe: POST /zen/v1/chat/completions (big-pickle) anonymous → 403 FreeTierError "OpenCode's free tier can only be used from within OpenCode".
Independent confirmation: freellmapi server catalog (issues #1249, #1204) — free models return the same 403 on a valid Zen key, and sending OpenCode client headers does not change it; they tried, reverted, and disabled the free rows. The provider remains registered there only for paid models.
OpenCode client source (packages/core/src/plugin/provider/opencode.ts): the "opencode" integration authenticates via OAuth device flow against https://opencode.ai/console (client opencode-cli) or a service-account key; free access inside the TUI rides this client identity.
A Zen console key is free to create, but it unlocks paid models only — it grants no free inference from non-OpenCode clients.
How the lock is enforced
No secret is involved: the gateway fingerprints each request against what the official client sends, and tightens the check when third parties copy it.
opencode#50627: same headers, account, and model; an agent without the bash tool got FreeTierError
Minimum client version
opencode#49433: variant message "1.17.0 or newer is required"
The check changes server-side while the official client updates in step: mimicking proxies broke after changes (9router#4101; opencode2dsh#9, broken since 2026-09-17).
It also misfires on the real client: tool-restricted agents, and reportedly compaction requests (opencode#49609).
This reconciles freellmapi's finding that headers alone do not help: headers are necessary, not sufficient.
Conclusion
The TUI's "open opencode and it just works" experience is real but is a client-locked free tier: a moving server-side fingerprint of the OpenCode client, not a key.
Open source makes the check readable, not stable: passing it means impersonating the client down to its tool list and session fingerprint, and it breaks at the next server change.
Consequences for gratis: no opencode backend, no GRATIS_OPENCODE_TOKEN; a mimic would be visible-but-broken by design, would send OpenCode's tool definitions and session identity with the user's requests, and would violate the grts/auto no-disruption rule.
This mirrors the post-mortem lesson: do not build on unlabeled, uncontractual access.
Unresolved questions
Which fingerprint fields the gateway checks today; the evidence is observational and changes over time.
Whether OpenCode ever offers a sanctioned free API for other clients; that would reopen this verdict.
---
id: PX-RESEARCH-8WQ4KZ2M
type: research
title: OpenCode Free Tier Lock
---
## OpenCode Free Tier Lock
Why `opencode`/`zen` cannot be a gratis backend. Complements [Kilo Gateway Free Access](../PX-RESEARCH-KZ2M6WQ4-kilo-gateway-free-access/index.md).
All probes 2026, live HTTP and public source; no secrets involved.
### Facts
- Two surfaces exist and must not be conflated: **opencode free** (zero-setup models inside the OpenCode TUI) and **Zen** (the `opencode.ai/zen/v1` gateway with console API keys). In OpenCode's own source and models.dev, provider `opencode` = "OpenCode Zen" (env `OPENCODE_API_KEY`); Zen catalog on models.dev lists ~15 free models (`big-pickle`, `grok-code`, `*-free`, `muse-spark-*-contributor-free`, …).
- Live probe: `GET /zen/v1/models` anonymous → 200, but **zero free IDs** in the public response; free roster is not publicly listed.
- Live probe: `POST /zen/v1/chat/completions` (`big-pickle`) anonymous → **403 `FreeTierError`** "OpenCode's free tier can only be used from within OpenCode".
- Independent confirmation: freellmapi server catalog (issues #1249, #1204) — free models return the same 403 **on a valid Zen key**, and sending OpenCode client headers does not change it; they tried, reverted, and disabled the free rows. The provider remains registered there only for paid models.
- OpenCode client source (`packages/core/src/plugin/provider/opencode.ts`): the "opencode" integration authenticates via OAuth device flow against `https://opencode.ai/console` (client `opencode-cli`) or a service-account key; free access inside the TUI rides this client identity.
- A Zen console key is free to create, but it unlocks **paid models only** — it grants no free inference from non-OpenCode clients.
### How the lock is enforced
No secret is involved: the gateway fingerprints each request against what the official client sends, and tightens the check when third parties copy it.
| Signal | Evidence |
| --- | --- |
| Client headers: `user-agent: opencode/<version> …`, `x-opencode-client`, `x-opencode-project`, `x-opencode-session`, `x-opencode-request` | [opencode#50627](https://github.com/anomalyco/opencode/issues/50627) lists them on a real client request |
| Session id derived from a conversation fingerprint, as the SDK does | [opencode2api architecture](https://raw.githubusercontent.com/MidasStore/winoc2api/main/opencode-zen-adapter/docs/architecture.md): reproducing it passed the 403 for a while |
| Request body shape: the standard tool set | [opencode#50627](https://github.com/anomalyco/opencode/issues/50627): same headers, account, and model; an agent without the `bash` tool got `FreeTierError` |
| Minimum client version | [opencode#49433](https://github.com/anomalyco/opencode/issues/49433): variant message "1.17.0 or newer is required" |
The check changes server-side while the official client updates in step: mimicking proxies broke after changes ([9router#4101](https://github.com/decolua/9router/issues/4101); [opencode2dsh#9](https://github.com/FishBottle7/opencode2dsh/issues/9), broken since 2026-09-17).
It also misfires on the real client: tool-restricted agents, and reportedly compaction requests ([opencode#49609](https://github.com/anomalyco/opencode/issues/49609)).
This reconciles freellmapi's finding that headers alone do not help: headers are necessary, not sufficient.
### Conclusion
The TUI's "open opencode and it just works" experience is real but is a client-locked free tier: a moving server-side fingerprint of the OpenCode client, not a key.
Open source makes the check readable, not stable: passing it means impersonating the client down to its tool list and session fingerprint, and it breaks at the next server change.
Consequences for gratis: no `opencode` backend, no `GRATIS_OPENCODE_TOKEN`; a mimic would be visible-but-broken by design, would send OpenCode's tool definitions and session identity with the user's requests, and would violate the `grts/auto` no-disruption rule.
This mirrors the post-mortem lesson: do not build on unlabeled, uncontractual access.
### Unresolved questions
- Which fingerprint fields the gateway checks today; the evidence is observational and changes over time.
- Whether OpenCode ever offers a sanctioned free API for other clients; that would reopen this verdict.