01 Quick Start
Your first request
The public API is designed to accept familiar OpenAI-shaped requests while handling provider routing, usage tracking, and prepaid billing behind the scenes.
Create an API key
Sign in to Console, open API Keys, and create a key. Keys use the One Interface prefix and are only shown once.
Choose a priced model
Use the Models page or /v1/models endpoint. Production calls are limited to curated models with configured prices.
Send an OpenAI-compatible request
Point your existing OpenAI SDK at the One Interface base URL and keep the rest of your app mostly unchanged.
from openai import OpenAI
client = OpenAI(
base_url="https://api.oneinterface.ai/v1",
api_key="oi_your_api_key",
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Write a one-line haiku about APIs."}],
)
print(response.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.oneinterface.ai/v1",
apiKey: process.env.ONEINTERFACE_API_KEY,
});
const response = await client.chat.completions.create({
model: "claude-sonnet-4-6",
messages: [{ role: "user", content: "Summarize this pull request." }],
});
console.log(response.choices[0].message.content);curl https://api.oneinterface.ai/v1/chat/completions \
-H "Authorization: Bearer oi_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{ "role": "user", "content": "Hello from One Interface" }
]
}'02 Integrations
Use One Interface inside Cursor, Claude Code, and Codex
Start here if you want your coding tools to call One Interface directly. Cursor and Codex use OpenAI-compatible settings; Claude Code can route its own model calls through the native Anthropic proxy or connect to the MCP server for direct account tools.
Most coding-tool setups start here
Use a model provider setup when you want the tool's own model calls billed through One Interface. Use MCP when you want the agent to query One Interface tools such as list_models, get_balance, and chat_completion.
Cursor
OpenAI-compatible provider (Option A) or native MCP server via .cursor/mcp.json (Option D) — gives the Cursor agent direct access to all nine One Interface tools.
Claude Code
Native Anthropic API proxy via ANTHROPIC_BASE_URL for Claude Code's own model calls, including task-specific models like oi/balanced-coder, plus native MCP tools for account access.
Codex
OpenAI-compatible provider (Option A) or native MCP server via ~/.codex/config.toml (Option E) — gives the Codex agent direct access to all nine One Interface tools.
Option A — Cursor model provider (Settings UI)
Open Settings → Models and set the Override OpenAI Base URL and API key fields. No CLI flags or config files needed.
- Create a One Interface API key from Console.
- Open Cursor Settings (Cmd+, on Mac) → Models.
- Set Override OpenAI Base URL to
https://api.oneinterface.ai/v1. - Set OpenAI API Key to your
oi_...key. - Click Add Model and enter a model ID from
/v1/models(e.g.gpt-4o). - Select the model in the chat panel (Cmd+L). It will route through One Interface.
Only the chat/plan panel (Cmd+L) uses this endpoint. Composer, inline edits, and autocomplete remain on Cursor's backend.
# Cursor Settings → Models → add these fields:
#
# Override OpenAI Base URL: https://api.oneinterface.ai/v1
# OpenAI API Key: oi_your_api_key
# Add Model: gpt-4o (or any ID from /v1/models)
#
# ⚠ Only the chat/plan panel (Cmd+L / Ctrl+L) sends requests to this endpoint.
# Composer, inline edits, and autocomplete stay on Cursor's proprietary backend.Option B — Codex model provider (env vars or config file)
Codex reads OPENAI_BASE_URL and OPENAI_API_KEY automatically — no flags needed. For a persistent setup, define a named provider in ~/.codex/config.toml.
- Create a One Interface API key from Console.
- Quick: export the two env vars below and run
codexas normal. - Persistent: add the TOML block to
~/.codex/config.toml— applies to every session.
# Quickest option — set two env vars and run Codex as normal.
# No flags, no config file changes needed.
export OPENAI_BASE_URL="https://api.oneinterface.ai/v1"
export OPENAI_API_KEY="oi_your_api_key"
codex "refactor this function to use async/await"# ~/.codex/config.toml (persistent — applies to every Codex session)
# Define One Interface as a named provider, then set it as default.
[model_providers.oneinterface]
name = "One Interface"
base_url = "https://api.oneinterface.ai/v1"
env_key = "OI_API_KEY" # export OI_API_KEY=oi_your_api_key
wire_api = "chat" # OpenAI-compatible chat completions
[model]
provider = "oneinterface"
name = "gpt-4o" # any model ID from /v1/modelsOption C — Anthropic API proxy (Claude Code only)
One Interface exposes a /v1/messages endpoint that accepts the native Anthropic Messages API format and translates it to your configured upstream providers. Setting ANTHROPIC_BASE_URL routes Claude Code's own model calls — including tool use and streaming — through One Interface, billed to your account.
- Create a One Interface API key from Console.
- Set
ANTHROPIC_API_KEYto youroi_...key andANTHROPIC_BASE_URLtohttps://api.oneinterface.ai. - Launch Claude Code with
--bare --model <model-id>. The--bareflag forces Claude Code to use your API key instead of its OAuth session — without it requests will fail with 401. - For coding work, start with
oi/balanced-coder. You can also choose any concrete model ID from/v1/modelssuch asgpt-4o-mini.
oi/cheap-coderSmall fixes, tests, routine refactorsoi/balanced-coderEveryday feature work and debuggingoi/deep-reviewPR review, subtle bug analysis, harder reasoningoi/long-contextLarge repos, logs, long design docs# --bare forces Claude Code to use ANTHROPIC_API_KEY instead of its OAuth session.
# Without --bare the OAuth token is sent to One Interface and rejected (401).
ANTHROPIC_API_KEY=oi_your_api_key \
ANTHROPIC_BASE_URL=https://api.oneinterface.ai \
claude --bare --model oi/balanced-coder
# Recommended: add an alias to ~/.zshrc so you just type "claude-oi"
alias claude-oi='ANTHROPIC_API_KEY=oi_your_api_key ANTHROPIC_BASE_URL=https://api.oneinterface.ai claude --bare --model oi/balanced-coder'Option D — Native MCP server (Claude Code)
The MCP server runs at https://api.oneinterface.ai/mcp and exposes nine tools: chat_completion, get_balance, list_models, list_api_keys, create_api_key, revoke_api_key, get_usage, web_fetch, and http_request.
- Create a One Interface API key from Console.
- Run the command below — registers the server globally across all your projects.
- Verify with
claude mcp list— oneinterface should show Connected. - Ask Claude anything: “What models does OneInterface have?” or “Use oi/balanced-coder to summarise this file.”
# Run once in your terminal — registers the server for all your projects
claude mcp add --transport http -s user oneinterface https://api.oneinterface.ai/mcp \
-H "Authorization: Bearer oi_your_api_key"
# Verify the connection
claude mcp listOption E — Native MCP server (Cursor)
Cursor supports Streamable HTTP MCP servers natively. Add the config below to .cursor/mcp.json in your project root (or to the global Cursor MCP config via Settings → MCP → Edit config). Cursor will discover all nine One Interface tools automatically.
- Create a One Interface API key from Console.
- Add the JSON block below to
.cursor/mcp.json, replacing the placeholder key. - Reload Cursor — the oneinterface server should appear as connected in Settings → MCP.
- Ask the Cursor agent anything that requires a model call or account lookup.
// .cursor/mcp.json (project-level)
// or add to Cursor Settings → MCP → Edit config
{
"mcpServers": {
"oneinterface": {
"url": "https://api.oneinterface.ai/mcp",
"headers": {
"Authorization": "Bearer oi_your_api_key"
}
}
}
}Option F — Native MCP server (Codex CLI)
Codex CLI supports Streamable HTTP MCP servers via ~/.codex/config.toml. Add the block below and Codex will connect to the One Interface MCP server on startup. Bearer tokens are passed as static headers — no OAuth flow required.
- Create a One Interface API key from Console.
- Add the TOML block below to
~/.codex/config.toml, replacing the placeholder key. - Start Codex — it will connect automatically and expose all nine tools to the agent.
# ~/.codex/config.toml
# Codex picks this up automatically on startup.
[mcp_servers.oneinterface]
type = "http"
url = "https://api.oneinterface.ai/mcp"
[mcp_servers.oneinterface.headers]
Authorization = "Bearer oi_your_api_key"03 Authentication
Use a One Interface API key
Every API request must include a bearer token created in Console. The API validates hashed keys server-side and never needs your upstream provider credentials.
Keep keys server-side
Do not expose API keys in browser code. Create requests from your backend, edge function, or another trusted environment.
Authorization: Bearer oi_your_api_key
Content-Type: application/json04 API Reference
Supported endpoints
These routes are implemented by the API service today and proxy to configured upstream providers in priority order.
/v1/chat/completionsChat completions
OpenAI-compatible chat endpoint for conversational and instruction-following models.
modelmessagestemperaturemax_tokensstreamtools/v1/responsesResponses
Forward-compatible endpoint for newer OpenAI-style response payloads.
modelinputinstructionsstreamtoolsmetadata/v1/modelsModels
Returns the curated public model catalog backed by configured model prices.
idobjectcreatedowned_bypricing/v1/embeddingsEmbeddings
OpenAI-compatible embedding endpoint for retrieval, clustering, and search workflows.
modelinputencoding_formatdimensions05 Routing profiles
Pick a task, not a model
Task routing profiles are virtual model IDs (prefixed oi/) that you put in the model field instead of a specific model. One Interface routes to a high cost-performance model commonly preferred for that task, with transparent fallback if the primary is unavailable. They work anywhere a model ID is accepted — no new parameter and no client changes — and appear in GET /v1/models with type: "routing_profile".
oi/chat-fastChat — high-volume, latency-sensitive turns (lowest cost)oi/chatChat — Q&A, drafting, summarization (balanced)oi/chat-smartChat — complex reasoning and nuanced writing (premium)oi/cheap-coderCoding — small fixes, tests, routine refactors (lowest cost)oi/balanced-coderCoding — feature work and debugging (balanced)oi/deep-reviewCoding — PR review and subtle bug analysis (premium)oi/long-contextCoding — large repos, logs, long design docs (long context)oi/agent-fastAgent — high-volume tool loops and background agents (lowest cost)oi/agentAgent — tool use, planning, multi-step execution (balanced)oi/agent-maxAgent — complex multi-step reasoning and orchestration (premium)curl https://api.oneinterface.ai/v1/chat/completions \
-H "Authorization: Bearer oi_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"model": "oi/chat",
"messages": [
{ "role": "user", "content": "Summarize this thread in three bullets." }
]
}'Image, video, and audio tasks are on the roadmap. They require dedicated endpoints and non-chat upstream contracts, so they are not yet available as routing profiles.
06 Streaming
Stream chat responses with SSE
Set stream to true on compatible endpoints. One Interface preserves event-stream responses and requests usage data when streaming so billing can be recorded accurately.
await client.chat.completions.create({
model: "gpt-4o",
stream: true,
messages: [{ role: "user", content: "Think step by step." }],
});07 Agents
Agents and tool use
Agents can use tools in two ways: pass schemas directly in the request (no setup needed), or register schemas in the One Interface registry and share them across all agents on the account. Either way, your agent executes the tool itself — One Interface is never in the execution path.
Option A — bring your own tools (no setup)
Pass tools: [...] directly in the request body, exactly as you would with the OpenAI or Anthropic API. One Interface forwards it unchanged. No registration required — works out of the box for any agent that already defines its own tool schemas.
# Option A — bring your own tools.
# Pass tools: [...] directly. No registry needed.
# Works exactly like the OpenAI API — One Interface forwards it unchanged.
from openai import OpenAI
import json
client = OpenAI(
base_url="https://api.oneinterface.ai/v1",
api_key="oi_your_api_key",
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
]
messages = [{"role": "user", "content": "What is the weather in Tokyo?"}]
response = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
choice = response.choices[0]
while choice.finish_reason == "tool_calls":
messages.append(choice.message)
for call in choice.message.tool_calls:
result = my_tools[call.function.name](**json.loads(call.function.arguments))
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
response = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
choice = response.choices[0]
print(choice.message.content)Option B — shared tool registry
Register a tool schema once with POST /v1/tools. Any agent on the account can then add "custom_tools": true to a chat request and One Interface injects all registered schemas before forwarding to the LLM. Useful when multiple agents need the same tools without each one defining them locally.
# Option B — shared tool registry.
# Register a tool schema once; any agent on the account can use it via custom_tools: true.
# One Interface injects the schemas before forwarding — your agent still executes the tool itself.
from openai import OpenAI
import json
client = OpenAI(
base_url="https://api.oneinterface.ai/v1",
api_key="oi_your_api_key",
)
messages = [{"role": "user", "content": "Search for the latest AI news"}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
extra_body={"custom_tools": True}, # injects all schemas registered under your account
)
choice = response.choices[0]
while choice.finish_reason == "tool_calls":
messages.append(choice.message)
for call in choice.message.tool_calls:
result = my_tools[call.function.name](**json.loads(call.function.arguments))
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
response = client.chat.completions.create(
model="gpt-4o", messages=messages, extra_body={"custom_tools": True}
)
choice = response.choices[0]
print(choice.message.content)Claude-based agents (Anthropic SDK)
Both options work with the Anthropic SDK too. Point base_url at the root of One Interface (not /v1). The /v1/messages endpoint accepts native Anthropic format — tool use blocks, content arrays, streaming SSE events — and translates to your configured upstream.
# Claude-based agents using the Anthropic SDK.
# custom_tools works the same way — One Interface injects registered schemas,
# your agent executes the tool directly when the model requests it.
import anthropic
import json
client = anthropic.Anthropic(
api_key="oi_your_api_key",
base_url="https://api.oneinterface.ai", # note: root URL, not /v1
)
messages = [{"role": "user", "content": "Search for the latest AI news"}]
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages,
extra_headers={"x-custom-tools": "true"}, # or pass via bespoke_parameters
)
# stop_reason == "tool_use" when the model wants to call a tool
while response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
# Execute the tool yourself — One Interface is not in the execution path
result = my_tools[block.name](**block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result),
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages,
)
print(response.content[0].text)Tool call response shape
When finish_reason is "tool_calls", read choices[0].message.tool_calls, execute the named function with the provided arguments, and append the result as a tool role message before the next LLM call. Repeat until finish_reason is "stop".
// finish_reason tells your agent what to do next:
// "stop" → final answer, read choices[0].message.content
// "tool_calls" → execute the requested tool, append the result, loop
{
"choices": [{
"finish_reason": "tool_calls",
"message": {
"role": "assistant",
"tool_calls": [{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"Tokyo\"}"
}
}]
}
}]
}08 Errors
Stable error shape
Customer-facing errors use a consistent JSON envelope. Raw upstream provider error bodies are not returned to clients.
{
"error": {
"message": "The requested model is not available.",
"type": "oneinterface_error",
"code": "model_not_available"
}
}invalid_api_keyThe bearer token is missing, revoked, or invalid.insufficient_creditThe account balance is too low for a billable request.model_not_availableThe requested model is not in the curated priced catalog.invalid_requestThe body or parameters are malformed.rate_limit_exceededRetry after a short delay.upstream_unavailableAll configured upstream providers are temporarily unavailable.internal_errorUnexpected One Interface service error.09 Console
Keys, usage, and prepaid billing
Console endpoints use Supabase user sessions, while API traffic uses One Interface API keys. Usage events track endpoint, model, token counts, status, billing status, and cost.
Prepaid balance
Billable requests require a positive account balance. Stripe Checkout top-ups are supported.
Provider routing
The API tries configured upstreams in priority order and records the selected provider internally.
Curated pricing
Models must exist in the model price table unless unpriced models are explicitly allowed.
10 Deployment
Operational references
The repository also includes deeper setup documents for local development, backend deployment, environment variables, and product gaps.
Need a model catalog?
Browse public model availability and pricing, then call the selected model ID from any OpenAI-compatible SDK.