Responses API
OpenAI-совместимый Responses API
Этот API stateless — каждый запрос независим, состояние диалога между запросами не сохраняется. Вы должны передавать полную историю переписки в каждом запросе. Запросы с store: true или непустым previous_response_id отклоняются с ошибкой 400.
Responses API предоставляет OpenAI-совместимый доступ к множеству AI-моделей через единый интерфейс и является drop-in заменой OpenAI Responses API. API поддерживает reasoning, вызов инструментов (tool calling) и веб-поиск, при этом каждый запрос независим и не сохраняет состояние на стороне сервера.
Базовый URL
https://api.ru-openrouter.ru/v1/responses
Также доступен через основной домен:
https://ru-openrouter.ru/api/v1/responses
Аутентификация
Все запросы требуют аутентификацию с помощью вашего API-ключа:
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": "Hello, world!"
}'
import requests
response = requests.post(
'https://api.ru-openrouter.ru/v1/responses',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
json={
'model': 'openai/o4-mini',
'input': 'Hello, world!',
}
)
Основные возможности
- Базовое использование — простой текстовый ввод и обработка ответов
- Reasoning — расширенные возможности рассуждений с настраиваемым уровнем усилий
- Tool Calling — интеграция вызова функций с поддержкой параллельного выполнения
- Web Search — веб-поиск с получением информации в реальном времени и цитированием
- Обработка ошибок — структурированные ответы об ошибках
Базовое использование
Responses API поддерживает как простой строковый ввод, так и структурированные массивы сообщений.
Простой строковый ввод
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": "What is the meaning of life?",
"max_output_tokens": 9000
}'
Структурированный ввод сообщений
Для более сложных диалогов используйте формат массива сообщений:
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Tell me a joke about programming"
}
]
}
],
"max_output_tokens": 9000
}'
Формат ответа
API возвращает структурированный ответ с сгенерированным контентом:
{
"id": "resp_1234567890",
"object": "response",
"created_at": 1234567890,
"model": "openai/o4-mini",
"output": [
{
"type": "message",
"id": "msg_abc123",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "The meaning of life is a philosophical question that has been pondered for centuries...",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 12,
"output_tokens": 45,
"total_tokens": 57
},
"status": "completed"
}
Стриминг
Включите стриминг для генерации ответа в реальном времени:
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": "Write a short story about AI",
"stream": true,
"max_output_tokens": 9000
}'
Стриминговый ответ возвращается в виде Server-Sent Events (SSE):
data: {"type":"response.created","response":{"id":"resp_1234567890","object":"response","status":"in_progress"}}
data: {"type":"response.output_item.added","response_id":"resp_1234567890","output_index":0,"item":{"type":"message","id":"msg_abc123","role":"assistant","status":"in_progress","content":[]}}
data: {"type":"response.content_part.added","response_id":"resp_1234567890","output_index":0,"content_index":0,"part":{"type":"output_text","text":""}}
data: {"type":"response.content_part.delta","response_id":"resp_1234567890","output_index":0,"content_index":0,"delta":"Once"}
data: {"type":"response.content_part.delta","response_id":"resp_1234567890","output_index":0,"content_index":0,"delta":" upon"}
data: {"type":"response.content_part.delta","response_id":"resp_1234567890","output_index":0,"content_index":0,"delta":" a"}
data: {"type":"response.content_part.delta","response_id":"resp_1234567890","output_index":0,"content_index":0,"delta":" time"}
data: {"type":"response.output_item.done","response_id":"resp_1234567890","output_index":0,"item":{"type":"message","id":"msg_abc123","role":"assistant","status":"completed","content":[{"type":"output_text","text":"Once upon a time, in a world where artificial intelligence had become as common as smartphones..."}]}}
data: {"type":"response.done","response":{"id":"resp_1234567890","object":"response","status":"completed","usage":{"input_tokens":12,"output_tokens":45,"total_tokens":57}}}
data: [DONE]
Общие параметры
| Параметр | Тип | Описание |
|---|---|---|
model |
string | Обязательный. Модель (например, openai/o4-mini) |
input |
string / array | Обязательный. Текст или массив сообщений |
stream |
boolean | Включить стриминг (по умолчанию: false) |
max_output_tokens |
integer | Максимальное количество генерируемых токенов |
temperature |
number | Температура сэмплирования (0–2) |
top_p |
number | Параметр nucleus sampling (0–1) |
Reasoning
Responses API поддерживает расширенные возможности рассуждений, позволяя моделям показывать свой внутренний процесс с настраиваемым уровнем усилий.
Конфигурация reasoning
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": "What is the meaning of life?",
"reasoning": {
"effort": "high"
},
"max_output_tokens": 9000
}'
Уровни усилий reasoning
| Уровень | Описание |
|---|---|
minimal |
Базовые рассуждения с минимальными вычислительными затратами |
low |
Лёгкие рассуждения для простых задач |
medium |
Сбалансированные рассуждения для задач средней сложности |
high |
Глубокие рассуждения для сложных задач |
Ответ с reasoning
Когда reasoning включён, ответ содержит информацию о процессе рассуждений:
{
"id": "resp_1234567890",
"object": "response",
"created_at": 1234567890,
"model": "openai/o4-mini",
"output": [
{
"type": "reasoning",
"id": "rs_abc123",
"encrypted_content": "gAAAAABotI9-FK1PbhZhaZk4yMrZw3XDI1AWFaKb9T0NQq7LndK6zaRB...",
"summary": [
"First, I need to determine the current year",
"Then calculate the difference from 1995",
"Finally, compare that to 30 years"
]
},
{
"type": "message",
"id": "msg_xyz789",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "Yes. In 2025, 1995 was 30 years ago.",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 85,
"output_tokens_details": {
"reasoning_tokens": 45
},
"total_tokens": 100
},
"status": "completed"
}
Стриминг reasoning
Включите стриминг, чтобы наблюдать за рассуждениями в реальном времени. Событие response.reasoning.delta содержит фрагменты процесса рассуждений.
Рекомендации
- Выбирайте подходящий уровень усилий:
highдля сложных задач,lowдля простых - Учитывайте расход токенов: reasoning увеличивает потребление токенов
- Используйте стриминг: для длинных цепочек рассуждений стриминг даёт лучший пользовательский опыт
- Предоставляйте контекст: давайте модели достаточно контекста для эффективных рассуждений
Tool Calling
Responses API поддерживает полноценный вызов инструментов: вызов функций, параллельное выполнение и сложные многошаговые сценарии.
Определение инструмента
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "What is the weather in San Francisco?"
}
]
}
],
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "Get the current weather in a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
],
"tool_choice": "auto",
"max_output_tokens": 9000
}'
Варианты tool_choice
| Tool Choice | Описание |
|---|---|
auto |
Модель сама решает, вызывать ли инструменты |
none |
Модель не будет вызывать инструменты |
{type: 'function', name: 'tool_name'} |
Принудительный вызов конкретного инструмента |
Параллельные вызовы инструментов
API поддерживает параллельное выполнение нескольких инструментов. Определите несколько инструментов в массиве tools — модель сможет вызывать их одновременно, если это уместно.
Ответ с вызовом функции
Когда инструменты вызываются, ответ содержит информацию о вызове функции:
{
"id": "resp_1234567890",
"object": "response",
"created_at": 1234567890,
"model": "openai/o4-mini",
"output": [
{
"type": "function_call",
"id": "fc_abc123",
"call_id": "call_xyz789",
"name": "get_weather",
"arguments": "{\"location\":\"San Francisco, CA\"}"
}
],
"usage": {
"input_tokens": 45,
"output_tokens": 25,
"total_tokens": 70
},
"status": "completed"
}
Ответы инструментов в диалоге
Включайте ответы инструментов в последующие запросы:
{
"model": "openai/o4-mini",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "What is the weather in Boston?"
}
]
},
{
"type": "function_call",
"id": "fc_1",
"call_id": "call_123",
"name": "get_weather",
"arguments": "{\"location\": \"Boston, MA\"}"
},
{
"type": "function_call_output",
"id": "fc_output_1",
"call_id": "call_123",
"output": "{\"temperature\": \"72°F\", \"condition\": \"Sunny\"}"
},
{
"type": "message",
"role": "assistant",
"id": "msg_abc123",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "The weather in Boston is currently 72°F and sunny.",
"annotations": []
}
]
},
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Is that good weather for a picnic?"
}
]
}
],
"max_output_tokens": 9000
}
Поле id необязательно для объектов function_call_output. Обязательны только type, call_id и output — именно call_id связывает вывод с исходным function_call.
Мультимодальные выводы инструментов
function_call_output.output принимает строку или массив частей контента (input_text, input_image, input_file) — ту же структуру, что и контент пользовательского сообщения. Используйте массив, чтобы возвращать изображения или файлы из инструмента; нетекстовые части передаются только поддерживающим мультимодальным моделям.
Стриминг вызовов инструментов
При стриминге отслеживайте события response.output_item.added (с item.type === 'function_call') и response.function_call_arguments.done (содержит полные аргументы).
Рекомендации
- Понятные описания: давайте подробные описания функций и параметров
- Корректные схемы: используйте валидный JSON Schema для параметров
- Обработка ошибок: учитывайте случаи, когда инструменты могут не вызываться
- Параллельное выполнение: проектируйте инструменты независимыми, когда это возможно
- Поток диалога: включайте ответы инструментов в последующие запросы для контекста
Web Search
Responses API поддерживает веб-поиск, позволяя моделям получать актуальную информацию из интернета и отвечать с корректными цитатами и аннотациями.
Включение веб-поиска
Используйте параметр plugins:
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": "What is OpenRouter?",
"plugins": [{ "id": "web", "max_results": 3 }],
"max_output_tokens": 9000
}'
Конфигурация плагина
| Параметр | Тип | Описание |
|---|---|---|
id |
string | Обязательный. Должен быть "web" |
engine |
string | Поисковый движок: "native", "exa", "firecrawl", "parallel" или опустить для авто |
max_results |
integer | Максимальное количество результатов (1–25; по умолчанию 5) |
include_domains |
string[] | Ограничить результаты этими доменами (поддерживаются wildcard, например *.substack.com) |
exclude_domains |
string[] | Исключить результаты из этих доменов |
X Search Filters (SpaceXAI)
При использовании моделей SpaceXAI (например, x-ai/grok-4.1-fast) можно передать параметр x_search_filter верхнего уровня для фильтрации результатов поиска по X/Twitter:
{
"model": "x-ai/grok-4.1-fast",
"input": "What are people saying about AI?",
"plugins": [{ "id": "web" }],
"x_search_filter": {
"allowed_x_handles": ["OpenRouterAI"],
"from_date": "2025-01-01",
"enable_image_understanding": true
}
}
| Параметр | Тип | Описание |
|---|---|---|
allowed_x_handles |
string[] | Включать посты только этих аккаунтов (макс. 20) |
excluded_x_handles |
string[] | Исключить посты этих аккаунтов (макс. 20) |
from_date |
string | Начальная дата (ISO 8601, например "2025-01-01") |
to_date |
string | Конечная дата (ISO 8601, например "2025-12-31") |
enable_image_understanding |
boolean | Анализировать изображения в постах |
enable_video_understanding |
boolean | Анализировать видео в постах |
allowed_x_handles и excluded_x_handles взаимоисключающие.
Online Model Variants
Вариант :online устарел. Используйте серверный инструмент openrouter:web_search через массив tools вместо него.
Некоторые модели имеют встроенный веб-поиск через вариант :online:
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini:online",
"input": "What was a positive news story from today?",
"max_output_tokens": 9000
}'
Ответ с аннотациями
Ответы веб-поиска содержат аннотации цитирования:
{
"id": "resp_1234567890",
"object": "response",
"created_at": 1234567890,
"model": "openai/o4-mini",
"output": [
{
"type": "message",
"id": "msg_abc123",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "OpenRouter is a unified API for accessing multiple Large Language Model providers through a single interface.",
"annotations": [
{
"type": "url_citation",
"url": "https://openrouter.ai/docs",
"start_index": 0,
"end_index": 85
}
]
}
]
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 95,
"total_tokens": 110
},
"status": "completed"
}
Типы аннотаций
URL Citation:
{
"type": "url_citation",
"url": "https://example.com/article",
"start_index": 0,
"end_index": 50,
"content": "Excerpt from the web page..."
}
Рекомендации
- Ограничивайте результаты: используйте подходящий
max_resultsдля баланса качества и скорости - Обрабатывайте аннотации: обрабатывайте цитаты для корректной атрибуции
- Конкретные запросы: делайте поисковые запросы конкретными для лучших результатов
- Обработка ошибок: учитывайте случаи, когда веб-поиск может завершиться ошибкой
Дополнительные возможности
Суффиксы моделей :nitro / :floor
К имени модели можно добавить суффикс, чтобы управлять выбором провайдера по приоритету:
| Суффикс | Поведение |
|---|---|
:nitro |
Приоритет провайдеров по пропускной способности (provider.sort = "throughput") |
:floor |
Приоритет провайдеров по цене (provider.sort = "price") |
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini:nitro",
"input": "Hello, world!"
}'
Управление маршрутизацией (provider)
Параметр provider позволяет управлять выбором провайдера для запроса:
{
"model": "openai/o4-mini",
"input": "Hello, world!",
"provider": {
"sort": "throughput",
"order": ["OpenAI", "Azure"],
"ignore": ["SomeProvider"],
"allow_fallbacks": true
}
}
| Поле | Тип | Описание |
|---|---|---|
sort |
string | Стратегия сортировки провайдеров: "throughput", "price", "latency" |
order |
string[] | Приоритетный порядок провайдеров |
ignore |
string[] | Провайдеры, которые следует исключить |
allow_fallbacks |
boolean | Разрешить fallback на другие провайдеры при ошибке |
Заголовки атрибуции
Заголовки атрибуции пробрасываются провайдеру и используются для идентификации источника запроса:
| Заголовок | Описание |
|---|---|
HTTP-Referer |
URL сайта-источника запроса |
X-Title / X-OpenRouter-Title |
Название приложения-источника |
X-OpenRouter-Metadata |
Произвольные метаданные запроса |
X-OpenRouter-Experimental-Metadata |
Экспериментальные метаданные запроса |
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "HTTP-Referer: https://example.com" \
-H "X-Title: My App" \
-d '{
"model": "openai/o4-mini",
"input": "Hello, world!"
}'
Кэширование
Кэширование управляется через заголовки запроса:
| Заголовок | Описание |
|---|---|
X-OpenRouter-Cache |
Включить/выключить кэширование (true / false) |
X-OpenRouter-Cache-TTL |
Время жизни кэша в секундах (по умолчанию 3600) |
X-OpenRouter-Cache-Clear |
Принудительный сброс кэша (true) |
При включённом кэшировании в запрос автоматически добавляются cache_control: { "type": "ephemeral" } и session_id для sticky routing, что оптимизирует повторные запросы в многоходовых диалогах.
Отслеживание запросов
Заголовок X-Request-Id позволяет связать запрос с его логами и историей использования:
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: my-request-123" \
-d '{
"model": "openai/o4-mini",
"input": "Hello, world!"
}'
Обработка ошибок
API возвращает структурированные ответы об ошибках в едином формате.
Формат ответа об ошибке
{
"error": {
"code": "invalid_prompt",
"message": "Detailed error description"
},
"metadata": null
}
Коды ошибок
| Код | Описание | HTTP-статус |
|---|---|---|
invalid_prompt |
Ошибка валидации запроса или промпта (превышение длины контекста, некорректные поля) | 400 |
rate_limit_exceeded |
Слишком много запросов | 429 |
image_content_policy_violation |
Входной или выходной контент отклонён фильтром | 400 |
server_error |
Внутренняя ошибка сервера, ошибка аутентификации, перегрузка/недоступность провайдера или таймаут | 500+ |
Каноническое поле error_type
Поскольку нативный словарь error.code теряет часть информации (многие ошибки сводятся к server_error), неудачные ответы также содержат поле верхнего уровня error_type с точным каноническим типом ошибки:
{
"id": "resp_abc123",
"status": "failed",
"error": { "code": "server_error", "message": "Invalid credentials" },
"error_type": "authentication"
}
Используйте error_type для программного различения категорий ошибок, когда нативный code неоднозначен.
Многоходовые диалоги
Поскольку Responses API stateless, вы должны включать полную историю переписки в каждый запрос, чтобы сохранить контекст. Параметры состояния, такие как store: true и previous_response_id, не поддерживаются и отклоняются с ошибкой 400.
# Первый запрос
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "What is the capital of France?"
}
]
}
],
"max_output_tokens": 9000
}'
# Второй запрос — включаем предыдущий диалог
curl -X POST https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/o4-mini",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "What is the capital of France?"
}
]
},
{
"type": "message",
"role": "assistant",
"id": "msg_abc123",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "The capital of France is Paris.",
"annotations": []
}
]
},
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "What is the population of that city?"
}
]
}
],
"max_output_tokens": 9000
}'
Поля id и status обязательны для сообщений с ролью assistant, включённых в историю переписки.
Всегда включайте полную историю переписки в каждый запрос. API не хранит предыдущие сообщения, поэтому контекст должен поддерживаться на стороне клиента.