Responses API

OpenAI-совместимый Responses API

Stateless Only

Этот 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 содержит фрагменты процесса рассуждений.

Рекомендации

  1. Выбирайте подходящий уровень усилий: high для сложных задач, low для простых
  2. Учитывайте расход токенов: reasoning увеличивает потребление токенов
  3. Используйте стриминг: для длинных цепочек рассуждений стриминг даёт лучший пользовательский опыт
  4. Предоставляйте контекст: давайте модели достаточно контекста для эффективных рассуждений

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.addeditem.type === 'function_call') и response.function_call_arguments.done (содержит полные аргументы).

Рекомендации

  1. Понятные описания: давайте подробные описания функций и параметров
  2. Корректные схемы: используйте валидный JSON Schema для параметров
  3. Обработка ошибок: учитывайте случаи, когда инструменты могут не вызываться
  4. Параллельное выполнение: проектируйте инструменты независимыми, когда это возможно
  5. Поток диалога: включайте ответы инструментов в последующие запросы для контекста

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..."
}

Рекомендации

  1. Ограничивайте результаты: используйте подходящий max_results для баланса качества и скорости
  2. Обрабатывайте аннотации: обрабатывайте цитаты для корректной атрибуции
  3. Конкретные запросы: делайте поисковые запросы конкретными для лучших результатов
  4. Обработка ошибок: учитывайте случаи, когда веб-поиск может завершиться ошибкой

Дополнительные возможности

Суффиксы моделей :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 не хранит предыдущие сообщения, поэтому контекст должен поддерживаться на стороне клиента.