Skip to content

OpenAI Compatible Protocol

The OpenAI compatible protocol is the most widely supported AI API standard in the industry. RouteAPI fully implements the OpenAI API specification, allowing you to seamlessly integrate with existing OpenAI SDKs, tools, and clients by simply switching the Base URL and API Key.

The OpenAI API defines a standardized set of REST interfaces for conversation generation, text embeddings, model listing, and other capabilities. Its core advantage lies in its mature ecosystem: OpenAI official SDKs, LangChain, LiteLLM, Cursor, and various coding assistants natively support this protocol.

RouteAPI compatibility scope:

  • Fully compatible with OpenAI Chat Completions, Responses, Embeddings, and Models endpoints
  • Consistent authentication using Authorization: Bearer request headers
  • Consistent request/response formats, including streaming SSE and error structures
  • Broader model ID range, can call OpenAI, Claude, Gemini, Mistral, and other providers
  • Explicit zero-value parameters preserved, explicitly passed 0 / false are not dropped

Migrating from the official OpenAI API to RouteAPI requires only two configuration changes:

from openai import OpenAI
client = OpenAI(
api_key="sk-your-routeapi-token", # Switch to RouteAPI Token
base_url="https://api.routeapi.ai/v1" # Switch to RouteAPI Base URL
)

All other code remains unchanged.

https://api.routeapi.ai/v1

All OpenAI compatible endpoints use this base URL. If your client or SDK requires the full URL, simply append the endpoint path, e.g., https://api.routeapi.ai/v1/chat/completions.

Identical to the official OpenAI API, using the HTTP Authorization request header:

Authorization: Bearer sk-your-routeapi-token
Content-Type: application/json

RouteAPI Tokens start with sk- and are generated on the API Keys page in the console. Store tokens on the server side and do not expose them in browsers, mobile apps, or public repositories.

EndpointPurposeDetailed Documentation
/v1/chat/completionsConversation generation, supports multi-turn dialogue, tool calling, structured outputChat Completions
/v1/responsesOpenAI Responses protocol, suitable for coding agents and next-generation application frameworksResponses
/v1/embeddingsText vector embeddings for semantic search, RAG, similarity calculationEmbeddings
/v1/modelsGet the list of models available to the current accountBelow on this page
ScenarioRecommended EndpointReason
General chat, Q&A, summarization, classification/v1/chat/completionsMost mature ecosystem, broadest compatibility
Coding agents (Cursor, Claude Code, Copilot)/v1/responses or /v1/chat/completionsDepends on the protocol natively supported by the client
Multi-turn dialogue, conversation history/v1/chat/completionsmessages array naturally supports multiple rounds
Tool calling, function calling/v1/chat/completionsMost standard tool definition and result passing structure
Semantic search, RAG, document retrieval/v1/embeddingsReturns vector representations
Structured output, JSON Schema/v1/chat/completions or /v1/responsesControlled via response_format parameter

The specific endpoint choice should prioritize the client and SDK’s native support. If the client explicitly requires a certain protocol, follow the client’s requirements.

Installation:

Terminal window
pip install openai

Configure RouteAPI:

import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ROUTEAPI_KEY"],
base_url="https://api.routeapi.ai/v1"
)
response = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "user", "content": "Please introduce RouteAPI in one sentence"}
]
)
print(response.choices[0].message.content)

Only the api_key and base_url parameters need to be set; all other code is identical to the official API.

Installation:

Terminal window
npm install openai

Configure RouteAPI:

import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.ROUTEAPI_KEY,
baseURL: 'https://api.routeapi.ai/v1'
});
const response = await client.chat.completions.create({
model: 'gpt-5.5',
messages: [
{ role: 'user', content: 'Please introduce RouteAPI in one sentence' }
]
});
console.log(response.choices[0].message.content);

LangChain’s ChatOpenAI class supports custom base_url:

from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-5.5",
openai_api_key=os.environ["ROUTEAPI_KEY"],
openai_api_base="https://api.routeapi.ai/v1"
)
response = llm.invoke("Please introduce RouteAPI in one sentence")
print(response.content)

LiteLLM’s completion() function supports custom api_base:

import litellm
response = litellm.completion(
model="gpt-5.5",
messages=[{"role": "user", "content": "Please introduce RouteAPI in one sentence"}],
api_key=os.environ["ROUTEAPI_KEY"],
api_base="https://api.routeapi.ai/v1"
)
print(response.choices[0].message.content)

Any client, tool, or framework that supports the OpenAI API can integrate with RouteAPI through the following configuration:

  1. API Key set to RouteAPI Token (starts with sk-)
  2. Base URL set to https://api.routeapi.ai/v1
  3. Model ID use model names supported by RouteAPI (query via /v1/models)

The main endpoints of the OpenAI compatible protocol share a core set of parameters. Below is a quick reference table for common parameters; detailed explanations are in each endpoint’s dedicated documentation.

ParameterTypeRequiredDescription
modelstringYesModel ID, must be available to the current account
messagesarrayYesConversation message list, each message contains role and content
streambooleanNoWhether to use SSE streaming output, default false
temperaturenumberNoSampling temperature, range 0 to 2, default 1
top_pnumberNoNucleus sampling parameter, range 0 to 1
max_tokensnumberNoMaximum output tokens (legacy parameter name, still required by some models)
max_completion_tokensnumberNoMaximum output tokens (new parameter name)
toolsarrayNoTool definition list for function calling
tool_choicestring/objectNoTool selection strategy (auto / required / none / specific tool)
response_formatobjectNoOutput format constraint (JSON mode / JSON Schema)
stream_optionsobjectNoAdditional streaming options, such as include_usage
stopstring/arrayNoCustom stop sequences
presence_penaltynumberNoPresence penalty, range -2 to 2
frequency_penaltynumberNoFrequency penalty, range -2 to 2
userstringNoEnd user identifier for abuse detection

For detailed explanations and more parameters, refer to the Chat Completions documentation.

ParameterTypeRequiredDescription
modelstringYesEmbedding model ID
inputstring/arrayYesText to embed, supports single string or string array
encoding_formatstringNoReturn format, float (default) or base64
dimensionsnumberNoOutput vector dimensions, depends on model support
userstringNoEnd user identifier

For detailed explanations, refer to the Embeddings documentation.

Chat Completions standard response example:

{
"id": "chatcmpl_xxx",
"object": "chat.completion",
"created": 1730000000,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "RouteAPI is an API gateway that unifies access to multiple AI model providers."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 18,
"total_tokens": 42
}
}

Key fields:

  • choices[0].message.content — Model’s text response
  • choices[0].finish_reason — Completion reason (stop / length / tool_calls / content_filter)
  • usage — Token usage statistics

Setting stream: true returns Server-Sent Events (SSE) format incremental data:

data: {"id":"chatcmpl_xxx","object":"chat.completion.chunk","created":1730000000,"model":"gpt-5.5","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl_xxx","object":"chat.completion.chunk","created":1730000000,"model":"gpt-5.5","choices":[{"index":0,"delta":{"content":"RouteAPI"},"finish_reason":null}]}
data: {"id":"chatcmpl_xxx","object":"chat.completion.chunk","created":1730000000,"model":"gpt-5.5","choices":[{"index":0,"delta":{"content":" is"},"finish_reason":null}]}
data: {"id":"chatcmpl_xxx","object":"chat.completion.chunk","created":1730000000,"model":"gpt-5.5","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":24,"completion_tokens":18,"total_tokens":42}}
data: [DONE]

Streaming response characteristics:

  • Each line starts with data: followed by a JSON object
  • Incremental content is in choices[0].delta.content
  • When complete, finish_reason is not null
  • The last line is data: [DONE]

If you need token usage statistics in streaming mode, set stream_options: { "include_usage": true }, and usage information will be returned in the last data chunk.

Error responses follow OpenAI’s standard format:

{
"error": {
"message": "Invalid API key provided",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}

Common error types:

HTTP Status CodetypeDescription
401invalid_request_errorInvalid or missing API Key
429rate_limit_errorRate limit exceeded
500api_errorInternal server error
503overloaded_errorService overloaded

For detailed error handling, refer to the Error Handling documentation.

RouteAPI’s OpenAI compatible protocol is fully compatible at the protocol level, but has some differences in model capabilities, billing, and rate limiting:

The official OpenAI API can only call OpenAI’s own models (gpt-4o, gpt-5.5, etc.). RouteAPI supports models from multiple providers:

  • OpenAI: gpt-4o, gpt-5.5, o3-mini, etc.
  • Anthropic Claude: claude-sonnet-4-5, claude-opus-4, etc.
  • Google Gemini: gemini-2.0-flash, gemini-2.5-pro, etc.
  • Mistral: mistral-large, mistral-small, etc.
  • Others: DeepSeek, Qwen, LLaMA, etc.

Query the complete list of models available to the current account via the /v1/models endpoint.

Billing and Rate Limiting Managed by RouteAPI

Section titled “Billing and Rate Limiting Managed by RouteAPI”
  • Billing: Charged according to RouteAPI’s rate card, which may differ from upstream providers’ official pricing
  • Rate limiting: Controlled by RouteAPI’s rate limit policies, not upstream providers’ limits
  • Quotas: Account balance and quotas are managed by RouteAPI, recharge and view in the console

Parameter Support Depends on Underlying Model

Section titled “Parameter Support Depends on Underlying Model”

The OpenAI compatible protocol defines a complete set of parameters, but actual support depends on the selected model:

CapabilityDescription
Tool calling (tools)Depends on whether the model supports function calling
Structured output (response_format)Depends on whether the model supports JSON mode or JSON Schema
Visual input (image_url)Depends on whether the model supports multimodal input
Streaming usage (stream_options.include_usage)Depends on whether the model and channel support streaming usage statistics
Reasoning control (reasoning_effort)Only supported by some reasoning models

It’s recommended to validate the selected model’s support for key parameters in a test environment before enabling in production.

This is a subtle but important difference. In the OpenAI compatible protocol, if optional parameters are explicitly passed as 0, 0.0, or false, RouteAPI treats them as the user’s explicit setting rather than dropping them as default values.

For example:

{
"model": "gpt-5.5",
"messages": [...],
"temperature": 0,
"top_p": 1.0
}

Here, temperature: 0 will be preserved and forwarded to the upstream model, rather than being treated as unset because “the value is 0”. This ensures clients can precisely control sampling parameters.

If you don’t want to pass a certain parameter, simply remove that field from the request; don’t pass null or 0.

The OpenAI compatible protocol is a standard interface definition, but specific capabilities depend on the underlying model:

  • Tool calling: Requires the model to support function calling, and tool definition format to match model requirements
  • Structured output: Requires the model to support JSON mode or JSON Schema
  • Visual input: Requires the model to support image or multimodal input
  • Streaming usage: Requires the model and channel to support returning token usage in streaming mode

If the request includes parameters the model doesn’t support, behavior depends on the parameter type:

  • Ignorable parameters (such as frequency_penalty) will be silently ignored
  • Critical parameters (such as tools) may trigger errors

In production, it’s recommended to fix model IDs and prepare fallback strategies for critical business flows.

RouteAPI performs basic validation on request parameters, such as:

  • Missing required parameters (such as model, messages)
  • Incorrect parameter types (such as passing a string for temperature)
  • Parameter values out of range (such as temperature: 3)

When validation fails, it returns 400 Bad Request with detailed error information. If the request passes RouteAPI’s validation but is rejected by the upstream model, it returns 500 or 502 along with the upstream’s original error message.

When switching from one model to another, even if both use the OpenAI compatible protocol, the following points need attention:

  1. Context length: Different models have different maximum context lengths; excessively long requests may be rejected
  2. Tool calling format: Some models have stricter requirements for tool description formats
  3. Output style: The same prompt may produce different output styles, lengths, and formats across different models
  4. Token counting: Different models have different tokenizers; the same text may have different token counts
  5. Billing price: Different models have different unit prices; switching models may affect costs

It’s recommended to validate the complete workflow in a test environment before switching models in production.

The /v1/models endpoint returns a list of models available to the current account, in a format consistent with the official OpenAI API.

Terminal window
curl https://api.routeapi.ai/v1/models \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{
"success": true,
"object": "list",
"data": [
{
"id": "gpt-5.5",
"object": "model",
"created": 1626777600,
"owned_by": "openai",
"supported_endpoint_types": ["openai", "openai-response"]
},
{
"id": "claude-sonnet-4-5",
"object": "model",
"created": 1626777600,
"owned_by": "anthropic",
"supported_endpoint_types": ["openai", "anthropic"]
}
]
}

The returned data array contains the models available to the current Token, not the platform’s full catalog. Each model object includes:

  • id — Model ID, use this value when making requests
  • object — Fixed as "model"
  • owned_by — The channel type the model belongs to; custom for platform-custom models
  • supported_endpoint_types — RouteAPI extension field, the endpoint types this model can be used with
  • created — A fixed placeholder value 1626777600, not a real listing time; do not use it for sorting

The extra top-level success field is a RouteAPI extension. OpenAI SDKs only read data, so it does not affect parsing. The ordering of data is not guaranteed to be stable.

It’s recommended to call /v1/models once when the application starts, cache the available model list, and avoid querying on every request. For field meanings and filtering rules, see Models.

Terminal window
curl https://api.routeapi.ai/v1/chat/completions \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [
{
"role": "system",
"content": "You are a rigorous technical assistant. Keep answers concise."
},
{
"role": "user",
"content": "Please introduce RouteAPI in one sentence"
}
],
"temperature": 0.7
}'
import os
from openai import OpenAI
# Initialize client
client = OpenAI(
api_key=os.environ["ROUTEAPI_KEY"],
base_url="https://api.routeapi.ai/v1"
)
# Basic conversation
def basic_chat():
response = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "system", "content": "You are a rigorous technical assistant."},
{"role": "user", "content": "Please introduce RouteAPI in one sentence"}
],
temperature=0.7
)
print(response.choices[0].message.content)
print(f"Usage: {response.usage.total_tokens} tokens")
# Streaming conversation
def streaming_chat():
stream = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "user", "content": "Explain step by step what an API gateway is"}
],
stream=True,
stream_options={"include_usage": True}
)
for chunk in stream:
if chunk.choices:
delta = chunk.choices[0].delta
if delta.content:
print(delta.content, end="", flush=True)
# Last chunk contains usage
if hasattr(chunk, 'usage') and chunk.usage:
print(f"\nUsage: {chunk.usage.total_tokens} tokens")
# Tool calling
def tool_calling():
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Query the current weather for a specified city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, e.g., Beijing"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
}
}
}
]
messages = [{"role": "user", "content": "What's the weather like in Beijing right now?"}]
# First round: model requests tool call
response = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
tools=tools,
tool_choice="auto"
)
# Check for tool calls
if response.choices[0].message.tool_calls:
# Simulate tool execution
tool_call = response.choices[0].message.tool_calls[0]
tool_result = "Beijing, sunny, temperature 23 Celsius, humidity 45%."
# Construct second round request
messages.append(response.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": tool_result
})
# Second round: model generates response based on tool result
final_response = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
tools=tools
)
print(final_response.choices[0].message.content)
# Structured output
def structured_output():
response = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "user", "content": "Extract key information from the following text: RouteAPI is an AI API gateway supporting OpenAI, Claude, Gemini and other models."}
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "key_info",
"strict": True,
"schema": {
"type": "object",
"properties": {
"product_name": {"type": "string"},
"category": {"type": "string"},
"supported_models": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["product_name", "category", "supported_models"],
"additionalProperties": False
}
}
}
)
print(response.choices[0].message.content)
if __name__ == "__main__":
basic_chat()
print("\n" + "="*50 + "\n")
streaming_chat()
print("\n" + "="*50 + "\n")
tool_calling()
print("\n" + "="*50 + "\n")
structured_output()
import OpenAI from 'openai';
// Initialize client
const client = new OpenAI({
apiKey: process.env.ROUTEAPI_KEY,
baseURL: 'https://api.routeapi.ai/v1'
});
// Basic conversation
async function basicChat() {
const response = await client.chat.completions.create({
model: 'gpt-5.5',
messages: [
{ role: 'system', content: 'You are a rigorous technical assistant.' },
{ role: 'user', content: 'Please introduce RouteAPI in one sentence' }
],
temperature: 0.7
});
console.log(response.choices[0].message.content);
console.log(`Usage: ${response.usage.total_tokens} tokens`);
}
// Streaming conversation
async function streamingChat() {
const stream = await client.chat.completions.create({
model: 'gpt-5.5',
messages: [
{ role: 'user', content: 'Explain step by step what an API gateway is' }
],
stream: true,
stream_options: { include_usage: true }
});
for await (const chunk of stream) {
if (chunk.choices[0]?.delta?.content) {
process.stdout.write(chunk.choices[0].delta.content);
}
if (chunk.usage) {
console.log(`\nUsage: ${chunk.usage.total_tokens} tokens`);
}
}
}
// Tool calling
async function toolCalling() {
const tools = [
{
type: 'function',
function: {
name: 'get_weather',
description: 'Query the current weather for a specified city',
parameters: {
type: 'object',
properties: {
city: {
type: 'string',
description: 'City name, e.g., Beijing'
},
unit: {
type: 'string',
enum: ['celsius', 'fahrenheit']
}
},
required: ['city']
}
}
}
];
const messages = [
{ role: 'user', content: "What's the weather like in Beijing right now?" }
];
// First round
const response = await client.chat.completions.create({
model: 'gpt-5.5',
messages: messages,
tools: tools,
tool_choice: 'auto'
});
// Check for tool calls
if (response.choices[0].message.tool_calls) {
const toolCall = response.choices[0].message.tool_calls[0];
const toolResult = 'Beijing, sunny, temperature 23 Celsius, humidity 45%.';
// Second round
messages.push(response.choices[0].message);
messages.push({
role: 'tool',
tool_call_id: toolCall.id,
content: toolResult
});
const finalResponse = await client.chat.completions.create({
model: 'gpt-5.5',
messages: messages,
tools: tools
});
console.log(finalResponse.choices[0].message.content);
}
}
// Structured output
async function structuredOutput() {
const response = await client.chat.completions.create({
model: 'gpt-5.5',
messages: [
{
role: 'user',
content: 'Extract key information from the following text: RouteAPI is an AI API gateway supporting OpenAI, Claude, Gemini and other models.'
}
],
response_format: {
type: 'json_schema',
json_schema: {
name: 'key_info',
strict: true,
schema: {
type: 'object',
properties: {
product_name: { type: 'string' },
category: { type: 'string' },
supported_models: {
type: 'array',
items: { type: 'string' }
}
},
required: ['product_name', 'category', 'supported_models'],
additionalProperties: false
}
}
}
});
console.log(response.choices[0].message.content);
}
// Run examples
async function main() {
await basicChat();
console.log('\n' + '='.repeat(50) + '\n');
await streamingChat();
console.log('\n' + '='.repeat(50) + '\n');
await toolCalling();
console.log('\n' + '='.repeat(50) + '\n');
await structuredOutput();
}
main().catch(console.error);
  • Prioritize the OpenAI compatible protocol if your client, SDK, or tool natively supports the OpenAI API
  • Fix model IDs, don’t rely on temporary aliases or display names in production
  • Record request metadata, including request ID, model ID, status code, latency, and token usage
  • Enable failure retries, enable client retries and alternative model options for core business flows
  • Validate optional capabilities, test tool calling, structured output, visual input, and other capabilities in a test environment first
  • Monitor costs and quotas, regularly check usage logs and billing details in the console
  • Protect API Keys, encapsulate RouteAPI Tokens on the server side and avoid exposing keys directly to business frontends

If the client only supports Claude Messages or Google Gemini protocol, use the corresponding protocol endpoints; refer to Claude Messages and Gemini API documentation.