Multimodal (мультимодальные запросы)
Передача изображений, PDF, аудио и видео моделям, которые умеют с ними работать. Базовый URL: https://api.ru-openrouter.ru/v1/
Большинство современных моделей принимает не только текст. В одном запросе можно передать картинку, документ, аудиозапись или ролик — и попросить модель описать содержимое, распознать текст, найти нужный фрагмент, сравнить материалы между собой.
Мультимодальные входы передаются двумя способами: прямой ссылкой (если материал публично доступен) или base64-данными (для локальных и приватных файлов).
Обзор модальностей
| Модальность | Часть контента в /v1/responses |
Часть контента в /v1/chat/completions |
Ссылка | Base64 |
|---|---|---|---|---|
| Изображения | input_image |
image_url |
Да | Да |
input_file |
file |
Да (Responses) | Да | |
| Аудио (вход) | input_audio |
input_audio |
Нет | Да |
| Видео | input_video |
video_url |
Зависит от провайдера | Да |
Модальности можно смешивать в одном запросе: текст, изображения, документы, аудио и видео обрабатываются вместе. Сколько файлов примет провайдер, зависит от модели и провайдера.
Способы передачи данных
| Способ | Как выглядит | Когда использовать |
|---|---|---|
| Прямая ссылка | https://example.com/file |
Материал публично доступен |
| Base64 data URL | data:image/jpeg;base64,..., data:application/pdf;base64,..., data:video/mp4;base64,... |
Локальный или приватный файл |
Ссылки экономят трафик и не требуют кодирования, но поддерживаются не для всех модальностей. Base64 работает всегда, однако увеличивает тело запроса примерно на треть.
Эндпоинты
| Эндпоинт | Метод | Что принимает |
|---|---|---|
/v1/responses |
POST | input_image, input_file, input_audio, input_video |
/v1/chat/completions |
POST | image_url, file, input_audio, video_url |
/v1/messages |
POST | формат Anthropic; видео на входе не поддерживается |
Части контента передаются в массиве content сообщения пользователя. При смешивании текста и вложений сначала ставьте текст с задачей, затем файлы: так контент разбирается надёжнее. Системные сообщения должны содержать только текст.
Изображения
Модели со зрением принимают картинки для описания, OCR, поиска объектов и сравнения кадров.
Поддерживаемые форматы
| MIME-тип | Формат |
|---|---|
image/png | PNG |
image/jpeg | JPEG |
image/webp | WebP |
image/gif | GIF |
MIME-тип в data URL должен соответствовать реальному формату файла, иначе провайдер может отклонить изображение.
Изображение по ссылке (Chat Completions)
curl https://api.ru-openrouter.ru/v1/chat/completions \
-H "Authorization: Bearer sk_ваш_api_ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemini-3.1-flash-lite",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Сравни два изображения и опиши отличия." },
{ "type": "image_url", "image_url": { "url": "https://example.com/before.jpg" } },
{ "type": "image_url", "image_url": { "url": "https://example.com/after.jpg" } }
]
}
],
"max_tokens": 800
}'
Изображение в base64 (Responses API)
В Responses API image_url — строка со ссылкой или data URL.
import base64
import requests
with open("photo.jpg", "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
payload = {
"model": "google/gemini-3.1-flash-lite",
"input": [
{
"role": "user",
"content": [
{"type": "input_text", "text": "Распознай весь текст на изображении."},
{"type": "input_image", "image_url": f"data:image/jpeg;base64,{image_b64}"},
],
}
],
"max_output_tokens": 800,
}
response = requests.post(
"https://api.ru-openrouter.ru/v1/responses",
headers={
"Authorization": "Bearer sk_ваш_api_ключ",
"Content-Type": "application/json",
},
json=payload,
)
print(response.json())
Параметры части с изображением
| Поле | Тип | Описание |
|---|---|---|
type |
string | input_image (Responses) или image_url (Chat Completions) |
image_url / image_url.url |
string | Ссылка или data URL |
detail |
string | Необязательный уровень детализации: auto, low, high; поддерживается не всеми моделями |
Несколько изображений передаются отдельными элементами массива content.
PDF можно отправить любой модели. Если модель умеет работать с файлами напрямую, документ передаётся ей как есть; если нет — текст и изображения страниц извлекаются и передаются как обычный контент. Так можно задавать вопросы по договорам, отчётам, инструкциям и сканам без ручного копирования текста.
В Responses API документ передаётся частью input_file: ссылка — в file_url, содержимое — в file_data. Поле filename указывается вместе с документом. В Chat Completions используется часть file с полями filename и file_data.
PDF по ссылке (Responses API)
curl https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer sk_ваш_api_ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemini-3.1-flash-lite",
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Кратко перескажи документ и назови стороны договора." },
{ "type": "input_file", "filename": "contract.pdf", "file_url": "https://example.com/contract.pdf" }
]
}
],
"max_output_tokens": 1500
}'
Ссылка должна открываться без авторизации.
PDF в base64 (Chat Completions)
import base64
import requests
with open("report.pdf", "rb") as f:
pdf_b64 = base64.b64encode(f.read()).decode()
payload = {
"model": "google/gemini-3.1-flash-lite",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Сделай выжимку по ключевым цифрам отчёта."},
{
"type": "file",
"file": {
"filename": "report.pdf",
"file_data": f"data:application/pdf;base64,{pdf_b64}",
},
},
],
}
],
"max_tokens": 1500,
}
response = requests.post(
"https://api.ru-openrouter.ru/v1/chat/completions",
headers={
"Authorization": "Bearer sk_ваш_api_ключ",
"Content-Type": "application/json",
},
json=payload,
)
print(response.json())
Движки разбора
Как PDF превращается в контент для модели, задаётся плагином file-parser:
{
"plugins": [
{
"id": "file-parser",
"pdf": {
"engine": "cloudflare-ai"
}
}
]
}
| Движок | Что делает |
|---|---|
native |
Документ передаётся модели напрямую; доступен только моделям с нативной поддержкой файлов и тарифицируется как входные токены |
cloudflare-ai |
PDF конвертируется в markdown |
mistral-ocr |
OCR для сканов и документов с изображениями: извлекается текст и картинки страниц |
Если движок не указан, сначала используется нативная поддержка файлов у модели, а при её отсутствии — mistral-ocr. Движок pdf-text устарел: такие запросы перенаправляются на cloudflare-ai и продолжают работать.
Как обрабатывается документ
- Модель поддерживает файлы — PDF уходит провайдеру напрямую
- Модель не поддерживает файлы — документ разбирается, модели передаются текст и (если она принимает изображения) картинки страниц
- Модель не принимает изображения — картинки отбрасываются, остаётся только текст
Ограничение на изображения из PDF
При OCR-разборе из одного PDF запрашивается не более 8 изображений, и не более 8 передаётся модели. Лишние картинки отбрасываются, извлечённый текст сохраняется полностью. Ограничение связано с тем, что допустимое число изображений в запросе сильно различается у провайдеров.
Повторное использование разбора
В Chat Completions ответ может содержать аннотации разобранного файла:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "В документе обсуждается...",
"annotations": [
{
"type": "file",
"file": {
"hash": "abc123...",
"name": "contract.pdf",
"content": [
{ "type": "text", "text": "Разобранный текст..." },
{ "type": "image_url", "image_url": { "url": "data:image/png;base64,..." } }
]
}
}
]
}
}
]
}
| Поле | Описание |
|---|---|
file.hash |
Хеш разобранного содержимого |
file.name |
Имя файла (может отсутствовать) |
file.content |
Разобранное содержимое: текст и изображения |
Если вернуть аннотацию в следующем запросе, документ не будет разбираться заново — это экономит время и стоимость обработки. Дедупликация выполняется по file.hash.
В Responses API вместо этого приходят аннотации file_citation: они указывают, откуда взята цитата, но вернуть их для пропуска повторного разбора нельзя.
Аудио
Модели с поддержкой аудио-входа принимают записи для транскрипции, анализа и обработки. Аудио передаётся только в base64 — ссылки не поддерживаются.
Аудио на входе (Chat Completions)
import base64
import requests
with open("meeting.wav", "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode()
payload = {
"model": "google/gemini-3.1-flash-lite",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Транскрибируй аудио и определи язык речи."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "wav"}},
],
}
],
"max_tokens": 1000,
}
response = requests.post(
"https://api.ru-openrouter.ru/v1/chat/completions",
headers={
"Authorization": "Bearer sk_ваш_api_ключ",
"Content-Type": "application/json",
},
json=payload,
)
print(response.json())
Аудио на входе (Responses API)
{
"model": "google/gemini-3.1-flash-lite",
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Транскрибируй аудио." },
{ "type": "input_audio", "input_audio": { "data": "<base64>", "format": "wav" } }
]
}
],
"max_output_tokens": 1000
}
Форматы аудио на входе
| Эндпоинт | Допустимые значения format |
|---|---|
/v1/responses |
wav, mp3 |
/v1/chat/completions |
Любой формат, который поддерживает провайдер: wav, mp3, aiff, aac, ogg, flac, m4a, pcm16, pcm24 |
Список форматов у конкретной модели уточняйте в её документации.
Аудио на выходе
Модели с аудио-выходом возвращают озвученный ответ. Для этого в запросе к /v1/chat/completions указываются modalities и audio:
{
"model": "google/gemini-3.1-flash-lite",
"messages": [{ "role": "user", "content": "Расскажи короткую сказку." }],
"modalities": ["text", "audio"],
"audio": { "voice": "alloy", "format": "pcm16" },
"stream": true
}
| Опция | Описание |
|---|---|
voice |
Голос: например, alloy, echo, fable, onyx, nova, shimmer; набор зависит от модели |
format |
Формат аудио: например, wav, mp3, flac, opus, pcm16; набор зависит от модели |
Аудио-выход требует потоковой передачи (stream: true). Данные и транскрипт приходят по мере генерации:
{
"choices": [
{
"delta": {
"audio": {
"data": "<base64-encoded audio chunk>",
"transcript": "Hello"
}
}
}
]
}
Фрагменты delta.audio.data — самостоятельные base64-блоки. Декодируйте каждый и складывайте байты: после завершения стрима получится целый аудиофайл.
Видео
Модели с поддержкой видео принимают ролики для пересказа, поиска моментов, распознавания объектов и действий. Видео передаётся только через API.
Видео по ссылке (Responses API)
В Responses API video_url — строка со ссылкой или data URL.
curl https://api.ru-openrouter.ru/v1/responses \
-H "Authorization: Bearer sk_ваш_api_ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemini-3.1-flash-lite",
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Что происходит в этом видео? Опиши сцены по порядку." },
{ "type": "input_video", "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
]
}
],
"max_output_tokens": 1000
}'
Видео в base64 (Chat Completions)
В Chat Completions video_url — объект с полем url.
import base64
import requests
with open("clip.mp4", "rb") as f:
video_b64 = base64.b64encode(f.read()).decode()
payload = {
"model": "google/gemini-3.1-flash-lite",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Опиши, что происходит в видео."},
{
"type": "video_url",
"video_url": {"url": f"data:video/mp4;base64,{video_b64}"},
},
],
}
],
"max_tokens": 1000,
}
response = requests.post(
"https://api.ru-openrouter.ru/v1/chat/completions",
headers={
"Authorization": "Bearer sk_ваш_api_ключ",
"Content-Type": "application/json",
},
json=payload,
)
print(response.json())
Поддерживаемые форматы видео
| MIME-тип | Формат |
|---|---|
video/mp4 | MP4 |
video/mpeg | MPEG |
video/mov | MOV |
video/webm | WebM |
Режим обработки видео
Необязательное поле processing на видеочасти управляет тем, как модель просматривает ролик:
| Значение | Поведение | Когда подходит |
|---|---|---|
agentic |
Модель сама перемещается по таймлайну, подгружая нужные кадры, расшифровку и звук | Длинные видео, вопросы про конкретные моменты |
static |
Видео сэмплируется с фиксированной частотой кадров за один проход | Короткие клипы, важна скорость ответа |
Если processing не указан, значение по умолчанию определяет провайдер.
Режимы обработки — возможность Google Gemini: при выборе режима запрос направляется на эндпоинт, который его поддерживает, остальные провайдеры поле игнорируют. Подробнее о режимах и подсчёте токенов — в документации Google по video understanding.
{
"type": "input_video",
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"processing": "agentic"
}
{
"type": "video_url",
"video_url": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
"processing": "agentic"
}
Ответ при agentic-обработке
Шаги навигации по видео не возвращаются как вызовы инструментов — они приходят зашифрованными рассуждениями, а ответ завершается обычным образом:
- Responses API — шаги появляются в
outputэлементамиreasoningс полемencrypted_content. Чтобы сохранить контекст видео на следующем ходу, верните элементыoutput(включаяreasoning) обратно вinputследующего запроса. - Chat Completions API — шаги приходят зашифрованными записями
reasoning_detailsв сообщении ассистента, а ответ завершается сfinish_reason: "stop". Чтобы сохранить контекст, отправьте сообщение ассистента обратно вместе сreasoning_details.
Это тот же механизм возврата reasoning-токенов, что и в обычных запросах к reasoning-моделям.
Ссылки на видео по провайдерам
| Провайдер | Ссылки на видео |
|---|---|
| Google Gemini (AI Studio) | Только YouTube: https://www.youtube.com/watch?v=... |
| Google Gemini (Vertex AI) | Не поддерживаются — передавайте base64 |
| Остальные | Зависит от модели и провайдера |
Если ссылка не работает, самый надёжный вариант — base64 data URL.
Как выбрать модель
Возможности модели видны в GET /v1/models:
curl "https://api.ru-openrouter.ru/v1/models" \
-H "Authorization: Bearer sk_ваш_api_ключ"
| Что нужно | Признак в ответе |
|---|---|
| Понимает изображения | capabilities.can_understand_image: true |
| Понимает аудио | capabilities.can_understand_audio: true |
| Понимает видео | capabilities.can_understand_video: true |
| Генерирует изображения | capabilities.can_generate_image: true |
| Генерирует видео | capabilities.can_generate_video: true |
{
"id": "google/gemini-3.1-flash-lite",
"object": "model",
"capabilities": {
"can_understand_image": true,
"can_understand_audio": true,
"can_understand_video": true,
"output_modalities": ["text", "audio"]
}
}
Параметры ?filter=image и ?filter=video отбирают модели, которые контент генерируют. Для входа ориентируйтесь на can_understand_*.
Ограничения размера
Тело запроса ограничено 32 MB, и это общий лимит для всех эндпоинтов. Base64-кодирование увеличивает объём файла примерно на треть, поэтому крупные материалы лучше передавать ссылкой — тогда тело запроса остаётся маленьким.
{
"error": {
"message": "Request body too large (max 32MB)",
"code": "request_too_large"
}
}
Помимо общего лимита тела, у моделей и провайдеров бывают свои ограничения на размер файла, число вложений и длительность записи.
Рекомендации
Изображения
- Сжимайте картинку, если важна скорость, а не мелкие детали
- Не увеличивайте изображение перед отправкой — информации это не добавит
- Для OCR следите за разрешением, резкостью и ориентацией текста
- Несколько изображений передавайте отдельными элементами
content
- Текстовые PDF обрабатываются быстрее и точнее, чем сканы
- Для сканов и плохих копий используйте
mistral-ocr - Большие документы делите на части по смыслу
- Формулируйте задачу конкретно: «найди пункт о расторжении», а не «что тут важного»
Аудио
- Записывайте без сильного фонового шума — качество распознавания зависит от него
- Длинные записи делите на фрагменты
- Указывайте правильный
format, иначе провайдер может отклонить файл
Видео
- Сжимайте ролик и обрезайте до нужного фрагмента
- Снижайте разрешение: 720p обычно достаточно для анализа
- Уменьшайте частоту кадров, если важна не плавность, а содержание
- Уточняйте предельную длительность в документации модели и разбивайте длинные видео на части
Типовые задачи
| Модальность | Задачи |
|---|---|
| Изображения | Описание сцены, OCR, сравнение кадров, классификация, проверка качества |
| Разбор договоров, финансовые отчёты, инструкции, статьи, извлечение данных из сканов | |
| Аудио | Транскрипция, определение языка, анализ звонков и встреч, озвучка ответа |
| Видео | Суммаризация, поиск момента, распознавание объектов и действий, разбор записей камер |
Диагностика
| Симптом | Что проверить |
|---|---|
| Модель не видит вложение | Передано ли оно частью content, а не в тексте промпта |
| Модель не поддерживает модальность | can_understand_image / can_understand_audio / can_understand_video |
| Ошибка про неподдерживаемый формат | MIME-тип в data URL и реальный формат файла |
| Ссылка не принимается | Доступна ли она без авторизации и поддерживает ли провайдер ссылки для этой модальности |
| Ошибка на ссылке YouTube у Gemini | Нужна именно ссылка YouTube, а не прямой файл |
Ответ 413 request_too_large |
Сжать файл, разбить на части или перейти на ссылку |
| Документ разобран частично | Качество скана; попробуйте mistral-ocr |
| Повторный запрос снова долго разбирается | Не возвращены аннотации file из предыдущего ответа |
| Слабый результат анализа | Качество записи, освещение, конкретность промпта |
Вложение не обрабатывается
- Убедитесь, что модель принимает эту модальность на входе
- Для ссылок проверьте поддержку URL у провайдера
- Попробуйте base64 data URL вместо ссылки
- Проверьте формат файла и целостность записи
Слишком большой файл
- Сожмите материал, снизьте разрешение или длительность
- Обрежьте запись до нужного фрагмента
- Используйте ссылку вместо base64, если провайдер её поддерживает
Слабый результат
- Убедитесь, что качество записи достаточно для задачи
- Задавайте конкретные вопросы: что именно найти и где
- Проверьте, что материал соответствует возможностям модели
- Для документов и видео указывайте раздел или временной отрезок