Documentation

Build on every model through one OpenAI-compatible API.

Start with the SDKs you already use, route requests through One Interface, and manage keys, balances, usage, and model pricing from one Console.

Base URLhttps://api.oneinterface.ai/v1
AuthAuthorization: Bearer oi_...
CompatibilityOpenAI SDKs, cURL, server clients

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.

Python
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)
Node.js
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
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.

  1. Create a One Interface API key from Console.
  2. Open Cursor Settings (Cmd+, on Mac) → Models.
  3. Set Override OpenAI Base URL to https://api.oneinterface.ai/v1.
  4. Set OpenAI API Key to your oi_... key.
  5. Click Add Model and enter a model ID from /v1/models (e.g. gpt-4o).
  6. 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 — model provider fields
# 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.

  1. Create a One Interface API key from Console.
  2. Quick: export the two env vars below and run codex as normal.
  3. Persistent: add the TOML block to ~/.codex/config.toml — applies to every session.
Shell — quick env var setup (Codex)
# 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 provider config (Codex)
# ~/.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/models

Option 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.

  1. Create a One Interface API key from Console.
  2. Set ANTHROPIC_API_KEY to your oi_... key and ANTHROPIC_BASE_URL to https://api.oneinterface.ai.
  3. Launch Claude Code with --bare --model <model-id>. The --bare flag forces Claude Code to use your API key instead of its OAuth session — without it requests will fail with 401.
  4. For coding work, start with oi/balanced-coder. You can also choose any concrete model ID from /v1/models such as gpt-4o-mini.
oi/cheap-coderSmall fixes, tests, routine refactors
oi/balanced-coderEveryday feature work and debugging
oi/deep-reviewPR review, subtle bug analysis, harder reasoning
oi/long-contextLarge repos, logs, long design docs
Terminal — route Claude Code through a task-specific model
# --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.

  1. Create a One Interface API key from Console.
  2. Run the command below — registers the server globally across all your projects.
  3. Verify with claude mcp listoneinterface should show Connected.
  4. Ask Claude anything: “What models does OneInterface have?” or “Use oi/balanced-coder to summarise this file.”
Terminal — register MCP server (Claude Code)
# 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 list

Option 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.

  1. Create a One Interface API key from Console.
  2. Add the JSON block below to .cursor/mcp.json, replacing the placeholder key.
  3. Reload Cursor — the oneinterface server should appear as connected in Settings → MCP.
  4. Ask the Cursor agent anything that requires a model call or account lookup.
.cursor/mcp.json — MCP server config (Cursor)
// .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.

  1. Create a One Interface API key from Console.
  2. Add the TOML block below to ~/.codex/config.toml, replacing the placeholder key.
  3. Start Codex — it will connect automatically and expose all nine tools to the agent.
~/.codex/config.toml — MCP server config (Codex CLI)
# ~/.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.

Header
Authorization: Bearer oi_your_api_key
Content-Type: application/json

04 API Reference

Supported endpoints

These routes are implemented by the API service today and proxy to configured upstream providers in priority order.

POST/v1/chat/completions

Chat completions

OpenAI-compatible chat endpoint for conversational and instruction-following models.

modelmessagestemperaturemax_tokensstreamtools
POST/v1/responses

Responses

Forward-compatible endpoint for newer OpenAI-style response payloads.

modelinputinstructionsstreamtoolsmetadata
GET/v1/models

Models

Returns the curated public model catalog backed by configured model prices.

idobjectcreatedowned_bypricing
POST/v1/embeddings

Embeddings

OpenAI-compatible embedding endpoint for retrieval, clustering, and search workflows.

modelinputencoding_formatdimensions

05 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)
Use a profile like any model
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.

Streaming request
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.

Python — agent with own tools (OpenAI SDK)
# 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.

Python — agent with shared registry (OpenAI SDK)
# 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.

Python — Claude-based agent (Anthropic SDK)
# 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".

Tool call response shape
// 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 response
{
  "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.

View models