Multimodal (мультимодальные запросы)

Передача изображений, PDF, аудио и видео моделям, которые умеют с ними работать. Базовый URL: https://api.ru-openrouter.ru/v1/

Большинство современных моделей принимает не только текст. В одном запросе можно передать картинку, документ, аудиозапись или ролик — и попросить модель описать содержимое, распознать текст, найти нужный фрагмент, сравнить материалы между собой.

Мультимодальные входы передаются двумя способами: прямой ссылкой (если материал публично доступен) или base64-данными (для локальных и приватных файлов).

  Обзор модальностей

Модальность Часть контента в /v1/responses Часть контента в /v1/chat/completions Ссылка Base64
Изображения input_image image_url Да Да
PDF 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/pngPNG
image/jpegJPEG
image/webpWebP
image/gifGIF

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

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/mp4MP4
video/mpegMPEG
video/movMOV
video/webmWebM

Режим обработки видео

Необязательное поле 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

  • Текстовые PDF обрабатываются быстрее и точнее, чем сканы
  • Для сканов и плохих копий используйте mistral-ocr
  • Большие документы делите на части по смыслу
  • Формулируйте задачу конкретно: «найди пункт о расторжении», а не «что тут важного»

Аудио

  • Записывайте без сильного фонового шума — качество распознавания зависит от него
  • Длинные записи делите на фрагменты
  • Указывайте правильный format, иначе провайдер может отклонить файл

Видео

  • Сжимайте ролик и обрезайте до нужного фрагмента
  • Снижайте разрешение: 720p обычно достаточно для анализа
  • Уменьшайте частоту кадров, если важна не плавность, а содержание
  • Уточняйте предельную длительность в документации модели и разбивайте длинные видео на части

  Типовые задачи

Модальность Задачи
Изображения Описание сцены, OCR, сравнение кадров, классификация, проверка качества
PDF Разбор договоров, финансовые отчёты, инструкции, статьи, извлечение данных из сканов
Аудио Транскрипция, определение языка, анализ звонков и встреч, озвучка ответа
Видео Суммаризация, поиск момента, распознавание объектов и действий, разбор записей камер

  Диагностика

Симптом Что проверить
Модель не видит вложение Передано ли оно частью 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, если провайдер её поддерживает

Слабый результат

  • Убедитесь, что качество записи достаточно для задачи
  • Задавайте конкретные вопросы: что именно найти и где
  • Проверьте, что материал соответствует возможностям модели
  • Для документов и видео указывайте раздел или временной отрезок