Chat Completions API
OpenAI-compatible POST /v1/chat/completions with multiple models, service selection, streaming, and tool calls.
Inference Space provides the OpenAI-compatible chat completion endpoint POST /v1/chat/completions across the LLM model families in the catalog, including Claude, GPT, Gemini, DeepSeek, Qwen, and Kimi. Existing OpenAI-compatible clients can connect by changing only the Base, Key, and model; no application-code rewrite is required.
The private deployment API is identical; only the Base domain needs to change → Enterprise private deployment.
Overview
- Endpoint:
POST https://ai.inf.space/v1/chat/completions - Base:
https://ai.inf.space/v1(the browser console shares theai.inf.spacehost; use the/v1path for API requests) - Protocol: OpenAI Chat Completions compatible, with request and response fields matching OpenAI
- Multiple models: Send only
modelwith the same Key and endpoint; the gateway selects a service from the organization's routing policy
Actual model IDs and prices depend on what is shown in the console. Manage model IDs as configuration so that versions can be changed smoothly as the console is updated. See Model list and Authentication.
Authentication
Authenticate with the HTTP header Authorization: Bearer <gk_...>. API Keys start with gk_ and are created in the console. The request body is application/json.
Authorization: Bearer gk_xxxxxxxxxxxxxxxx
Content-Type: application/jsonIn production, keep the Key on the server and do not expose it to browsers or clients.
Automatic routing
Clients send only model and must not select a provider through a URL query parameter, the X-Provider header, or a request-body field. The gateway selects an available service from the API Key organization's routing policy and performs failover when a candidate is unavailable.
Do not include provider in requests. Service selection, circuit breaking, and failover are managed by the gateway; pinning a provider bypasses organization policy and reduces availability. /v1/chat/completions, /v1/responses, and /v1/messages all follow this rule.
Gemini models
Call Gemini by using the corresponding model. Model IDs match Google's official IDs, and the gateway selects the service from organization policy:
| model | Context window | Vision | Description |
|---|---|---|---|
gemini-3.5-flash | 1,048,576 | ✅ | Cost-effective Flash with strong coding and agent capabilities (2026-05 GA) |
gemini-3.1-pro-preview | 1,048,576 | ✅ | Flagship multimodal reasoning (text / image / video / audio / code) |
gemini-2.0-flash | 1,048,576 | ✅ | Previous-generation Flash |
gemini-1.5-pro | 2,097,152 | ✅ | Pro with an extra-long context window |
Gemini 3.x models use reasoning (thinking) tokens before producing an answer. Set max_tokens large enough (we recommend ≥ 1024); a budget that is too small can consume the entire allowance on thinking tokens, causing message.content to return null with finish_reason set to length.
Basic request
curl "https://ai.inf.space/v1/chat/completions" \
-H "Authorization: Bearer $TOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-x",
"messages": [
{ "role": "system", "content": "You are a concise assistant." },
{ "role": "user", "content": "Introduce yourself in three sentences." }
]
}'import os
from openai import OpenAI
client = OpenAI(
base_url="https://ai.inf.space/v1",
api_key=os.environ["TOS_API_KEY"],
)
resp = client.chat.completions.create(
model="claude-sonnet-4-x",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Introduce yourself in three sentences."},
],
)
print(resp.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://ai.inf.space/v1",
apiKey: process.env.TOS_API_KEY,
});
const resp = await client.chat.completions.create({
model: "claude-sonnet-4-x",
messages: [
{ role: "system", content: "You are a concise assistant." },
{ role: "user", content: "Introduce yourself in three sentences." },
],
});
console.log(resp.choices[0].message.content);Use the standard OpenAI request shape: send model and business parameters only, without any provider-selection field.
Parameters
The standard OpenAI fields are supported:
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model ID; use the value shown in the console. |
messages | array | Yes | Array of conversation messages; each item contains role and content. |
max_tokens | integer | No | Maximum number of output tokens in a response. |
temperature | number | No | Sampling temperature; higher values produce more varied output. |
top_p | number | No | Nucleus-sampling threshold; use it instead of temperature. |
stop | string / array | No | Stop sequence; generation stops when it is matched. |
stream | boolean | No | Whether to return an SSE stream; defaults to false. |
tools | array | No | List of tool (function) definitions. |
tool_choice | string / object | No | Tool-selection strategy, such as "auto" or a specific tool. |
Parameter support varies by service and model. Unsupported fields are ignored to avoid request errors. Service differences are handled by gateway routing and remain transparent to clients.
Streaming
With stream: true, the response is returned as Server-Sent Events (SSE) chunks. Each chunk is the OpenAI-standard chat.completion.chunk; incremental text is in choices[0].delta.content, and the stream ends with data: [DONE].
curl "https://ai.inf.space/v1/chat/completions" \
-H "Authorization: Bearer $TOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-x",
"stream": true,
"messages": [
{ "role": "user", "content": "Write a short poem about clouds." }
]
}'For streaming requests, the gateway forcibly injects stream_options.include_usage = true so the upstream sends a usage chunk at the end of the stream for metering and billing. The final chunk has an empty choices array ([]), which standard SDKs such as OpenAI, LangChain, LiteLLM, and Vercel AI SDK ignore automatically. Only hand-written SSE parsers that unconditionally access chunk.choices[0] need an empty-array check. Even if the client explicitly sends include_usage:false, the gateway overrides it to true; token metering is the gateway's responsibility and cannot be bypassed.
The final usage chunk looks like this:
{
"id": "chatcmpl-xxx",
"object": "chat.completion.chunk",
"choices": [],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 38,
"total_tokens": 62
}
}Tool calls
Declare callable functions with tools. When needed, the model returns tool_calls. After the application executes a tool, add its result as a role: "tool" message in the next messages turn so the model can produce the final answer.
curl "https://ai.inf.space/v1/chat/completions" \
-H "Authorization: Bearer $TOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-x",
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the weather for a specified city",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name" }
},
"required": ["city"]
}
}
}
],
"tool_choice": "auto",
"messages": [
{ "role": "user", "content": "What is the weather like in Hefei today?" }
]
}'Responses and usage
The non-streaming response uses the standard OpenAI structure:
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"model": "claude-sonnet-4-x",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Hello, I am a concise assistant." },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 38,
"total_tokens": 62
}
}Billing is based on input and output tokens in usage, in units of 1M tokens. Exact prices, available models, and discounts depend on console and organization pricing; organization-specific prices and contract discounts take precedence.