Available models
—
SubPool provides a high-performance Universal AI Gateway fully compatible with OpenAI Chat Completions and Anthropic Messages protocols. Connect via official SDKs, cURL, or integrate seamlessly into your backend services.
SubPool is a high-performance universal AI gateway. Use one API key to access 50+ leading models from OpenAI, Anthropic, Google Gemini, DeepSeek, and other providers through industry-standard APIs.
| Parameter | Configuration value | Applies to |
|---|---|---|
| Base URL (OpenAI) | https://subpool.net/v1 |
OpenAI SDK, Cursor, Cline, OpenCode, Continue, Python & Node.js |
| Base URL (Anthropic) | https://subpool.net |
Claude Code CLI, Claude Desktop App, @anthropic-ai/sdk |
| API Key | sk-xxxxxxxxxxxxxxxx Create a key at Manage API keys | All requests to the SubPool Gateway |
| Model ID | claude-3-7-sonnet, gpt-4o, deepseek-chat... Find the exact model ID on the Pricing & Models | Automatically routed by model ID |
SubPool accepts both common authentication header formats. Choose the one supported by your tool or library:
Authorization: Bearer sk-xxxxxxxxxxxxxxxx
For the OpenAI Python/Node SDKs, cURL, LangChain, LlamaIndex, and Cursor.
x-api-key: sk-xxxxxxxxxxxxxxxx anthropic-version: 2023-06-01
For the Anthropic SDK, Claude Code CLI, and Claude Desktop.
Run a simple cURL command in your terminal to verify the connection and API key:
curl https://subpool.net/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SUBPOOL_API_KEY" \
-d '{
"model": "claude-3-7-sonnet",
"messages": [
{"role": "system", "content": "You are a helpful AI expert."},
{"role": "user", "content": "Hello! Please confirm the connection to the SubPool Gateway."}
],
"temperature": 0.7
}'
Sample success response (HTTP 200 OK)
{
"id": "chatcmpl-8zV3A4kL9Qx8p",
"object": "chat.completion",
"created": 1729061000,
"model": "claude-3-7-sonnet",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Connection successful! The SubPool Gateway is ready to process your request."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 28,
"completion_tokens": 18,
"total_tokens": 46
}
}
We provide detailed setup guides for Claude Code CLI, Cursor, Cline, Continue, OpenCode, and Codex CLI, including OS-specific instructions and one-click setup scripts.
The API follows the OpenAI API format and supports text generation, SSE streaming, tool/function calling, and vision.
curl https://subpool.net/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SUBPOOL_API_KEY" \
-d '{
"model": "claude-3-7-sonnet",
"messages": [
{"role": "system", "content": "You are a professional software architect."},
{"role": "user", "content": "Explain idempotent APIs with a clear example."}
],
"temperature": 0.7,
"max_tokens": 1500,
"stream": false
}'
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get("SUBPOOL_API_KEY"),
base_url="https://subpool.net/v1",
)
response = client.chat.completions.create(
model="claude-3-7-sonnet",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a quicksort implementation in Python."},
],
temperature=0.7,
stream=False,
)
print(response.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.SUBPOOL_API_KEY,
baseURL: "https://subpool.net/v1",
});
const completion = await client.chat.completions.create({
model: "claude-3-7-sonnet",
messages: [
{ role: "system", content: "You are a TypeScript expert." },
{ role: "user", content: "Define a generic Result type." },
],
stream: false,
});
console.log(completion.choices[0].message.content);
| Field | Type | Description |
|---|---|---|
| model | string (required) | The target model ID (for example, claude-sonnet-5-5, gpt-6.1-sol, or deepseek-chat). |
| messages | array (required) | Messages using the role structure (`system`, `user`, `assistant`, `tool`) and content. |
| stream | boolean (optional) | When `true`, the server streams Server-Sent Events (SSE) token by token. Defaults to `false`. |
| temperature | number (optional) | Controls randomness, from 0.0 (more deterministic) to 2.0 (more creative). For coding, 0.2–0.7 is recommended. |
| max_tokens | integer (optional) | Maximum number of tokens to generate in the response. |
| tools | array (optional) | List of function definitions for OpenAI-compatible tool calling. |
For reasoning models such as DeepSeek R1 or Claude Sonnet with extended thinking, reasoning may be returned in the reasoning_content or in a separate reasoning block:
data: {"choices":[{"delta":{"reasoning_content":"First, let us analyze the base case..."}}]}
data: {"choices":[{"delta":{"content":"Here is the detailed solution..."}}]}
data: [DONE]
For Claude Code CLI, Claude Desktop, and applications using the official Anthropic SDK. Supports extended thinking and prompt caching.
curl https://subpool.net/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $SUBPOOL_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-3-7-sonnet",
"max_tokens": 1500,
"system": "You are a senior software engineer.",
"messages": [
{"role": "user", "content": "Optimize the following SQL query for the fastest possible execution..."}
]
}'
import os
import anthropic
client = anthropic.Anthropic(
api_key=os.environ.get("SUBPOOL_API_KEY"),
base_url="https://subpool.net",
)
message = client.messages.create(
model="claude-3-7-sonnet",
max_tokens=2048,
system="You are a professional programming assistant.",
messages=[
{"role": "user", "content": "Design an event-driven microservices architecture."}
],
)
print(message.content[0].text)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: process.env.SUBPOOL_API_KEY,
baseURL: "https://subpool.net",
});
const message = await client.messages.create({
model: "claude-3-7-sonnet",
max_tokens: 1500,
messages: [{ role: "user", content: "Hello from the Claude SDK!" }],
});
console.log(message.content[0].text);
system: "...", rather than inside the messages.max_tokens (for example: 1024, 2048, or 4096)."thinking": {"type": "enabled", "budget_tokens": 4096} to the request body to enable deeper reasoning.Analyze images, read documents with OCR, review UI/UX designs, and debug screenshots with leading vision models (GPT-6, Claude, Gemini).
SubPool Gateway accepts images directly in chat requests. You can provide a public URL or Base64-encoded string (data:image/jpeg;base64,...).
OCR & document reading
Extract tables, invoices, handwriting, and legal documents with high accuracy.
UI/UX & Frontend Code
Turn screenshots or Figma mockups into complete HTML/Tailwind/React code.
Chart analysis & debugging
Interpret financial charts, system architecture, and error logs captured from a terminal.
In the OpenAI format, a message’s content is an array containing both text and image blocks:
curl https://subpool.net/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SUBPOOL_API_KEY" \
-d '{
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Analyze the system architecture in this diagram and identify potential bottlenecks:"},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/system-architecture.png",
"detail": "high"
}
}
]
}
],
"max_tokens": 1000
}'
import os
import base64
from openai import OpenAI
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
client = OpenAI(
api_key=os.environ.get("SUBPOOL_API_KEY"),
base_url="https://subpool.net/v1",
)
base64_image = encode_image("screenshot-error.png")
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Read the error message in this screenshot and explain how to fix it:"},
{
"type": "image_url",
"image_url": {
"url": f"data:image/png;base64,{base64_image}"
},
},
],
}
],
max_tokens=800,
)
print(response.choices[0].message.content)
import fs from "fs";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.SUBPOOL_API_KEY,
baseURL: "https://subpool.net/v1",
});
const imageBase64 = fs.readFileSync("receipt.jpg").toString("base64");
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [
{
role: "user",
content: [
{ type: "text", text: "Extract the item list and total amount from this invoice as JSON:" },
{
type: "image_url",
image_url: {
url: `data:image/jpeg;base64,${imageBase64}`,
},
},
],
},
],
});
console.log(response.choices[0].message.content);
For Claude models, you can send images using Anthropic’s native source object format:
curl https://subpool.net/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $SUBPOOL_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-3-7-sonnet",
"max_tokens": 1500,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
}
},
{
"type": "text",
"text": "Describe this image and explain its key details."
}
]
}
]
}'
image/png), JPEG (image/jpeg), WEBP (image/webp) and GIF (image/gif).detail: "low" for quick image classification tasks that use only 85 fixed tokens. Use detail: "high" when you need to inspect small text or complex diagrams.SubPool returns standard HTTP status codes with detailed JSON error bodies to help developers debug and handle failures programmatically.
{
"error": {
"message": "Insufficient account balance to process this request. Please add funds.",
"type": "insufficient_quota",
"param": null,
"code": "balance_exhausted"
}
}
| HTTP status | Error | Cause & solution |
|---|---|---|
| 400 | Bad Request | Invalid JSON syntax or missing a required field (for example, model or messages). |
| 401 | Unauthorized | API key is invalid, disabled, or has an invalid Bearer header. Check the key on the API Keys page. |
| 402 | Payment Required | Your account balance is empty or too low for the estimated minimum charge. Add funds on the Top Up page. |
| 404 | Not Found | The model ID does not exist or is temporarily unavailable. Check the exact model ID on the pricing page. |
| 429 | Too Many Requests | Request rate limit exceeded (RPM/TPM). Use a retry strategy with exponential backoff. |
| 500 / 502 | Upstream Error | The upstream model provider returned an error. The system will retry through a backup route when available. |
Exponential Backoff & Jitter
For 429 or 503 errors, do not retry immediately. Increase the wait time between attempts (for example, 1s, 2s, 4s, and 8s with jitter) to avoid overloading the service.
Automatic balance monitoring
Handle 402 errors by notifying Slack/Telegram or setting a low-balance alert on the dashboard so your app is not interrupted.
Models
Compare supported models, capabilities, and specifications, then choose the right model for your workload.
Available models
—
Providers
—
Capability types
—
See the active catalog grouped by provider, with higher-priority models first.
Available models that support each capability.
Browse available models by provider, capabilities, and context size.
Transparent token-based pricing, supported capabilities (Thinking, Vision, Tools, Img2img), and specifications for 50+ frontier AI models.
Models
Browse available models by provider, capabilities, and context size.
| Model | Provider | Capabilities | Context window | Max output | |
|---|---|---|---|---|---|
| Loading model catalog… | |||||
Transparent token-based pricing, supported capabilities (Thinking, Vision, Tools, Img2img), and specifications for 50+ frontier AI models.
All prices are in USD per 1M tokens.
| Model | Provider | Input | Output | Cache write | Cache read |
|---|
Detailed guides to help you connect and use AI tools (Claude Code, Cursor, Codex CLI, OpenCode...) directly with our high-performance Gateway at undefined.
1. API Key
Create at Manage API Keys, format sk-xxxxxxxx. Shows only once — save immediately.
2. Base URL
Use exact /v1. Use the URL shown in each tool's example. SubPool also tolerates a duplicated /v1 prefix, but omitting it is recommended when the tool appends /v1 itself.
3. Model ID
Get exact ID (e.g. claude-sonnet-4-6) at Pricing page — click copy icon next to any model.
Terminal coding agent, Anthropic standard
Claude desktop app, configured via inference gateway
OpenAI coding agent, Responses API standard
The Codex tab built into OpenAI's official ChatGPT Desktop App
Open-source multi-provider terminal coding agent
AI-native IDE based on VS Code
VS Code extension coding agent
Continue
Autocomplete & chat extension for VS Code / JetBrains
TOML configured CLI, OpenAI standard
Terminal coding agent, Anthropic standard
This configuration works for both Claude Code CLI and Claude Code in Visual Studio Code. Install either the CLI (npm install -g @anthropic-ai/claude-code) or the Claude Code extension from the Visual Studio Code Marketplace. Node.js >= 18 is required either way.
npm install -g @anthropic-ai/claude-code
Step 1 — Open Terminal: press Cmd + Space, type Terminal, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
curl -fsSL /setup/claude-code/claude-code.sh | bash
Step 1 — Open PowerShell: press the Windows key, type powershell, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
irm /setup/claude-code/claude-code.ps1 | iex
The script asks for your SubPool API key, then lets you pick a model for each of the 4 roles Claude Code uses — FABLE, OPUS, SONNET, HAIKU (press Enter on any of them to use Model Switch, so you can change the model later from the website without rerunning the script). If a settings.json already exists, it is renamed to settings_backup_<timestamp>.json right next to it before the new one is written — nothing is ever deleted.
Claude Code reads ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN from the settings JSON file — writing them directly to settings.json is more reliable than exporting them temporarily in a shell. Use the URL exactly as shown below, ending in /v1.
{
"hasCompletedOnboarding": true,
"env": {
"ANTHROPIC_BASE_URL": "/v1",
"ANTHROPIC_AUTH_TOKEN": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx",
"ANTHROPIC_DEFAULT_FABLE_MODEL": "gpt-5-6-sol",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "gpt-5-6-terra",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt-5-6-terra",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "gpt-5-6-luna"
}
}
{
"hasCompletedOnboarding": true,
"env": {
"ANTHROPIC_BASE_URL": "/v1",
"ANTHROPIC_AUTH_TOKEN": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx",
"ANTHROPIC_DEFAULT_FABLE_MODEL": "gpt-5-6-sol",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "gpt-5-6-terra",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt-5-6-terra",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "gpt-5-6-luna"
}
}
Note
Claude Code only reads settings.json on startup — open a new session after editing. SubPool also tolerates a duplicated /v1 prefix if you accidentally add one, but the URL shown above (ending in /v1) is the recommended configuration.
Run claude in any folder and send a prompt. Response without 401 error confirms setup.
Claude desktop app, configured via inference gateway
On macOS there's nothing elaborate to do: on the app's opening screen (Get Started), just click Or sign in with Gateway.
This step is required on Windows for both paths in Step 3 below. A normal claude.ai sign-in does NOT create this config — it's a separate, hidden feature.
undefined for Gateway base URL, and enter any temporary value for API Key (it will be overwritten in Step 3 below), then click Apply Changes.Paste the single line below into a command window and press Enter. The script asks for your API key and model, then writes the config for you. You never have to find a hidden folder or edit JSON, and any existing file is backed up before it is replaced.
The script lists the Claude models active on your account for you to pick from (Model Switch and other providers' models don't work here).
Step 1 — Open Terminal: press Cmd + Space, type Terminal, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
curl -fsSL /setup/claude-app/claude-app.sh | bash
Step 1 — Open PowerShell: press the Windows key, type powershell, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
irm /setup/claude-app/claude-app.ps1 | iex
Note
Three things differ from the other tools here: (1) inferenceGatewayBaseUrl must be the bare domain, with NO trailing /v1 — the app appends /v1/messages and /v1/models itself, so adding /v1 makes it call /v1/v1/... and show "organization's model list hasn't loaded". (2) Every entry in inferenceModels[] must be a real Anthropic model id (like the models in the example below) — the Model Switch alias (switch-default) doesn't work here, showing "not an Anthropic model". (3) Add inferenceGatewayAuthScheme: "bearer" and modelDiscoveryEnabled: true as shown. Get the exact id of an active model on the pricing page.
~/Library/Application Support/Claude-3p/configLibrary/ and hit Enter. Find the <appliedId>.json file for the profile you use — with a single profile there is exactly one .json in there.sk-xxx... with your real API key.{
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "",
"inferenceGatewayApiKey": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx",
"inferenceGatewayAuthScheme": "bearer",
"modelDiscoveryEnabled": true,
"inferenceModels": [
{ "name": "claude-fable-5" },
{ "name": "claude-opus-5" },
{ "name": "claude-sonnet-5" },
{ "name": "claude-haiku-4-5-20251001" }
]
}
%APPDATA% and press Enter — Explorer opens at C:\Users\<your-name>\AppData\Roaming. Look for a folder whose name starts with "Claude" (e.g. Claude-3p), open it, then go into the configLibrary subfolder.Can't find the folder?
If Explorer says "Location is not available", or you see no Claude folder at all, open PowerShell (press Windows, type PowerShell, Enter) and paste the command below. It prints the exact path on your machine:
Get-ChildItem "$env:APPDATA","$env:LOCALAPPDATA" -Recurse -Directory -Filter configLibrary -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
If the command prints nothing, the folder was never created — go back to Step 2 above and complete all 5 Enable Developer Mode steps, then run the command again. This is not about forgetting to sign in.
<appliedId>.json files; if there are several, pick the one with the most recent Date modified. Right-click → Open with → Visual Studio Code (or Notepad++). Do not use Word or WordPad — they corrupt the file format.sk-xxx... with your real API key.{
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "",
"inferenceGatewayApiKey": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx",
"inferenceGatewayAuthScheme": "bearer",
"modelDiscoveryEnabled": true,
"inferenceModels": [
{ "name": "claude-fable-5" },
{ "name": "claude-opus-5" },
{ "name": "claude-sonnet-5" },
{ "name": "claude-haiku-4-5-20251001" }
]
}
Note
If configLibrary holds several .json files (several profiles), editing the wrong one has no effect. The reliable way: open _meta.json in the same folder — its appliedId field names the active profile's .json file. No _meta.json? Check each file's last modified time, or open the app first to see which profile is active before quitting to edit.
Reopen Claude. If it shows a sign-in screen, choose Continue with Gateway (do not sign in with a claude.ai account). If that screen shows “Your provider setup needs a fix”, your inferenceModels field is still wrong — see the note above. Once past that screen, start a new session and send a short prompt to confirm the gateway points at SubPool.
OpenAI coding agent, Responses API standard
Paste the single line below into a command window and press Enter. The script asks for your API key and model, then writes the config for you. You never have to find a hidden folder or edit JSON, and any existing file is backed up before it is replaced.
Step 1 — Open Terminal: press Cmd + Space, type Terminal, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
curl -fsSL /setup/codex/codex.sh | bash
Step 1 — Open PowerShell: press the Windows key, type powershell, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
irm /setup/codex/codex.ps1 | iex
Step 1 — create/edit ~/.codex/auth.json:
{
"auth_mode": "apikey",
"OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
Step 2 — create/edit ~/.codex/config.toml. The name field is required — Codex errors on startup without it. env_key and requires_openai_auth = false are also required — without them, a machine that has ever done `codex login` with a ChatGPT account gets a 401 missing API key error even with the right key:
model = "switch-default" model_provider = "subpool" [model_providers.subpool] name = "SubPool" base_url = "/v1" wire_api = "responses" env_key = "SUBPOOL_API_KEY" requires_openai_auth = false
Step 3 — set the SUBPOOL_API_KEY environment variable (Codex reads the key via env_key from step 2, not directly from auth.json, for a custom provider):
echo 'export SUBPOOL_API_KEY="sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"' >> ~/.zshrc launchctl setenv SUBPOOL_API_KEY "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
Step 4 — open a new Terminal window (to pick up the env var you just set), then restart Codex CLI completely.
Step 1 — create/edit %USERPROFILE%\.codex\auth.json:
{
"auth_mode": "apikey",
"OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
Step 2 — create/edit %USERPROFILE%\.codex\config.toml. env_key and requires_openai_auth = false are required — without them, a machine that has ever done `codex login` with a ChatGPT account gets a 401 missing API key error even with the right key:
model = "switch-default" model_provider = "subpool" [model_providers.subpool] name = "SubPool" base_url = "/v1" wire_api = "responses" env_key = "SUBPOOL_API_KEY" requires_openai_auth = false
Step 3 — set the SUBPOOL_API_KEY environment variable (run in PowerShell, no admin rights needed):
[Environment]::SetEnvironmentVariable('SUBPOOL_API_KEY', 'sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx', 'User')
Step 4 — open a new PowerShell window, then restart Codex CLI completely.
401 missing API key even with the right key
If this machine has ever done `codex login` with a ChatGPT account, Codex prefers that login state and won't attach Authorization to requests for a custom provider based on auth.json alone — even with the correct key entered. The surest fix is to log out before configuring: run codex logout. The Quick install script above already prompts for this and handles the config side (sets env_key plus the environment variable); doing it manually, make sure you have both the env_key/requires_openai_auth lines in config.toml AND the environment variable step above — missing either one still causes the error.
Codex CLI Specific Error
Error 'provider name must not be empty' means name = "SubPool" is missing under [model_providers.subpool].
Check the model after opening Codex
After configuring and opening Codex, if the model shown is Custom, that's correct — use it as-is. Do NOT switch to a different model from Codex's built-in list — switching makes Codex fall back to OpenAI's default provider (no longer going through SubPool), which won't work.
Open Codex, start a new chat session, and send a short message. A normal reply (no 401 or invalid api key error) confirms it's talking to SubPool.
The Codex tab built into OpenAI's official ChatGPT Desktop App
Note
Quit ChatGPT (Desktop App) completely before running the script — if it's still running, it can overwrite what you just wrote when you later quit it.
Paste the single line below into a command window and press Enter. The script asks for your API key and model, then writes the config for you. You never have to find a hidden folder or edit JSON, and any existing file is backed up before it is replaced.
Step 1 — Open Terminal: press Cmd + Space, type Terminal, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
curl -fsSL /setup/chatgpt-app/chatgpt-app.sh | bash
Step 1 — Open PowerShell: press the Windows key, type powershell, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
irm /setup/chatgpt-app/chatgpt-app.ps1 | iex
Step 1 — create/edit ~/.codex/auth.json:
{
"auth_mode": "apikey",
"OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
Step 2 — create/edit ~/.codex/config.toml (name field is required). env_key and requires_openai_auth = false are also required — without them, a machine that has ever done `codex login` with a ChatGPT account gets a 401 missing API key error even with the right key:
model = "switch-default" model_provider = "subpool" [model_providers.subpool] name = "SubPool" base_url = "/v1" wire_api = "responses" env_key = "SUBPOOL_API_KEY" requires_openai_auth = false
Step 3 — set the SUBPOOL_API_KEY environment variable for GUI apps (the app reads the key via env_key from step 2, not directly from auth.json, for a custom provider):
launchctl setenv SUBPOOL_API_KEY "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
Step 4 — quit ChatGPT (Desktop App) completely (not just the window), reopen it, and go to the Codex tab.
Step 1 — create/edit %USERPROFILE%\.codex\auth.json:
{
"auth_mode": "apikey",
"OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
Step 2 — create/edit %USERPROFILE%\.codex\config.toml. env_key and requires_openai_auth = false are required — without them, a machine that has ever done `codex login` with a ChatGPT account gets a 401 missing API key error even with the right key:
model = "switch-default" model_provider = "subpool" [model_providers.subpool] name = "SubPool" base_url = "/v1" wire_api = "responses" env_key = "SUBPOOL_API_KEY" requires_openai_auth = false
Step 3 — set the SUBPOOL_API_KEY environment variable (run in PowerShell, no admin rights needed):
[Environment]::SetEnvironmentVariable('SUBPOOL_API_KEY', 'sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx', 'User')
Step 4 — quit ChatGPT (Desktop App) completely and reopen it to apply the new config.
401 missing API key even with the right key
If this machine has ever done `codex login` with a ChatGPT account, the app prefers that login state and won't attach Authorization to requests for a custom provider based on auth.json alone — even with the correct key entered. The surest fix is to sign out before configuring: run codex logout (if Codex CLI is installed) or sign out directly in the app. The Quick install script above already prompts for this and handles the config side; doing it manually, make sure you have both the env_key/requires_openai_auth lines in config.toml AND the environment variable step above — missing either one still causes the error.
Why it shares config with Codex CLI
Per OpenAI's official docs (learn.chatgpt.com): the desktop app, CLI, and VS Code extension all use the same cached login mechanism and config file — editing it once applies to all three, no need to repeat this per tool.
Check the model after opening the Codex tab
After configuring and opening the Codex tab, if the model shown is Custom, that's correct — use it as-is. Do NOT switch to a different model from the built-in list — switching makes the app fall back to OpenAI's default provider (no longer going through SubPool), which won't work.
Open the Codex tab in ChatGPT (Desktop App), start a new session, and send a short message. A normal reply (no auth error) confirms it's talking to SubPool.
Open-source multi-provider terminal coding agent
Paste the single line below into a command window and press Enter. The script asks for your API key and model, then writes the config for you. You never have to find a hidden folder or edit JSON, and any existing file is backed up before it is replaced.
Step 1 — Open Terminal: press Cmd + Space, type Terminal, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
curl -fsSL /setup/opencode/opencode.sh | bash
Step 1 — Open PowerShell: press the Windows key, type powershell, press Enter.
Step 2 — In the window that just opened, paste the command below and press Enter:
irm /setup/opencode/opencode.ps1 | iex
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"subpool": {
"npm": "@ai-sdk/openai-compatible",
"name": "SubPool",
"options": {
"baseURL": "/v1",
"apiKey": "sk-xxxxxxxxxxxxxxxxxxxxxxx"
},
"models": {
"gpt-5-6-sol": {
"name": "GPT-5.6 Sol"
},
"gpt-5-6-terra": {
"name": "GPT-5.6 Terra"
},
"gpt-5-6-luna": {
"name": "GPT-5.6 Luna"
},
"claude-sonnet-5": {
"name": "Claude Sonnet 5"
},
"gemini-3-6-flash-high": {
"name": "Gemini 3.6 Flash High"
}
}
}
}
}
Run opencode models subpool or use /models in the TUI. If the provider is missing, check provider.subpool and the models section in opencode.json.
AI-native IDE based on VS Code
OpenAI Base URL: /v1 OpenAI API Key: sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx
Open chat panel, send a test prompt. Normal response confirms active connection.
Note
Cursor caches verified models — if you change Base URL or key, delete old model entries and re-add them.
VS Code extension coding agent
{
"actModeApiProvider": "openai",
"planModeApiProvider": "openai",
"openAiBaseUrl": "",
"openAiModelId": "switch-default",
"planModeOpenAiModelId": "switch-default"
}
{
"openAiApiKey": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
Send a prompt in Cline panel. Response with tool execution indicates success.
Note
openAiBaseUrl here must NOT include /v1 suffix — Cline appends it automatically.
Autocomplete & chat extension for VS Code / JetBrains
{
"models": [
{
"title": "SubPool",
"provider": "openai",
"model": "switch-default",
"apiBase": "/v1",
"apiKey": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
]
}
Send a chat prompt in Continue. Streaming response confirms success.
YAML + .env configured coding agent
model: default: "switch-default" provider: "custom" base_url: "/v1"
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx
Run Hermes Agent and send a prompt. No auth errors confirms connection.
Multi-agent framework configured via JSON
{
"agents": {
"defaults": {
"model": {
"primary": "subpool/custom"
}
}
},
"models": {
"providers": {
"subpool": {
"baseUrl": "/v1",
"apiKey": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx",
"apiType": "openai",
"models": [{ "id": "switch-default", "name": "switch-default" }]
}
}
}
}
Run default agent and verify subpool provider log activity.
Alibaba terminal coding agent, OpenAI standard
{
"security": {
"auth": {
"selectedType": "openai",
"openaiApiKey": "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx"
}
},
"model": {
"openaiBaseUrl": "/v1",
"name": "switch-default"
}
}
Run qwen and send a prompt. Normal response confirms connection.
TOML configured CLI, OpenAI standard
[providers.openai] base_url = "/v1" api_key = "sk-xxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxx" model = "switch-default"
Open new CLI session after saving configuration.
All tools listed above authenticate through the same SubPool gateway, so the errors below present identically whether you use Cursor, Codex, or any other tool. Read the error message to identify the root cause instantly.
| Error Message | HTTP Code | Root Cause | Fix / Solution |
|---|---|---|---|
| missing API key: provide Authorization: Bearer <key> or x-api-key: <key> | 401 | Request missing authentication header — key not configured or empty. | Check tool configuration file and paste key into correct field. |
| invalid api key | 401 | Key header present but not matching any active key — invalid or revoked key. | Create new key at Manage API Keys page and paste. |
| api key expired | 403 | Quota/prepaid key has expired. | Create new key or switch to pay-as-you-go credit key. |
| api key quota exhausted | 403 | Quota key token allowance exhausted. | Create new quota key or top up credit balance. |
| insufficient balance | 402 | Valid key but account balance insufficient for request. | Top up account balance at Topup page. |
Quick Error Isolation Tip
Before inspecting tool settings, make a direct curl call to the endpoint with your key. If curl succeeds but the tool fails, the issue is strictly inside local tool configuration, not your SubPool account.
Price
OpenAI & Anthropic
-
High speed / Native stream
-
-
-
Supports chain-of-thought extended reasoning, logic problems and complex code.
Image inputs, screenshot parsing, diagrams, and visual comprehension.
Function calling, structured outputs, and automated agent toolkits.
Low-latency real-time server-sent events for instant typing speed in IDEs.