Back to Blog
Developer GuideNovember 12, 20268 min read

One key. Every model. Codex and Claude Code included.

Codex CLI and Claude Code now connect to unbottled.ai directly, next to OpenCode, Continue, Aider and Cline. One base URL, one key, one command per tool.

Your coding agent is locked to one vendor's models. Want a second opinion from another lab, a cheaper model for grunt work, or a model that does not refuse? That means another account, another key, another bill.

unbottled.ai speaks all three formats coding agents use: OpenAI chat completions, the OpenAI Responses API and the Anthropic Messages API. Nothing to install in between. Point a tool at us once, then switch between Claude, GPT, DeepSeek, GLM, Kimi, Qwen and the uncensored models by changing one model id.

Why bother

  • One key, one balance. No separate accounts at Anthropic, OpenAI, DeepSeek, Moonshot and Z.ai.
  • Uncensored models in your editor. Security research, red-team prompts, fiction tooling, data that trips mainstream filters. You pick the filter level, not the vendor.
  • Right model per task. A frontier model for the hard refactor, a flash model for renames and test scaffolding. Same config, different id.
  • Same credits as the chat app, same prices. Every response reports what it cost.

Get a key and a base URL

Two values. Every tool below needs exactly these.

Create a key under Settings > API keys. It starts with sk-unb- and is shown once. The API is part of every paid plan: an active subscription or any credit pack unlocks it.

Base URL: https://unbottled.ai/api/en-GLOBAL/v1

For OpenAI-style tools: Codex, OpenCode, Continue, Aider, Cline. The locale in the path only changes the language of error messages.

Anthropic base URL: https://unbottled.ai/api/en-GLOBAL

For Claude Code and Anthropic SDKs. Same URL without /v1: they add /v1/messages themselves.

Check your key
terminal
export UNBOTTLED_API_KEY="sk-unb-YOUR_KEY"

curl https://unbottled.ai/api/en-GLOBAL/v1/models \
  -H "Authorization: Bearer $UNBOTTLED_API_KEY"
First request
terminal
curl https://unbottled.ai/api/en-GLOBAL/v1/chat/completions \
  -H "Authorization: Bearer $UNBOTTLED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"glm-5.3","messages":[{"role":"user","content":"Hello"}]}'

Keep the key in an environment variable, never in a file you commit. The curl call proves the key works and lists every model id your account can call, with context size, tool support and credit prices.

Fastest path: right after you create a key, the API keys page shows every block below with your key already filled in. Pick your tool, copy, run.

Every tool connects directly

Coding agents speak three different wire formats. We serve all three, on the same key and the same models.

  • Codex CLI: OpenAI Responses API.
  • Claude Code: Anthropic Messages API.
  • OpenCode, Continue, Aider, Cline: OpenAI chat completions.

Anything else with a base URL field works the same way: base URL, key, model id.

Settings
settings
# OpenAI-compatible tools (chat completions or Responses API)
Base URL:  https://unbottled.ai/api/en-GLOBAL/v1
API key:   sk-unb-YOUR_KEY
Model:     glm-5.3

# Anthropic-compatible tools (Messages API)
Base URL:  https://unbottled.ai/api/en-GLOBAL
API key:   sk-unb-YOUR_KEY
Model:     glm-5.3
Responses API

Codex CLI

OpenAI's terminal agent. Reads your repo, runs commands, edits files. Tested with Codex CLI 0.118.0.

Codex speaks the Responses API, and so do we. The one command defines the provider inline: nothing to edit, nothing to install. For daily use, append the config once and start Codex with the profile.

One command
terminal
UNBOTTLED_API_KEY="sk-unb-YOUR_KEY" codex \
  -c 'model_providers.unbottled={name="unbottled.ai",base_url="https://unbottled.ai/api/en-GLOBAL/v1",env_key="UNBOTTLED_API_KEY",wire_api="responses"}' \
  -c model_provider=unbottled \
  -m glm-5.3
Permanent setup
~/.codex/config.toml
[model_providers.unbottled]
name = "unbottled.ai"
base_url = "https://unbottled.ai/api/en-GLOBAL/v1"
env_key = "UNBOTTLED_API_KEY"
wire_api = "responses"

[profiles.unbottled]
model_provider = "unbottled"
model = "glm-5.3"
Then start it
terminal
export UNBOTTLED_API_KEY="sk-unb-YOUR_KEY"
codex --profile unbottled

Switch models with -m or the model line in the profile. Keep wire_api = "responses": current Codex accepts nothing else.

Messages API

Claude Code

Anthropic's terminal agent. Plans, edits, runs tests, spawns subagents. Tested with Claude Code 2.1.323.

Claude Code reads its gateway from environment variables. ANTHROPIC_BASE_URL is the base URL without /v1. ANTHROPIC_MODEL sets the main model. The OPUS and SONNET defaults cover the model picker and plan mode, the HAIKU default moves background jobs such as session titles to a cheap model, and CLAUDE_CODE_SUBAGENT_MODEL covers subagents. CLAUDE_CODE_MAX_CONTEXT_TOKENS tells Claude Code the real context size of a non-Claude model, so it compacts at the right point.

One command
terminal
ANTHROPIC_BASE_URL="https://unbottled.ai/api/en-GLOBAL" \
ANTHROPIC_AUTH_TOKEN="sk-unb-YOUR_KEY" \
ANTHROPIC_MODEL="glm-5.3" \
ANTHROPIC_DEFAULT_OPUS_MODEL="glm-5.3" \
ANTHROPIC_DEFAULT_SONNET_MODEL="glm-5.3" \
ANTHROPIC_DEFAULT_HAIKU_MODEL="glm-5.3-flash" \
CLAUDE_CODE_SUBAGENT_MODEL="glm-5.3" \
CLAUDE_CODE_MAX_CONTEXT_TOKENS="1048576" \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1" \
claude
Permanent setup
~/.claude/settings.json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://unbottled.ai/api/en-GLOBAL",
    "ANTHROPIC_AUTH_TOKEN": "sk-unb-YOUR_KEY",
    "ANTHROPIC_MODEL": "glm-5.3",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-5.3",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-5.3",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-5.3-flash",
    "CLAUDE_CODE_SUBAGENT_MODEL": "glm-5.3",
    "CLAUDE_CODE_MAX_CONTEXT_TOKENS": "1048576",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}
Then start it
terminal
claude

Want Claude itself? Drop the model lines. Claude Code asks for its usual Claude ids and we route them to our matching Claude model, billed in credits.

Claude Code sends a big system prompt, over 30k input tokens even for a trivial task. A cheap default model keeps that affordable.

Chat completions

OpenCode

Open-source terminal agent with a TUI and a headless run mode. Tested with OpenCode 1.19.5.

Save the config as opencode.json in your project, or as ~/.config/opencode/opencode.json for every project. The key stays in your environment. Add any id from GET /v1/models to the models map, then pick one with /models in the TUI.

One command
terminal
UNBOTTLED_API_KEY="sk-unb-YOUR_KEY" \
OPENCODE_CONFIG_CONTENT='{"provider":{"unbottled":{"npm":"@ai-sdk/openai-compatible","options":{"baseURL":"https://unbottled.ai/api/en-GLOBAL/v1","apiKey":"{env:UNBOTTLED_API_KEY}"},"models":{"glm-5.3":{}}}},"model":"unbottled/glm-5.3"}' \
opencode
Permanent setup
opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "unbottled": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "unbottled.ai",
      "options": {
        "baseURL": "https://unbottled.ai/api/en-GLOBAL/v1",
        "apiKey": "{env:UNBOTTLED_API_KEY}"
      },
      "models": {
        "glm-5.3": { "name": "GLM-5.3" },
        "claude-sonnet-5.5": { "name": "Claude Sonnet 5.5" },
        "glm-5.3-uncensored": { "name": "GLM 5.3 Uncensored" }
      }
    }
  },
  "model": "unbottled/glm-5.3"
}
Then start it
terminal
export UNBOTTLED_API_KEY="sk-unb-YOUR_KEY"
opencode
Update OpenCode first. Old 1.0.x builds pull the newest @ai-sdk/openai-compatible package and crash after the first tool call with DecimalError: Invalid argument. 1.19.5 runs the same config clean.
Chat completions

Continue

Coding assistant for VS Code and JetBrains, plus the cn CLI. Tested with Continue 1.5.47.

Permanent setup
config.yaml
name: unbottled
version: 1.0.0
schema: v1
models:
  - name: GLM-5.3
    provider: openai
    model: glm-5.3
    apiBase: https://unbottled.ai/api/en-GLOBAL/v1
    apiKey: ${{ secrets.UNBOTTLED_API_KEY }}
    roles: [chat, edit, apply]
Then start it
terminal
export UNBOTTLED_API_KEY="sk-unb-YOUR_KEY"
cn --config ./config.yaml

secrets.UNBOTTLED_API_KEY resolves from your environment. Add -p with a prompt for a headless run. The IDE extension reads ~/.continue/config.yaml: put the same model entry there.

Chat completions

Aider

Pair programming in your terminal, commits included. Tested with Aider 0.86.2.

One command, no config file. Aider wants openai/ in front of the model id and strips it before it calls us. --edit-format diff keeps edits small; without it Aider falls back to resending whole files for model ids it does not know. Name the files to edit on the command line, as usual with Aider.

One command
terminal
OPENAI_API_BASE="https://unbottled.ai/api/en-GLOBAL/v1" \
OPENAI_API_KEY="sk-unb-YOUR_KEY" \
aider --model openai/glm-5.3 --edit-format diff --no-show-model-warnings
Chat completions

Cline

Autonomous coding agent, in VS Code and as a CLI. Tested with Cline 3.0.74.

Two commands with the Cline CLI: save the provider once, then run cline. Base URL, key and model id are the same three values as everywhere else.

One command
terminal
cline auth -p openai -k "sk-unb-YOUR_KEY" -b "https://unbottled.ai/api/en-GLOBAL/v1" -m glm-5.3
Then start it
terminal
cline

Which model for which job

All of these call tools, which agents need. Ids are what goes in your config.

Hard problems

Large refactors, unfamiliar codebases, multi-step debugging. Higher credit prices, fewer wrong turns.

  • claude-sonnet-5.5Claude Sonnet 5.5
  • claude-opus-5.5Claude Opus 5.5
  • gpt-6.1-solGPT-6.1 Sol
  • kimi-k3.1-proKimi K3.1 Pro
  • deepseek-v4-proDeepSeek V4 Pro

Cheap and fast

Renames, tests, boilerplate, background jobs. A fraction of a frontier model's price. Good default for agents that send big prompts.

  • glm-5.3GLM-5.3
  • glm-5.3-flashGLM-5.3 Flash
  • qwen-3.8-flashQwen 3.8 Flash
  • claude-haiku-5.5Claude Haiku 5.5

Uncensored

Same agent workflow, no refusal reflex. Exploit analysis, red-team tooling, adult fiction pipelines, scrapers other models lecture you about. You stay responsible for what you build.

  • glm-5.3-uncensoredGLM 5.3 Uncensored
  • venice-deepseek-v4.1-flash-uncensoredDeepSeek V4.1 Flash Uncensored
  • qwen-3.6-plus-uncensoredQwen 3.6 Plus Uncensored
  • venice-uncensoredVenice Uncensored 1.2
Ids change as models get replaced. GET /v1/models is the source of truth: if an id is not listed for your key, the API returns 404 model_not_found. The one mapping is for Claude Code: its built-in Claude ids go to our newest Claude of the same family.

Gotchas we hit

So you do not have to.

  • Copy the base URL exactly, /api/<locale>/v1 included. Without the locale you get a redirect that some clients drop. Without /api you get an HTML page instead of JSON.
  • Claude Code gets the base URL without /v1. With /v1 it calls /v1/v1/messages and gets a 404.
  • Use the exact id from GET /v1/models, like glm-5.3. Aider wants openai/ in front. Claude Code's built-in Claude ids are mapped for you to our newest Claude of the same family. Any other unknown id returns 404 model_not_found.
  • HTTP 402 with paid_plan_required means the account has no paid plan yet. Any credit pack fixes it.
  • A model without tool support returns 400 tools_not_supported once the agent sends tools. Check supports_tools in GET /v1/models.
  • Each key allows 60 requests per minute. Agents fire many small calls. If you hit 429, give the agent its own key.

Wired up in one command.

Create a key, copy the block for your tool, pick a model. The API docs cover every endpoint, field, error code and streaming detail.

Back to Blog