Compatibility matrix
How each supported client connects, and the contract OpenGateway guarantees. The
machine-checked version of this table lives in tests/compat/ and runs in CI
against a mock gateway.
| Client | Base URL | Wire API | Discovery | Shape | Auth / headers |
| --- | --- | --- | --- | --- | --- |
| Claude Code | <host>/<lane> (no /v1) | Anthropic Messages (+ count_tokens) | optional, gated | Anthropic; claude*/anthropic* ids | x-api-key or Bearer; anthropic-version |
| Codex | <host>/<lane>/v1 | OpenAI Responses only | avoid /v1/models → model_catalog_json | n/a | Bearer |
| OpenCode | <host>/<lane>/v1 | Chat / Responses / Messages | config-declared | n/a | Bearer or x-api-key |
| Cursor | <host>/<lane>/v1 | OpenAI Chat | required 200 | OpenAI | Bearer |
| Cline / Roo | <host>/<lane>/v1 | OpenAI Chat | optional | OpenAI | Bearer |
| OpenAI SDK | <host>/<lane>/v1 (incl. /v1) | Chat / Responses | on demand | OpenAI | Bearer |
| Anthropic SDK | <host>/<lane> (excl. /v1) | Messages | on demand | Anthropic | x-api-key |
The two hard requirements
Section titled “The two hard requirements”- Dual-shape
GET /v1/models— Anthropic shape whenanthropic-version/x-api-keyis present (idsclaude*/anthropic*), else OpenAI shape returning200(Cursor verification). See Model discovery. - Both wire protocols on every lane, with tolerant auth/headers — accept
Bearerandx-api-key; never400on an unknownanthropic-versionor a retiredanthropic-beta. See Errors.
Client-side caveats (not gateway bugs)
Section titled “Client-side caveats (not gateway bugs)”- Cursor: global base-URL override self-disables periodically; vision via
BYOK hits a hardcoded
api.openai.comvalidation. - Codex: serving the OpenAI list can break its catalog refresh — use
model_catalog_json. - Claude Code: the picker hides non-
claude*/anthropic*ids.
Ask about configuring OpenGateway — lanes, base URLs, client setup, model choice, or an error you hit. Answers are grounded in the docs.