curl --request POST \
--url https://openrouter.ai/api/v1/chat/completions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"max_tokens": 150,
"messages": [
{
"content": "You are a helpful assistant.",
"role": "system"
},
{
"content": "What is the capital of France?",
"role": "user"
}
],
"model": "openai/gpt-4",
"temperature": 0.7
}
'import requests
url = "https://openrouter.ai/api/v1/chat/completions"
payload = {
"max_tokens": 150,
"messages": [
{
"content": "You are a helpful assistant.",
"role": "system"
},
{
"content": "What is the capital of France?",
"role": "user"
}
],
"model": "openai/gpt-4",
"temperature": 0.7
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
max_tokens: 150,
messages: [
{content: 'You are a helpful assistant.', role: 'system'},
{content: 'What is the capital of France?', role: 'user'}
],
model: 'openai/gpt-4',
temperature: 0.7
})
};
fetch('https://openrouter.ai/api/v1/chat/completions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://openrouter.ai/api/v1/chat/completions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'max_tokens' => 150,
'messages' => [
[
'content' => 'You are a helpful assistant.',
'role' => 'system'
],
[
'content' => 'What is the capital of France?',
'role' => 'user'
]
],
'model' => 'openai/gpt-4',
'temperature' => 0.7
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://openrouter.ai/api/v1/chat/completions"
payload := strings.NewReader("{\n \"max_tokens\": 150,\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"What is the capital of France?\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"openai/gpt-4\",\n \"temperature\": 0.7\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openrouter.ai/api/v1/chat/completions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"max_tokens\": 150,\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"What is the capital of France?\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"openai/gpt-4\",\n \"temperature\": 0.7\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/chat/completions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"max_tokens\": 150,\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"What is the capital of France?\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"openai/gpt-4\",\n \"temperature\": 0.7\n}"
response = http.request(request)
puts response.read_body{
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "The capital of France is Paris.",
"role": "assistant"
}
}
],
"created": 1677652288,
"id": "chatcmpl-123",
"model": "openai/gpt-4",
"object": "chat.completion",
"system_fingerprint": "fp_44709d6fcb",
"usage": {
"completion_tokens": 10,
"prompt_tokens": 25,
"total_tokens": 35
}
}Create a chat completion
Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.
curl --request POST \
--url https://openrouter.ai/api/v1/chat/completions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"max_tokens": 150,
"messages": [
{
"content": "You are a helpful assistant.",
"role": "system"
},
{
"content": "What is the capital of France?",
"role": "user"
}
],
"model": "openai/gpt-4",
"temperature": 0.7
}
'import requests
url = "https://openrouter.ai/api/v1/chat/completions"
payload = {
"max_tokens": 150,
"messages": [
{
"content": "You are a helpful assistant.",
"role": "system"
},
{
"content": "What is the capital of France?",
"role": "user"
}
],
"model": "openai/gpt-4",
"temperature": 0.7
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
max_tokens: 150,
messages: [
{content: 'You are a helpful assistant.', role: 'system'},
{content: 'What is the capital of France?', role: 'user'}
],
model: 'openai/gpt-4',
temperature: 0.7
})
};
fetch('https://openrouter.ai/api/v1/chat/completions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://openrouter.ai/api/v1/chat/completions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'max_tokens' => 150,
'messages' => [
[
'content' => 'You are a helpful assistant.',
'role' => 'system'
],
[
'content' => 'What is the capital of France?',
'role' => 'user'
]
],
'model' => 'openai/gpt-4',
'temperature' => 0.7
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://openrouter.ai/api/v1/chat/completions"
payload := strings.NewReader("{\n \"max_tokens\": 150,\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"What is the capital of France?\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"openai/gpt-4\",\n \"temperature\": 0.7\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openrouter.ai/api/v1/chat/completions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"max_tokens\": 150,\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"What is the capital of France?\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"openai/gpt-4\",\n \"temperature\": 0.7\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/chat/completions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"max_tokens\": 150,\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"What is the capital of France?\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"openai/gpt-4\",\n \"temperature\": 0.7\n}"
response = http.request(request)
puts response.read_body{
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "The capital of France is Paris.",
"role": "assistant"
}
}
],
"created": 1677652288,
"id": "chatcmpl-123",
"model": "openai/gpt-4",
"object": "chat.completion",
"system_fingerprint": "fp_44709d6fcb",
"usage": {
"completion_tokens": 10,
"prompt_tokens": 25,
"total_tokens": 35
}
}Authorizations
API key as bearer token in Authorization header
Headers
Opt-in to surface routing metadata on the response under openrouter_metadata. Defaults to disabled. The legacy header X-OpenRouter-Experimental-Metadata is also accepted for backward compatibility.
Opt-in level for surfacing routing metadata on the response under openrouter_metadata.
disabled, enabled "enabled"
Body
Chat completion request parameters
List of messages for the conversation
1Chat completion message with role-based discrimination
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
Show child attributes
Show child attributes
{
"content": "What is the capital of France?",
"name": "Assistant Config",
"role": "user"
}
[{ "content": "Hello!", "role": "user" }]
Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. When set on an individual content block, it marks an explicit cache breakpoint; block-level markers also work on OpenAI models that support explicit prompt caching — OpenRouter converts them to the provider's native format.
Show child attributes
Show child attributes
{ "type": "ephemeral" }
Debug options for inspecting request transformations (streaming only)
Show child attributes
Show child attributes
{ "echo_upstream_body": true }
Frequency penalty (-2.0 to 2.0)
0
Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
Show child attributes
Show child attributes
{ "aspect_ratio": "16:9", "quality": "high" }
Token logit bias adjustments
Show child attributes
Show child attributes
{ "50256": -100 }
Return log probabilities
false
Maximum tokens in completion
100
Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
100
Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
Show child attributes
Show child attributes
{
"session_id": "session-456",
"user_id": "user-123"
}
Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
0.1
Output modalities for the response. Supported values are "text", "image", and "audio".
text, image, audio ["text", "image"]
Model to use for completion
"openai/gpt-4"
Models to use for completion
Available OpenRouter chat completion models
["openai/gpt-4", "openai/gpt-4o"]
Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
true
Plugins you want to enable for this request, including their settings.
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
- Option 6
- Option 7
- Option 8
- Option 9
- Option 10
Show child attributes
Show child attributes
{
"allowed_models": ["anthropic/*", "openai/*"],
"cost_tier": "low",
"enabled": true,
"excluded_models": ["openai/gpt-4o"],
"id": "auto-router",
"pin_model": false
}
Static predicted output content. Supported models can use this to reduce latency when much of the response is known in advance.
Show child attributes
Show child attributes
{
"content": "Expected response",
"type": "content"
}
Presence penalty (-2.0 to 2.0)
0
Request-level prompt-cache controls. mode: "explicit" disables OpenAI-managed breakpoints so only blocks marked with prompt_cache_breakpoint are cached. Only supported by OpenAI GPT-5.6 and newer.
Show child attributes
Show child attributes
{ "mode": "explicit", "ttl": "30m" }
When multiple model providers are available, optionally indicate your routing preference.
Show child attributes
Show child attributes
{ "allow_fallbacks": true }
Configuration options for reasoning models
Show child attributes
Show child attributes
{ "effort": "medium", "summary": "concise" }
Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
max, xhigh, high, medium, low, minimal, none, null "medium"
Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
1
Response format configuration
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
Show child attributes
Show child attributes
{ "type": "json_object" }
DEPRECATED Use providers.sort.partition instead. Backwards-compatible alias for providers.sort.partition. Accepts legacy values: "fallback" (maps to "model"), "sort" (maps to "none").
fallback, sort, null "fallback"
Random seed for deterministic outputs
42
The service tier to use for processing this request. fast is accepted as an alias for priority.
auto, default, fast, flex, priority, scale, null "auto"
A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
256Stop sequences (up to 4)
["\n"]
Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides max_tool_calls. When a condition fires while the model is still emitting tool calls, the pending tool calls are executed and one final turn is made with tool calls disabled so the response ends with a natural-language answer instead of an unfinished tool call.
1A single condition that, when met, halts the server-tool agent loop.
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
Show child attributes
Show child attributes
{ "step_count": 5, "type": "step_count_is" }
[
{ "step_count": 5, "type": "step_count_is" },
{
"max_cost_in_dollars": 0.5,
"type": "max_cost"
}
]
Enable streaming response
false
Streaming configuration options
Show child attributes
Show child attributes
{ "include_usage": true }
Sampling temperature (0-2)
0.7
Tool choice configuration
none "auto"
Available tools for function calling
Tool definition for function calling (regular function or OpenRouter built-in server tool)
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
- Option 6
- Option 7
- Option 8
- Option 9
- Option 10
- Option 11
- Option 12
Show child attributes
Show child attributes
{
"function": {
"description": "Get the current weather for a location",
"name": "get_weather",
"parameters": {
"properties": {
"location": {
"description": "City name",
"type": "string"
},
"unit": {
"enum": ["celsius", "fahrenheit"],
"type": "string"
}
},
"required": ["location"],
"type": "object"
}
},
"type": "function"
}
[
{
"function": {
"description": "Get weather",
"name": "get_weather"
},
"type": "function"
}
]
Consider only tokens with "sufficiently high" probabilities based on the probability of the most likely token. Not all providers support this parameter.
0
Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
40
Number of top log probabilities to return (0-20)
5
Nucleus sampling parameter (0-1)
1
Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
Show child attributes
Show child attributes
{
"trace_id": "trace-abc123",
"trace_name": "my-app-trace"
}
Per-end-user identifier for abuse isolation. Use a stable ID, hash, or pseudonym. When a provider requires a user identity, OpenRouter folds it into the hashed identity sent upstream and never forwards it raw. If omitted, requests use an account-level identity, so provider policy blocks can affect the whole account.
"user-123"
Response
Successful chat completion response
Chat completion response
List of completion choices
Show child attributes
Show child attributes
Unix timestamp of creation
1677652288
Unique completion identifier
"chatcmpl-123"
Model used for completion
"openai/gpt-4"
chat.completion System fingerprint
"fp_44709d6fcb"
Show child attributes
Show child attributes
{
"attempt": 1,
"endpoints": {
"available": [
{
"model": "openai/gpt-4o",
"provider": "OpenAI",
"selected": true
}
],
"total": 1
},
"is_byok": false,
"region": "iad",
"requested": "openai/gpt-4o",
"strategy": "direct",
"summary": "available=1, selected=OpenAI"
}
The service tier used by the upstream provider for this request
"default"
Token usage statistics
Show child attributes
Show child attributes
{
"completion_tokens": 15,
"completion_tokens_details": { "reasoning_tokens": 5 },
"cost": 0.0012,
"cost_details": {
"upstream_inference_completions_cost": 0.0004,
"upstream_inference_cost": null,
"upstream_inference_prompt_cost": 0.0008
},
"is_byok": false,
"prompt_tokens": 10,
"prompt_tokens_details": { "cached_tokens": 2 },
"server_tool_use_details": {
"tool_calls_executed": 2,
"tool_calls_requested": 2
},
"total_tokens": 25
}