Вайб-Маркетолог Вайб-Маркетолог
Получить ключ

Agent API - Вайб-Маркетолог

Справочник API для ИИ-агентов: генерация изображений, видео, озвучки и музыки нейросетями.

API активен · обновлено 2026-08-17
Содержание ▾

Один ключ ко всем нейросетям: видео, изображения, озвучка, музыка, текст — одним POST /generate. Оплата в рублях с баланса личного кабинета. База: https://lk.vibemarketolog.ru/api/agent. Версия документа: 2026-08-13. Живой каталог моделей и цен — GET /capabilities.

Зачем через нас, а не напрямую к провайдерам

Напрямую к провайдерам Через Agent API
Доступ из России нужна зарубежная карта и обход гео-ограничений; часть провайдеров отказывает по региону работает с российского сервера как есть
Оплата отдельный валютный платёж каждому поставщику рубли с одного баланса; юрлицам — счёт и закрывающие документы
Интеграция у каждого свой формат, свои имена полей и свои лимиты один POST /generate на 56 моделей десяти провайдеров, единый формат ошибок
Цена вызова считаете сами по чужому прайсу POST /generate/estimate — точная сумма до списания, бесплатно
Сбой провайдера деньги ушли, разбираться вам возврат на баланс автоматически (поле refunded в статусе)
Результат ссылка провайдера протухает через часы файл остаётся в галерее кабинета, подписанная ссылка живёт 7 дней
Claude / ChatGPT писать своего клиента MCP-коннектор по OAuth 2.1, без единой строки кода
Отказ поставщика по оплате интеграция встала молча у части моделей есть резервный канал, разница в цене возвращается

Валютный контроль, договоры с зарубежными поставщиками и карта — не ваша забота: платёжный контур закрыт на нашей стороне.

Первый запрос за 3 минуты

  1. Аккаунтhttps://lk.vibemarketolog.ru, подтвердите адрес почты (без подтверждения платные вызовы отклоняются).
  2. Баланс — пополнение от 100 ₽ в кабинете. Юрлицам доступен счёт и закрывающие документы.
  3. Ключ — страница /#agent → раздел «API-ключи» → создать. Ключ и webhook_secret показываются один раз, сохраните сразу.
  4. Проверка ключа (бесплатно) — покажет права, лимиты и остаток:
curl -s -H "Authorization: Bearer $TOKEN" https://lk.vibemarketolog.ru/api/agent/me
  1. Смета (бесплатно, ничего не списывает) — то же тело, что у /generate:
curl -s -X POST https://lk.vibemarketolog.ru/api/agent/generate/estimate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"image","model":"z-image","prompt":"логотип кофейни на белом фоне","strict":true}'
  1. Генерация — тот же запрос на /generate: вернётся generation_id, дальше опрашивайте GET /generation/{id}/status до stage: "complete" и берите display_url.

Полный список моделей и их параметров всегда в GET /capabilities — на него и опирайтесь в коде, а не на этот документ.

Условия, лимиты и документы


Содержание


Аутентификация

Все запросы требуют Bearer-токен:

Authorization: Bearer <ваш_api_token>

Получить ключ: страница https://lk.vibemarketolog.ru/#agent → раздел «API-ключи». Ключ виден ОДИН раз при создании — сохраните его сразу. На сервере хранится только SHA-256 хеш. Вместе с ключом при создании выдаётся webhook_secret (тоже показывается один раз) — им подписываются вебхуки (см. «Верификация подписи»). Доступа к API он не даёт: нужен только чтобы проверить, что вебхук на ваш callback_url отправили мы.

Если секрет не сохранён или ключ выпущен раньше — перевыпустите секрет, не трогая ключ: в разделе «API-ключи» у нужного ключа нажмите кнопку с круговой стрелкой («Перевыпустить секрет подписи вебхуков»). Новый секрет показывается один раз; прежний перестаёт действовать сразу, а сам API-ключ и все интеграции продолжают работать. Тем же способом переводятся на выделенный секрет ключи, созданные до 2026-07-09 (они работают на легаси-схеме подписи).

Проверка ключа

curl -s -H "Authorization: Bearer $TOKEN" \
  https://lk.vibemarketolog.ru/api/agent/me

Ответ содержит права ключа (scopes), лимиты, остатки, статус Яндекс OAuth. Перед платными вызовами используйте бесплатную смету POST /generate/estimate (цена и valid без списания), а всю историю списаний — GET /usage.


MCP: подключение в Claude и ChatGPT

Платформа работает как MCP-сервер (Model Context Protocol): Streamable HTTP, JSON-RPC 2.0, версия протокола 2025-06-18. Её можно подключить к claude.ai, ChatGPT или любому MCP-клиенту и генерировать контент без написания кода.

Два эндпоинта

Эндпоинт Авторизация Для кого
POST https://lk.vibemarketolog.ru/mcp OAuth 2.1 (автоматический флоу) или Bearer oc_... Коннекторы claude.ai / ChatGPT и MCP-клиенты с поддержкой OAuth
POST https://lk.vibemarketolog.ru/api/mcp Bearer oc_... из ЛК (/#agent); открытые тулзы — без auth Самописные агенты; работает без изменений

Ключи oc_... принимаются на обоих эндпоинтах.

9 MCP-тулзов

Тулза Что делает Auth
list_capabilities Каталог моделей и цен открытая
get_prices Прайс по моделям открытая
search Поиск по каталогу моделей — открыто; по своим генерациям — с токеном. Формат ChatGPT Deep Research: results[] с id/title/url открытая / read
fetch Карточка модели model:<ключ> — открыто; генерация generation:<id> — с токеном открытая / read
get_balance Текущий баланс read
list_generations История генераций (limit ≤ 20) read
get_generation_status Статус и результат генерации read
estimate_generation Смета БЕЗ списания (бесплатно) read
generate_content Запуск генерации — СПИСЫВАЕТ рубли; обязателен idempotency_key для безопасных ретраев (поддержан и на REST /generate: повтор с тем же ключом и ТЕМ ЖЕ телом вернёт ответ той же формы с replayed: true без нового списания; тот же ключ с другим телом — 409 idempotency_key_conflict; параллельный дубль — 409 duplicate_request); вернёт status=processing + generation_id generate

OAuth 2.1-флоу (для /mcp)

Запрос без токена получает 401 с заголовком WWW-Authenticate, где указана resource-метадата /.well-known/oauth-protected-resource/mcp. Дальше клиент (claude.ai / ChatGPT) выполняет флоу сам:

  1. Dynamic Client Registration (RFC 7591) — POST /oauth/register;
  2. PKCE S256GET /oauth/authorize → consent-экран → POST /oauth/token;
  3. Refresh rotation — refresh-токен ротируется при каждом обновлении.

Метадата authorization-сервера: /.well-known/oauth-authorization-server. Скоупы OAuth: read, generate.

Биллинг: списания идут с рублёвого баланса владельца аккаунта; дневной лимит по умолчанию — 500 ₽/день на подключение (меняется в ЛК). Отзыв доступа: ЛК → вкладка «ИИ Агент» → «Подключённые приложения» → «Отозвать».

Подключение в Claude (claude.ai)

  1. Откройте claude.ai → SettingsConnectors;
  2. Нажмите Add (вверху справа) → Add custom connector;
  3. Вставьте URL https://lk.vibemarketolog.ru/mcp;
  4. Нажмите Connect;
  5. Войдите в Вайб-Маркетолог;
  6. Нажмите «Разрешить доступ» на consent-экране;
  7. Готово — тулзы доступны в чате.

Доступно на всех тарифах claude.ai (Free — 1 коннектор). В каталоге коннекторов Anthropic нас нет — подключение только по URL.

Подключение в ChatGPT

Settings → Apps & ConnectorsDeveloper mode (тарифы Plus/Pro/Business) → добавить коннектор по URL https://lk.vibemarketolog.ru/mcp, аутентификация — OAuth. Deep Research использует тулзы search/fetch.

Поллинг и результат

Генерация асинхронная: после generate_content опрашивайте get_generation_status каждые 10–15 секунд (image ~30–90 сек, video — до 30 минут). Готовый результат — поле display_url: подписанная ссылка вида https://lk.vibemarketolog.ru/files/generation/{id}?expires=…&signature=…, работает БЕЗ логина 7 дней (при каждом опросе статуса выдаётся свежая; файл навсегда остаётся в галерее ЛК). file_url — та же генерация в ЛК под сессией. result_url/result_urls при наличии локальной копии тоже указывают на подписанные ссылки нашего домена; срок действия ссылок продублирован явным полем expires_at (ISO 8601). URL апстрим-провайдеров в ответах API не отдаются.


Лимиты и скоупы

Scope Что разрешено Throttle
read Все GET-эндпоинты: каталог моделей и цен, баланс, история генераций, статусы, каталог голосов 120 req/min
generate POST /generate, POST /generate/estimate, POST /upload-media 30 req/min
write Изменение объектов аккаунта: бренды и продукты Brand Voice 10 req/min

🔒 Права выдаются явно (fail-closed). Каждый метод API привязан к своему праву, и ключ получает доступ только к тем методам, права на которые ему выданы. Ключ без прав не может ничего: пустой список больше не означает полный доступ. Новый ключ по умолчанию создаётся с read и generate; остальные права владелец аккаунта выдаёт осознанно на странице ключа. Если метод потребовал права, которого нет, приходит 403 insufficient_scope с полями required (какое право нужно) и granted (какие есть).

🔒 Least privilege для Яндекса. Сырой OAuth-токен (со всеми правами, что владелец выдал на экране согласия — вплоть до почты и Диска) отдаётся только под scope yandex. Ключу с одним read доступны безопасные операции чтения, но не сами доступы к внешним сервисам.

Дневной лимит трат (daily_spend_limit) настраивается на странице токена. Когда лимит достигнут — 429 daily_spend_limit_exceeded. Лимит занимается атомарно, поэтому параллельные запросы его не обходят.

Ограничение по IP (allowed_ips) действует на всех каналах доступа сразу: REST, MCP и проверка ключа.

Все обращения к API — включая неудачные попытки авторизации — фиксируются в журнале с отметкой времени; владелец аккаунта видит их в кабинете, поддержка — по request_id из ответа об ошибке.


Endpoint reference

Метод URL Описание
GET /me Информация о токене, балансы, Yandex OAuth
GET /balance Текущий баланс пользователя
GET /prices Полный прайс по моделям. price_semantics объявляет, что означает цена каждого источника (в prices — минимум/база, в /capabilities — дефолт-конфигурация, точная сумма — только смета). Разделы: per_second (посекундные ставки с формулой), per_1000_chars (посимвольная озвучка — списание за начатую 1000 знаков; флэт-числа в prices лишь фолбэк), non_generation_tools (платные инструменты вне /generate: direct/, campaigns/, voice/validate), hidden_non_generation_key_names (имена тарифных ключей других подсистем)
GET /capabilities Самоописывающийся каталог: все модели + их параметры + лимиты
GET /health Status check + последние ошибки
GET /generations История генераций; каждый элемент содержит display_url — подписанную ссылку на файл, работает без логина 7 дней (nullable)
POST /generate Запуск генерации (любого типа). strict=true — отклонять несовместимые поля до списания. type=text отвечает синхронно, оплата по фактическим токенам
POST /generate/estimate Dry-run: валидация + цена тела /generate БЕЗ списания (free)
POST /webhook-test Отправить подписанное тестовое событие на ваш callback_url (free)
POST /upload-media Загрузка файла (image / video / audio)
GET /generation/{id}/status Статус + результаты + error_message + cost + refunded
POST /safety-check Pre-action risk assessment (бесплатно)
GET /voices Каталог голосов ElevenLabs (97 голосов, фильтры: ?gender=female&category=professional&search=calm)
POST /voice/validate Suno Voice: загрузка аудио для клонирования голоса (50₽)
GET /voice/validate-info Suno Voice: получить верификационную фразу (polling, бесплатно)
POST /voice/generate Suno Voice: отправить запись фразы (бесплатно)
GET /voice/status Suno Voice: статус создания голоса → voice_id (polling, бесплатно)
POST /voice/regenerate Suno Voice: перегенерация истёкшей фразы (бесплатно)
GET /voice/list Suno Voice: список ваших кастомных голосов (бесплатно)

Совет: перед интеграцией сделайте GET /capabilities — там лежит полная JSON-схема всех моделей и их параметров.


Генерация: общая модель

POST /generate

Универсальная точка входа: одинаковый формат для всех типов (image/text/video/voice/music).

⚠️ type: "text" работает иначе остальных: он синхронный и тарифицируется по фактическим токенам. Ответ приходит в том же запросе (никакого поллинга), а деньги списываются не фикс-ценой, а по реальному расходу — см. раздел «Текстовые модели». Все остальные типы — асинхронные, с generation_id и опросом статуса.

Базовые поля:

Поле Тип Обяз. Описание
type string да image | text | video | voice | music
model string да Конкретная модель (см. GET /capabilities)
prompt string да Описание (до 20000 символов)
callback_url string нет URL для webhook-доставки результата (см. ниже)

Остальные параметры — модель-специфичные (см. далее).

Ответ

{
  "status": "processing",
  "generation_id": 5811,
  "task_id": "task_xxx",
  "cost": 196,
  "balance_after": 4504.0
}

generation_id сохраните — по нему опрашиваете статус.

GET /generation/{id}/status

{
  "status": "complete",           // pending | processing | complete | error
  "stage": "complete",            // ЕДИНОЕ поле состояния async-задачи на всех эндпоинтах (generation, voice/status, voiceover/long) — опрашивайте именно его
  "generation_id": 5811,
  "task_id": "task_xxx",
  "model": "grok-itv",
  "type": "video",
  "result_url": "https://...",    // временный URL провайдера — ПРОТУХАЕТ
  "result_urls": ["https://...", "..."],
  "display_url": "https://lk.vibemarketolog.ru/files/generation/5811?expires=…&signature=…", // подписанная, без логина, 7 дней
  "file_url": "https://lk.vibemarketolog.ru/newuser/file/5811",    // та же генерация в ЛК (нужен вход)
  "thumbnail": "https://...",
  "title": null,
  "duration": "10s",
  "cost": 196.0,
  "price_rub": 196.0,             // каноническое поле цены (то же значение, есть во всех ответах — используйте его для предохранителя бюджета)
  "error_message": null,
  "refunded": false,
  "created_at": "2026-05-11T01:50:34+00:00",
  "updated_at": "2026-05-11T01:54:12+00:00"
}

При ошибке error_message содержит человекочитаемую причину; refunded=true означает что деньги уже вернулись на баланс.

Пользователю показывайте display_url — подписанную ссылку, работающую без логина 7 дней (nullable: null, пока файл не сохранён локально; при новом опросе статуса выдаётся свежая). file_url — файл в ЛК под сессией, хранится бессрочно. result_url — временный URL провайдера, протухает; использовать не рекомендуется.


Видео-модели — параметры и примеры

⚠️ image-to-video: правильное поле под модель

Самая частая ошибка агентов — слать image_input для видео. image_input существует только для type: image (nano-banana / gpt-image / seedream). Видео-модели его не читают → вы получите чистый text-to-video, а деньги спишутся. Используйте поле из таблицы:

Модель (type: video) Как подать исходную картинку
veo3_fast / veo3.1 / veo3 image_urls: ["..."] + generation_type: "image-to-video"
kling-3.0-std / kling-3.0-pro image_urls: ["..."]
seedance-2 / seedance-2-fast / seedance-2-mini first_frame_url: "..." (опц. last_frame_url), либо reference_image_urls: ["..."]
minimax-h3 reference_image_urls: ["..."] + h3_mode: "image" (1-я картинка — первый кадр, 2-я — последний)
pixverse-v6 image_urls: ["..."] (ровно 1 шт., pv_mode: "image"); переход между кадрами — first_frame_image_url + last_frame_image_url; сцена по референсам — image_references: [...]
grok-itv image_urls: ["..."] (ровно 1 шт., Grok 1.5) — цена считается по duration автоматически
motion-control-720p/1080p character_image_url + reference_video_url
omnihuman-1-5 image_url: "..." + audio_url: "..." (оживление фото — не image_urls!)
volcengine-lipsync video_url: "..." + audio_url: "..." (пересинхрон губ готового видео)

Не уверены, какое поле принимает модель? Сделайте GET /capabilities (required/optional по каждой модели) или POST /generate/estimate с strict=true — он покажет rejected поля без списания.

Grok Imagine 1.5 — TTV / ITV (xAI)

Единый движок grok-imagine-video-1-5-preview. Обе модели: duration 1–15 сек, resolution 480p/720p, параметра mode нет (контент-фильтр включён по умолчанию). Самый доступный способ сделать видео.

# Текст → видео, 10 секунд
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "grok-ttv",
    "prompt": "cinematic shot of a fox jumping in autumn forest, golden hour",
    "duration": 10,
    "resolution": "720p",
    "aspect_ratio": "16:9"
  }'

# Картинка → видео (image-to-video, до 15 сек)
# Шаг 1 — загружаем картинку
curl -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@hero.png"
# → { "url": "https://lk.vibemarketolog.ru/uploads/agent/123/2026-05-11/.../hero.png" }

# Шаг 2 — запускаем grok-itv с image_urls (ровно 1)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "grok-itv",
    "prompt": "camera slowly zooms into product, light flicker",
    "image_urls": ["https://lk.vibemarketolog.ru/uploads/agent/..."],
    "duration": 10,
    "resolution": "720p",
    "aspect_ratio": "16:9"
  }'

Цена по длительности: зовите имена grok-ttv / grok-itv — ступень тарифа выбирается по duration автоматически (≤6 с, 7–10 с, 11–15 с), вы платите ровно за свою длительность. Точная сумма до списания — POST /generate/estimate; границы ступеней — tier_bounds в /capabilities. Имена с числовым суффиксом (grok-ttv-10 и подобные) оставлены только для совместимости со старыми интеграциями и в новых не используются: они берут фиксированную цену ступени независимо от длительности. Форматы (aspect_ratio): auto, 1:1, 16:9, 9:16, 3:2, 2:3. Расширение / апскейл: grok-extend (ref_task_id, extend_at, extend_times), grok-upscale (ref_task_id).

Veo 3.x (Google)

Кинематографическое качество, до 8 сек, нативный звук, до 1080p.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "veo3_fast",
    "prompt": "morning fog rolling over a mountain lake, drone shot",
    "aspect_ratio": "16:9",
    "duration": 8,
    "resolution": "720p",
    "generate_audio": true
  }'

# Image-to-video режим:
# Передайте image_urls + generation_type=image-to-video

Seedance 2.5 (ByteDance) — флагман семейства, посекундно

Старший тир Seedance, сменивший Seedance 2.0 в кабинете (17-08-2026). Ролик до 30 секунд одним куском, до 1080p, нативный AI-звук, до 9 reference images, до 3 reference videos / audio, first_frame_url / last_frame_url для image-to-video, aspect_ratio ещё и adaptive, output_formatmp4 или mov. Модель: seedance-2-5.

Цена — посекундная: 480p 20 ₽/сек, 720p 45 ₽/сек, 1080p 82 ₽/сек. Без duration и resolution заказывается минимальный ролик — 4 секунды в 720p (180 ₽).

⚠️ Видео-референс меняет ФОРМУЛУ, а не даёт скидку. С reference_video_urls действует пониженная ставка (480p 13, 720p 28, 1080p 49 ₽/сек), но она умножается на сумму секунд исходника и результата: (input + output) × rate. Длинный исходник делает короткий ролик дороже, чем генерация вообще без референса. Референсные видео обязаны быть загружены через POST /api/agent/upload-media — их длительность мы измеряем сами, суммарно не больше 30 секунд. Точная сумма до списания — POST /generate/estimate.

Все ставки машиночитаемо: GET /capabilities → поля per_second_by_resolution и per_second_by_resolution_with_video_input.

# Ролик 10 секунд в 720p (450 ₽)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2-5",
    "prompt": "stylish young woman walking through neon-lit Tokyo street at night, slow motion",
    "aspect_ratio": "9:16",
    "duration": 10,
    "resolution": "720p",
    "generate_audio": true
  }'

# Image-to-video через first_frame_url
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2-5",
    "prompt": "the model starts walking towards the camera, smiles",
    "first_frame_url": "https://lk.vibemarketolog.ru/uploads/agent/...",
    "duration": 6,
    "resolution": "1080p",
    "aspect_ratio": "9:16"
  }'

Русская озвучка (NEW). Передайте voiceover_text — русскую реплику диктора, и ролик придёт с закадровым голосом. Собственное русское произношение модели ненадёжно (она искажает слова), поэтому сцена генерируется без говорящих героев, а речь синтезирует наш TTS и подмешивает поверх звука сцены.

Цена — отдельным слоем: 13 ₽ за каждую начатую тысячу знаков сверх стоимости видео. Если синтез не удастся, стоимость слоя вернётся на баланс, а ролик придёт без голоса — за снятое видео деньги не теряются.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2-5",
    "prompt": "Cozy coffee shop, steam rising over a cup, warm morning light, slow push-in",
    "duration": 10,
    "resolution": "720p",
    "aspect_ratio": "9:16",
    "voiceover_text": "Свежая обжарка каждое утро. Заходите на чашку.",
    "voiceover_voice": "Leda"
  }'

Ограничения: prompt до 30000 знаков, duration 4–30 с, max 9 reference images, max 3 reference videos (суммарно ≤30 с), max 3 reference audio. first_frame_url/last_frame_url и reference_image_urls — взаимоисключающие сценарии, отправляйте что-то одно.

Seedance 2.0 / Fast (ByteDance) — снята с витрины

Убрана из интерфейса кабинета 17-08-2026 в пользу Seedance 2.5, но продолжает работать по API для уже интегрированных агентов. Cinematic-видео, 4-15 сек, до 9 reference images, до 3 reference videos / audio, first_frame_url и last_frame_url для image-to-video. Для новых интеграций берите seedance-2-5: она дешевле на коротких роликах и умеет до 30 секунд.

# Text-to-video, 9:16 для рилсов, Quality 1080p
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2",
    "prompt": "stylish young woman walking through neon-lit Tokyo street at night, slow motion",
    "aspect_ratio": "9:16",
    "duration": 8,
    "resolution": "1080p",
    "generate_audio": true
  }'

# Image-to-video через first_frame_url
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2-fast",
    "prompt": "the model starts walking towards the camera, smiles",
    "first_frame_url": "https://lk.vibemarketolog.ru/uploads/agent/...",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "9:16"
  }'

# С референсами (стиль / звук / движение)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2",
    "prompt": "...",
    "reference_image_urls": ["https://.../ref1.png", "https://.../ref2.png"],
    "reference_audio_urls": ["https://.../voice.mp3"],
    "duration": 10
  }'

Ограничения: prompt до 20000 chars, duration 4-15с, max 9 reference images, max 3 reference videos (общая длина ≤15с), max 3 reference audio (общая длина ≤15с).

Seedance 2 Mini (ByteDance)

Бюджетный тир Seedance с посекундной оплатой — самый дешёвый способ получить видео от ByteDance. Те же функции, что у Seedance 2.0 (референсы фото/видео/аудио, AI-звук, веб-поиск, first/last frame), но resolution только 480p/720p (без 1080p). duration 4–15с. Модель: seedance-2-mini.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "seedance-2-mini",
    "prompt": "first-person kitchen baking vlog, hands only, warm morning light",
    "aspect_ratio": "16:9",
    "duration": 8,
    "resolution": "720p",
    "generate_audio": true
  }'

Форматы: 16:9, 4:3, 1:1, 3:4, 9:16, 21:9. Остальные лимиты — как у Seedance 2.0.

MiniMax H3 (Hailuo 03) — 2K со встроенным звуком

Флагман MiniMax: видео 2560×1440 со встроенной стереодорожкой — звук генерируется вместе с картинкой в одном проходе, отдельная озвучка не нужна. Длительность 4–15 с, prompt до 7000 знаков. Модель: minimax-h3.

Биллинг: per-second, 37 ₽/сек. Полная формула провайдера:

цена = 37 ₽ × (длительность результата + длительность ВХОДНОГО видео) + 11 ₽ × (изображений сверх 5)

Аудио-референсы бесплатны. Точную сумму до списания всегда отдаёт POST /generate/estimate.

Три режима — параметр h3_mode:

h3_mode Что делает Что требует
text (по умолчанию) видео целиком по описанию prompt + aspect_ratio
image оживление опорных кадров: 1-я картинка — начало, 2-я — финал reference_image_urls (1–2). aspect_ratio игнорируется — пропорции берутся из кадра
reference мультимодальная сборка: камера с одного источника, герой со второго, голос из третьего минимум одно из reference_image_urls / reference_video_urls

Режим определяется по фактическому составу входов, а не только по слову клиента: если прислать видео или аудио, запрос уйдёт как reference, даже когда в h3_mode указан text — присланные файлы не выбрасываются молча.

# Режим reference: движение камеры из видео, персонаж из фото, голос из аудио
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "minimax-h3",
    "h3_mode": "reference",
    "prompt": "Возьми движение камеры из Видео 1, персонажа из Изображения 2, голос из Аудио 3",
    "reference_video_urls": ["https://lk.vibemarketolog.ru/uploads/agent/.../camera.mp4"],
    "reference_image_urls": ["https://lk.vibemarketolog.ru/uploads/agent/.../hero.jpg"],
    "reference_audio_urls": ["https://lk.vibemarketolog.ru/uploads/agent/.../voice.mp3"],
    "duration": 10,
    "aspect_ratio": "16:9"
  }'

Форматы: 21:9, 16:9, 4:3, 1:1, 3:4, 9:16, а в режиме reference ещё и adaptive (пропорции исходника).

Ограничения и подводные камни:

PixVerse V6 — пять режимов и самый дешёвый тариф каталога

Секунда видео от 4 ₽ — самая доступная видео-модель API. Звук генерируется вместе с картинкой (generate_audio: true), длительность 3–15 с, prompt до 5000 знаков, разрешение 360p / 540p / 720p / 1080p. Модель: pixverse-v6.

Биллинг: per-second, тариф — пара «разрешение + звук»:

Разрешение Без звука Со звуком
360p 4 ₽/сек 6 ₽/сек
540p 6 ₽/сек 8 ₽/сек
720p 8 ₽/сек 10 ₽/сек
1080p 15 ₽/сек 19 ₽/сек

Цена = тариф × duration. Режим на цену не влияет: extend оплачивает только запрошенные секунды продолжения, а не длину исходника. Точную сумму до списания отдаёт POST /generate/estimate.

Пять режимов — параметр pv_mode:

pv_mode Что делает Что требует
text (по умолчанию) ролик целиком по описанию prompt + aspect_ratio
image оживление одного фото image_urlsровно 1 шт. (второе изображение провайдер примет только с template_id)
transition готовый переход между двумя кадрами first_frame_image_url + last_frame_image_url
reference сцена по референсам с именами image_references — 1–7 ссылок
extend продление готового ролика video_url или parent_task_id своей завершённой генерации pixverse-v6

pv_mode можно не указывать — режим выводится из фактического состава входов. aspect_ratio (16:9, 4:3, 1:1, 3:4, 9:16, 2:3, 3:2, 21:9) применяется только в text и reference: в остальных режимах пропорции берутся из исходника.

# Сцена по референсам: имена Image1…Image7 присваиваются автоматически по порядку
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "pixverse-v6",
    "pv_mode": "reference",
    "prompt": "Персонаж с @Image1 берёт товар с @Image2 и улыбается в камеру",
    "image_references": [
      "https://lk.vibemarketolog.ru/uploads/agent/.../hero.jpg",
      "https://lk.vibemarketolog.ru/uploads/agent/.../product.jpg"
    ],
    "duration": 8,
    "resolution": "720p",
    "generate_audio": true,
    "aspect_ratio": "9:16"
  }'

Ограничения и подводные камни:

Kling 3.0 Motion Control

Перенос движений с reference-видео на загруженного персонажа (танцы / жесты / мимика). Сохраняет черты лица и идентичность героя из фото.

Биллинг: per-second. Цена = ceil(video_duration) × per_sec ₽, где video_duration ограничен 3–30 секундами.

Ограничения:

# Шаг 1 — загружаем фото персонажа
IMG_URL=$(curl -s -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@character.png" | jq -r .url)

# Шаг 2 — загружаем reference-видео с движением (бэкенд ffprobe вернёт duration)
RESP=$(curl -s -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@dance_reference.mp4")
VID_URL=$(echo "$RESP" | jq -r .url)
DUR=$(echo "$RESP" | jq -r .duration)   # например 13.23

# Шаг 3 — запускаем (по умолчанию orient=video — переносит позу/повороты из видео)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d "{
    \"type\": \"video\",
    \"model\": \"motion-control-720p\",
    \"character_image_url\": \"$IMG_URL\",
    \"reference_video_url\": \"$VID_URL\",
    \"character_orientation\": \"video\",
    \"video_duration\": $DUR,
    \"prompt\": \"smooth dance moves, cinematic lighting\"
  }"

Параметры:

Поле Тип Обязат. Описание
character_image_url url Фото персонажа (whose face/identity to use)
reference_video_url url Видео-донор движений
character_orientation enum video (default, до 30s видео) или image (до 10s видео)
video_duration float Длительность видео в секундах. Если не передан — backend сам через ffprobe выяснит. Влияет на биллинг
prompt string Текстовая подсказка, до 2500 chars
model enum motion-control-720p или motion-control-1080p

Что НЕ передавать: поле background_source (input_video/input_image) — Оператор (Kling 3.0 prod-прокси) его игнорирует, удалено из API ещё в мае 2026.

Kling 3.0 (std / pro)

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "kling-3.0-pro",
    "prompt": "...",
    "aspect_ratio": "16:9",
    "image_urls": ["https://.../start.png"],
    "duration": 5,
    "sound": true
  }'

VEED Avatar

Говорящая голова из текста.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "veed-avatar",
    "avatar_id": "anna_pro",
    "script": "Привет! Расскажу про новинку нашего магазина.",
    "language": "ru",
    "prompt": "AI avatar speech"
  }'

TopView URL-to-Video

Вставка URL продукта → AI создаёт рекламный ролик.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "video",
    "model": "topview-url-video",
    "source_url": "https://example.com/product",
    "video_length": 30,
    "language": "ru",
    "prompt": "promo video"
  }'

Особенность: превью-фаза бесплатна. HD-рендер оплачивается отдельно при подтверждении.


Текстовые модели (type=text)

Добавлено 29-07-2026. Синхронная генерация текста флагманскими моделями. Оплата — по фактическим токенам, а не фикс-ценой за вызов: у текста нет заранее известного «размера ответа».

Чем отличается от остальных типов:

Медиа (image/video/voice/music) Текст (type: "text")
Ответ status: processing + generation_id, дальше поллинг status: complete + готовый text сразу
Цена фикс по прайсу модели по фактическим токенам, минимум 2 ₽ за вызов
Списание сразу вся цена резерв по max_tokens → пересчёт → возврат разницы в том же ответе

Модели и ставки (живой список с ценами — GET /capabilitiestext_models):

Модель Вход, ₽/1M токенов Выход, ₽/1M Контекст Потолок ответа
claude-opus-5 1500 7500 200 000 8192
gpt-5.6-sol 1500 9000 400 000 8192

Ориентир: промпт на 1000 токенов с ответом на 300 токенов — около 3.75 ₽ (Opus 5) и 4.2 ₽ (Sol).

Поля запроса:

Поле Тип Обяз. Описание
prompt string да Задание модели (до 200 000 знаков; реальный потолок ставит оценка входных токенов)
system string нет Системная инструкция — роль, тон, формат ответа
max_tokens int нет Потолок ответа. От него считается резерв, поэтому не завышайте без нужды
effort string нет low | medium | high | xhigh | max — глубина работы модели
thinking bool нет Размышления. По умолчанию false: они считаются по ставке вывода и заметно удорожают простые задачи
curl -s -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "text",
    "model": "claude-opus-5",
    "system": "Ты копирайтер. Пиши по-русски, без эмодзи.",
    "prompt": "Пост для телеграм-канала кофейни про сезонный напиток, 2 абзаца.",
    "max_tokens": 1500
  }'

Ответ:

{
  "status": "complete",
  "generation_id": 26118,
  "type": "text",
  "model": "claude-opus-5",
  "text": "Осень пришла в наше меню: встречайте тыквенный латте…",
  "stop_reason": "end_turn",
  "usage": { "input": 69, "output": 289, "cache_read": 0, "cache_write": 0 },
  "cost": 2.28,
  "reserved": 11.48,
  "refunded": 9.2,
  "balance_after": 5977.25
}

Как читать деньги в ответе: reserved — сколько заняли на время работы, cost — сколько реально списали, refunded — сколько вернули на баланс в этом же вызове. Дневной лимит ключа расходуется на cost, а не на reserved.

Смета до списания (бесплатно): POST /generate/estimate с type: "text" возвращает reserve_rub (верхняя граница), estimated_input_tokens, ставки rub_per_1m и предупреждения — например, что промпт длиннее лимита или что резерв не проходит по дневному лимиту ключа.

Что нужно знать:


Изображения / звук / музыка

Изображения

# Z-Image (быстрая)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"image","model":"z-image","prompt":"cyberpunk warrior, neon","aspect_ratio":"1:1"}'

# Nano Banana Pro 2K с правкой существующего изображения
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "model": "nano-banana-pro-2k",
    "prompt": "remove the watermark, brighten",
    "image_input": "https://lk.vibemarketolog.ru/uploads/agent/...",
    "aspect_ratio": "16:9"
  }'

# Nano Banana 2 Lite (Gemini 3.1 Flash Lite) — быстро и дёшево, txt2img + img2img
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "model": "nano-banana-2-lite",
    "prompt": "add a cheerful hat to the character, keep everything else",
    "image_input": "https://lk.vibemarketolog.ru/uploads/agent/...",
    "aspect_ratio": "1:1"
  }'
# ⚠️ Lite поддерживает aspect_ratio только 1:1 / 2:3 / 3:2 / 3:4 / 4:3 / 4:5 / 5:4 / auto
#    (16:9, 9:16, 21:9 автоматически маппятся на ближайший). image_input до 10 шт.

# SeeDream 5 Pro (ByteDance) — фотореализм до 2K, точный текст на картинке
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "model": "seedream-5-pro",
    "prompt": "рекламный баннер салона красоты, крупный текст «САЛОН КРАСОТЫ»",
    "aspect_ratio": "1:1",
    "quality": "high",
    "output_format": "png"
  }'
# quality: basic=1K (дешевле) / high=2K. output_format: png|jpeg.

# SeeDream 5 Pro Edit — image-to-image по 1–10 референсам
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "model": "seedream-5-pro-edit",
    "prompt": "объедини товар и фон в один премиальный баннер",
    "image_input": ["https://lk.vibemarketolog.ru/uploads/agent/...", "https://lk.vibemarketolog.ru/uploads/agent/..."],
    "quality": "high"
  }'
# image_input: 1–10 стабильных URL (POST /api/agent/upload-media).

# Qwen Image 3.0 (Alibaba) — 2K по цене 1K, ровный текст на картинке
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "model": "qwen-image-3",
    "prompt": "витрина кофейни, меловая доска с надписью «КОФЕ 149 ₽», тёплый свет",
    "aspect_ratio": "16:9",
    "resolution": "2K",
    "output_format": "png",
    "negative_prompt": "водяные знаки, лишние надписи",
    "seed": 12345,
    "prompt_extend": true
  }'
# ⚠️ prompt ≤ 800 символов — длиннее отклоняется ДО списания.
# resolution 1K|2K стоит одинаково → берите 2K. prompt_extend=true (по умолчанию):
# модель сама разворачивает короткое описание. seed: 0..2147483647, один и тот же
# сид даёт близкие кадры (серия в одном стиле). Старшая версия — qwen-image-3-pro.

# Qwen Image 3.0 Edit — редактирование по 1–10 картинкам (или qwen-image-3-pro-edit)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "model": "qwen-image-3-pro-edit",
    "prompt": "замени содержимое постера на витрине, остальное не трогай",
    "image_input": ["https://lk.vibemarketolog.ru/uploads/agent/..."],
    "resolution": "2K"
  }'

# GPT Image 2 / Grok Image — аналогично

Музыка (Suno V5 / V5.5)

Модели: suno-v5 (89₽), suno-v5-instrumental (89₽), suno-v5.5 (99₽, улучшенное качество), suno-v5.5-instrumental (99₽).

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "music",
    "model": "suno-v5.5",
    "prompt": "energetic upbeat pop song about freedom",
    "lyrics": "Verse 1: ...\nChorus: ...",
    "music_style": "pop",
    "style_tags": "upbeat, energetic",
    "vocal_gender": "f",
    "persona_id": "OPTIONAL_CUSTOM_VOICE_ID"
  }'

persona_id — кастомный голос, созданный через POST /voice/validate workflow (см. раздел «Клонирование голоса»).

Gemini Omni — видео + персонаж + голос (Google, движок Veo 3) 🆕

Связанная экосистема: создайте кастомный голос, привяжите его к персонажу, затем подставьте персонажа в видео (character_ids). Голос звучит через персонажа. Русская озвучка по умолчанию.

gemini-omni-video (type: video) — text/image/video-to-video с нативным синхронным звуком. Цена по разрешению: 720p — от 149₽, 1080p — от 299₽, 4K — от 590₽.

Параметр Описание
prompt ✅ описание ролика
image_urls до 7 фото → image-to-video (стабильные URL, POST /upload-media)
video_list [{"url":"...","start":0,"ends":8}]video-to-video (1 клип ≤100MB, ≤30с; ends-start ≤10с; при видео длительность определяет модель)
character_ids до 3 персонажей из gemini-omni-character (персонаж несёт свой голос)
duration 4 / 6 / 8 / 10
aspect_ratio 16:9 / 9:16
resolution 720p / 1080p / 4k
lang ru (по умолч., русская озвучка) или off
seed число (опц.)

⚠️ Фильтр безопасности Google отклоняет (HTTP 400 PUBLIC_ERROR_UNSAFE_GENERATION) сцены риска — люди на высоте, трюки, оружие, реальные знаменитости. Это касается и текста, и загруженных image_urls/video_list/character_ids: если заблокировано с вложением — причина чаще в самом видео/фото, а не в тексте. Средства автоматически возвращаются.

🎙️ Голос в видео — ТОЛЬКО через персонажа. Не передавайте audio_ids напрямую в gemini-omni-video — Оператор отклоняет это content-policy фильтром («flagged ... violating content policies») для любого голоса. Правильно: создайте персонажа с голосом (gemini-omni-character + audio_ids), затем передайте его character_ids в видео — персонаж говорит этим голосом. Без своего голоса модель озвучивает сама на русском (lang:"ru").

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type":"video","model":"gemini-omni-video",
    "prompt":"Кот-маркетолог презентует AI-платформу, неоновая студия",
    "duration":8,"aspect_ratio":"16:9","resolution":"1080p","lang":"ru",
    "character_ids":["CHAR_ID_FROM_OMNI_CHARACTER"]
  }'

gemini-omni-character (type: image, 49₽) — консистентный персонаж из 1 фото + описания. audio_ids (из gemini-omni-audio) привязывает голос к персонажу. Возвращает изображение; result_object.characterIdGET /generation/{id}/status) → используйте в видео character_ids.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"image","model":"gemini-omni-character","prompt":"Дружелюбный кот-маскот, фиолетовый неон","image_urls":["https://.../photo.jpg"],"character_name":"ВайбКот","audio_ids":["AUDIO_ID_FROM_OMNI_AUDIO"]}'

gemini-omni-audio (type: voice, 39₽) — кастомный голос-ассет. prompt = название, audio_id = базовый тембр (30 пресетов: achernar, puck, kore, fenrir, sulafat…). НЕ возвращает аудиофайл — только result_object.audioId → передайте его в gemini-omni-character (audio_ids), а персонажа уже в видео (character_ids).

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"voice","model":"gemini-omni-audio","prompt":"Голос бренда","audio_id":"puck","voice_description":"энергичный молодой мужской голос"}'

Рабочий процесс (голос → персонаж → видео): 1) создать голос (gemini-omni-audio) → audioId; 2) создать персонажа (gemini-omni-character + audio_ids:[audioId]) → characterId (персонаж несёт голос); 3) видео (gemini-omni-video) с character_ids:[characterId]. ⚠️ audio_ids напрямую в видео НЕ передавать — блокируется.

Оживить и Озвучить — Omnihuman 1.5 + Lip-Sync 🆕

Два способа: оживить фото (фото говорит/поёт под аудио) и переозвучить видео (пересинхрон губ под новое аудио). Обе модели — посекундная оплата: списывается ceil(длительность) × тариф (минимум 3 сек). Длительность определяется сервером автоматически по загруженным файлам.

omnihuman-1-5 (type: video) — фото + аудио → видео, где субъект (человек/питомец/аниме) говорит/поёт с точным лип-синком. Длина видео = длине аудио. Тариф: 720p — 32₽/сек, 1080p — 42₽/сек.

Параметр Описание
image_url ✅ портрет ≤10MB (jpeg/png/webp), любое соотношение (POST /upload-media)
audio_url ✅ вокал ≤10MB, <60с (рекомендуется ≤15с)
prompt описание манеры/мимики (опц., ≤1000)
resolution 720 / 1080 (по умолч. 1080)
mask_url маски субъектов от omnihuman-1-5/human-identification — для группового фото (кто именно говорит)
pe_fast_mode true — быстрее за счёт качества
anim_seed число для воспроизводимости (-1 = случайный)
IMG=$(curl -s -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@portrait.jpg" | jq -r .url)
AUD=$(curl -s -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@voice.mp3" | jq -r .url)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d "{\"type\":\"video\",\"model\":\"omnihuman-1-5\",\"image_url\":\"$IMG\",\"audio_url\":\"$AUD\",\"resolution\":\"1080\",\"prompt\":\"уверенно поёт в микрофон, естественная мимика\"}"

omnihuman-1-5/human-identification (type: video, бесплатно) — служебная детекция субъектов на фото. Возвращает result_object.subject_status (1 — чёткий герой распознан, 0 — лучше взять фото крупным планом). Используйте перед omnihuman-1-5 как проверку пригодности фото; для групповых фото маски подставляются в omnihuman-1-5.mask_url.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d "{\"type\":\"video\",\"model\":\"omnihuman-1-5/human-identification\",\"image_url\":\"$IMG\"}"
# затем GET /generation/{id}/status → result_object.subject_status

volcengine-lipsync (type: video) — готовое видео + новое аудио → пересинхрон губ. Оплата по max(длина видео, длина аудио). Тариф: Lite — 10₽/сек, Basic — 14₽/сек.

Параметр Описание
video_url ✅ видео ≤500MB (mp4/mov/mkv)
audio_url ✅ вокал ≤10MB
lipsync_mode lite (быстро) / basic (качество, поддерживает open_scenedet)
separate_vocal true — шумоподавление/выделение вокала
open_scenedet сегментация сцен и спикеров (только basic)
align_audio зацикливать видео под длинное аудио (только lite)
align_audio_reverse зацикливание «туда-обратно» (только lite, требует align_audio)
templ_start_seconds старт шаблонного видео, сек (только lite)
VID=$(curl -s -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@clip.mp4" | jq -r .url)
AUD=$(curl -s -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@new_voice.mp3" | jq -r .url)
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d "{\"type\":\"video\",\"model\":\"volcengine-lipsync\",\"video_url\":\"$VID\",\"audio_url\":\"$AUD\",\"lipsync_mode\":\"basic\",\"open_scenedet\":true}"

💡 Посекундная оплата: перед запуском оцените стоимость — длительность × тариф. Например, lip-sync Basic для 3-минутного ролика (180с) ≈ 2520₽. Точная цена возвращается в ответе generate (поле cost).

Голос (ElevenLabs — 4 модели + Google Gemini TTS — 2 модели)

Модели ElevenLabs:

Модели Google Gemini TTS (одиночная озвучка + диалоги, 30 фирменных голосов, эмоции тегами в тексте — см. раздел «Gemini TTS» ниже):

⚠️ ВАЖНО про выбор голоса. Чтобы голос отличался от стандартного, в КАЖДОМ запросе передавайте voice_id. Если его не передать — всегда звучит голос по умолчанию Rachel (женский). Поэтому, если нужен мужской/другой голос, его обязательно надо указать явно.

Как выбрать голос (рабочий процесс):

  1. Получите каталог: GET /api/agent/voices (можно с фильтром ?gender=male).
  2. Возьмите поле id нужного голоса (это либо имя вроде Roger/Brian, либо ID вроде EkK5I93UQWFDigLMpZcX).
  3. Передайте это значение в voice_id при генерации. Принимается и алиас voice — это одно и то же.

TTS (single speaker):

# Сначала подобрать мужской голос:
curl -s -H "Authorization: Bearer $TOKEN" "https://lk.vibemarketolog.ru/api/agent/voices?gender=male" | jq '.voices[].id'

# Затем озвучить им (voice_id = id из каталога):
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "voice",
    "model": "el-tts-turbo",
    "prompt": "Привет, мир! Это тестовая озвучка мужским голосом.",
    "voice_id": "Roger",
    "language_code": "ru"
  }'

voice_id — значение поля id из GET /api/agent/voices: имя голоса (Roger, Brian, Bella) или ID (EkK5I93UQWFDigLMpZcX). Без него используется дефолт Rachel. Алиас: voice.

Длинная озвучка (prompt > 5000 знаков, только el-tts-turbo):

Текст от 5001 до 200 000 знаков не отклоняется, а автоматически обрабатывается как «длинная озвучка»: нарезка на куски ~4800 знаков по границам предложений → последовательная озвучка через очередь (с контекстом соседних кусков для плавной интонации) → склейка в один mp3. Цена та же посимвольная (6₽/1000 от полного текста), списывается при старте, при ошибке возвращается автоматически.

/generate в этом случае возвращает НЕ generation_id, а проект озвучки:

{
  "status": "processing",
  "long_voiceover": true,
  "voiceover_id": 12,
  "chars": 14920,
  "chunks": 4,
  "cost": 90,
  "status_url": "https://lk.vibemarketolog.ru/api/agent/voiceover/long/12",
  "hint": "Poll status_url every 20-30 seconds..."
}

Прогресс и результат — GET /api/agent/voiceover/long/{id} (скоуп read):

curl -s -H "Authorization: Bearer $TOKEN" https://lk.vibemarketolog.ru/api/agent/voiceover/long/12
# processing: {"status":"processing","stage":"processing","chunks_done":2,"chunks_total":4,...}
# готово:     {"status":"complete","generation_id":24001,"display_url":"https://...","duration":812,...}
# ошибка:     {"status":"error","error_message":"...","refunded":true}

Ориентир по времени: ~30–60 секунд на кусок (4 куска ≈ 2–4 минуты). Поллинг каждые 20–30 секунд. idempotency_key поддерживается так же, как в обычном generate. callback_url для длинной озвучки пока не поддерживается — используйте поллинг status_url.

Multilingual TTS (расширенные настройки):

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "voice",
    "model": "el-tts-multilingual-v2",
    "prompt": "Привет! Это качественная озвучка.",
    "voice_id": "Bella",
    "stability": 0.5,
    "similarity_boost": 0.75,
    "style": 0.3,
    "speed": 1.0,
    "previous_text": "Текст перед этим абзацем для плавности",
    "next_text": "Текст после для плавности"
  }'

Диалог (мультиспикер):

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "voice",
    "model": "el-dialogue-v3",
    "prompt": "placeholder",
    "dialogue": [
      {"voice_id": "JBFqnCBsd6RMkjVDRZzb", "text": "Привет! Как дела?"},
      {"voice_id": "Xb7hH8MSUJpSbSDYk0k2", "text": "Отлично! А у тебя?"},
      {"voice_id": "JBFqnCBsd6RMkjVDRZzb", "text": "[whispers] У меня секрет..."}
    ],
    "stability": 0.5,
    "language_code": "ru"
  }'

Популярные пары: George (JBFqnCBsd6RMkjVDRZzb) ♂ + Alice (Xb7hH8MSUJpSbSDYk0k2) ♀, Rachel ♀ + Brian ♂. Stage directions: [whispers], [laughs], [яростно].

Звуковые эффекты:

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "voice",
    "model": "el-sound-fx-v2",
    "prompt": "thunder and heavy rain in a forest",
    "duration_seconds": 8,
    "prompt_influence": 0.7
  }'

Gemini TTS (Google — озвучка и диалоги)

gemini-flash-tts (13₽/1000 знаков) и gemini-pro-tts (18₽/1000 знаков) — синтез речи Google с 30 фирменными голосами, живыми интонациями и эмоциями прямо в тексте. Обе модели умеют одиночную озвучку (1 голос) и диалог (1–2 голоса). Тариф посимвольный — как у el-tts-turbo, но 13/18₽ за начатую 1000 знаков. Лимит 5000 знаков за запрос; больше — авто «длинная озвучка» (см. ниже, voiceover_id+status_url).

30 голосов: Zephyr, Puck, Charon, Kore, Fenrir, Leda, Orus, Aoede, Callirrhoe, Autonoe, Enceladus, Iapetus, Umbriel, Algieba, Despina, Erinome, Algenib, Rasalgethi, Laomedeia, Achernar, Alnilam, Schedar, Gacrux, Pulcherrima, Achird, Zubenelgenubi, Vindemiatrix, Sadachbia, Sadaltager, Sulafat. По умолчанию — Zephyr.

Параметры (все опциональны, кроме prompt):

Одиночная озвучка:

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "voice",
    "model": "gemini-flash-tts",
    "prompt": "[радостно] Привет! [шёпотом] А теперь маленький секрет.",
    "voice_name": "Zephyr",
    "style": "Deadpan",
    "temperature": 1
  }'

Диалог (1–2 голоса):

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "type": "voice",
    "model": "gemini-pro-tts",
    "prompt": "placeholder",
    "speakers": [
      {"speaker_id": "Speaker 1", "voice_name": "Puck", "style": "Newscaster"},
      {"speaker_id": "Speaker 2", "voice_name": "Kore", "style": "Deadpan"}
    ],
    "dialogue_turns": [
      {"speaker_id": "Speaker 1", "text": "[воодушевлённо] Привет! Как продвигается запуск?"},
      {"speaker_id": "Speaker 2", "text": "[спокойно] Отлично, уже почти всё готово."}
    ]
  }'

Длинная озвучка (prompt > 5000 знаков) работает и для gemini-flash-tts/gemini-pro-tts — тот же посимвольный тариф (13/18₽/1000 от полного текста), тот же ответ voiceover_id+status_url (см. «Длинная озвучка» выше). Точная смета — через POST /generate/estimate и GET /prices.

Мой голос — my-voice-tts (10₽/1000 знаков)

Озвучка текста голосом, клонированным в личном кабинете (MiniMax). Обязательные поля: prompt (текст, ≤5000 знаков) и cloned_voice_id — id вашего клонированного голоса; опционально speed (0.7–1.2). Голос обязан принадлежать владельцу API-ключа, иначе отказ «Голос не найден» с возвратом. Списание — за каждую начатую 1000 знаков (10 ₽), см. per_1000_chars в GET /prices.

Каталог голосов

# Все голоса (97 шт)
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voices"

# Фильтры
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voices?gender=female&category=professional"

# Только голоса с готовым превью (можно прослушать без генерации)
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voices?has_preview=1"

# Поиск
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voices?search=calm"

Категории: neutral, character, professional, meditation, announcer.

Превью: аудио-сэмплы голосов (preview_url / ?has_preview=1) в API пока не отдаются — характер голоса описывает поле style, а звучание на русском проверяйте по gender_ru/recommended_ru ниже.

⚠️ Голоса на русском — ВЕРИФИЦИРОВАНО (замеры F0)

Поле gender размечено по английскому звучанию и на русском часть голосов меняет пол. Мы замерили основную частоту (F0) на русском (el-tts-multilingual-v2) — /voices отдаёт по каждому голосу gender_ru (male/female/ambiguous/null — не проверялся), verified_ru (bool) и f0_ru_hz (там, где замер есть). На русском доверяй именно gender_ru.

Расхождения не единичные: у части голосов метка провайдера противоположна тому, что слышно на русском. Поимённые результаты замеров — в ответе GET /voices, поле recommended_ru (male / female / avoid) и f0_ru_hz по каждому голосу. Списки поддерживаются нами и обновляются по мере новых замеров, поэтому берите их из эндпоинта, а не переписывайте в свой код.

Правила для русского:

# Проверенные мужские голоса на русском:
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voices?language=ru&gender=male" | jq '.voices[] | {id, gender_ru, verified_ru}'

# Озвучить гарантированно мужским голосом на русском:
curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"voice","model":"el-tts-multilingual-v2","prompt":"Текст на русском.","voice_id":"Brian","similarity_boost":0.85,"stability":0.5,"style":0,"language_code":"ru"}'

Клонирование голоса (Suno Voice — 50₽)

Создание кастомного голоса для использования в музыке. Голоса имеют ограниченный срок действия.

Workflow (5 шагов):

1. POST /voice/validate    → task_id     (50₽ — списание)
2. GET  /voice/validate-info?task_id=... → validate_info (фраза для чтения)
3. Записать фразу → загрузить через POST /upload-media
4. POST /voice/generate    → task_id     (бесплатно)
5. GET  /voice/status?task_id=...        → voice_id (бесплатно)
6. Использовать voice_id как persona_id в POST /generate (type=music)

Шаг 1: Загрузка аудио-образца

curl -X POST https://lk.vibemarketolog.ru/api/agent/voice/validate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "voice_url": "https://example.com/my-voice-sample.mp3",
    "vocal_start_s": 0,
    "vocal_end_s": 15,
    "language": "ru"
  }'
# → {"status":"ok","task_id":"abc123","cost":50}

Шаг 2: Получение верификационной фразы (polling)

curl -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voice/validate-info?task_id=abc123"
# → {"stage":"success","validate_info":"Произнесите: ...","task_status":"success"}  // опрашивайте stage

Шаг 3-4: Запись и отправка

# Загрузить запись
curl -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" -F "file=@recorded-phrase.mp3"
# → {"url":"https://lk.../uploads/agent/...mp3"}

# Отправить на создание голоса
curl -X POST https://lk.vibemarketolog.ru/api/agent/voice/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"task_id":"abc123","verify_url":"https://lk.../uploads/agent/...mp3"}'

Шаг 5: Получение voice_id

curl -H "Authorization: Bearer $TOKEN" \
  "https://lk.vibemarketolog.ru/api/agent/voice/status?task_id=def456"
# → {"stage":"complete","voice_id":"persona_xyz","task_status":"complete"}  // stage — единое поле опроса

Использование в музыке:

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"music","model":"suno-v5.5","prompt":"...","persona_id":"persona_xyz"}'

Если голос истёк:

curl -X POST https://lk.vibemarketolog.ru/api/agent/voice/regenerate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"task_id":"abc123"}'
# Затем повторить шаги 2-5

Upload media

POST /upload-media

Загрузка стабильно-доступного файла. URL действует ~7 дней, хранится на нашем домене.

Лимиты:

Запрос (multipart):

curl -X POST https://lk.vibemarketolog.ru/api/agent/upload-media \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@/tmp/seed.png"

Ответ (image/audio):

{
  "status": "ok",
  "url": "https://lk.vibemarketolog.ru/uploads/agent/123/2026-05-11/1715387034_a8b2c1.png",
  "kind": "image",
  "mime": "image/png",
  "size": 482103,
  "size_mb": 0.46,
  "expires_at": "2026-05-18T01:50:34+00:00"
}

Ответ (video) — дополнительно содержит duration через ffprobe:

{
  "status": "ok",
  "url": "https://lk.vibemarketolog.ru/uploads/agent/123/2026-05-14/1715387089_b9d2e1.mp4",
  "kind": "video",
  "mime": "video/mp4",
  "size": 5177395,
  "size_mb": 4.94,
  "duration": 13.23,
  "expires_at": "2026-05-21T01:50:34+00:00"
}

Передавай duration в video_duration при POST /generate для motion-control-* — это нужно для per-second биллинга и backend-валидации лимита character_orientation=image (≤10s).

Зачем использовать этот endpoint? Внешние URL (tmpfiles.org, gist, etc.) часто блокируются или истекают раньше чем Оператор успевает скачать файл. Загрузка через /upload-media гарантирует доступность.


Webhook callback

Передайте callback_url в POST /generate — мы пришлём результат сами, как только генерация завершится. Не нужно поллить.

Когда отправляется

Доставка

Headers

Header Значение
Content-Type application/json
User-Agent VibeMarketolog-Webhook/1.0
X-Vibe-Event generation.complete | generation.error
X-Vibe-Signature HMAC-SHA256 от body (см. ниже)
X-Vibe-Token-Id ID вашего API-токена
X-Vibe-Generation generation_id
X-Vibe-Timestamp Unix-время отправки (дубль подписанного timestamp из тела)
X-Vibe-Delivery-Id Идентификатор доставки (дубль delivery_id из тела)
X-Vibe-Signature-Scheme webhook_secret | legacy_token_hash (дубль из тела)

Тело

{
  "event": "generation.complete",
  "generation_id": 5811,
  "task_id": "task_xxx",
  "type": "video",
  "model": "grok-itv",
  "status": "complete",
  "result_url": "https://...",
  "result_urls": ["https://..."],
  "cost": 196.0,
  "price_rub": 196.0,             // каноническое поле цены (то же значение, есть во всех ответах — используйте его для предохранителя бюджета)
  "error_message": null,
  "refunded": false,
  "created_at": "2026-05-11T01:50:34+00:00",
  "completed_at": "2026-05-11T01:54:12+00:00",
  "attempt": 1,
  "delivery_id": "dlv_...",          // стабильный id ДОСТАВКИ: одинаков у всех повторов одного события — ключ дедупликации
  "timestamp": 1770000000,           // unix seconds, момент отправки
  "sent_at": "2026-08-11T01:50:34+03:00",
  "signature_scheme": "webhook_secret",  // либо "legacy_token_hash" = sha256(raw_token) у ключей до 09.07.2026
  "signature_version": 1,
  "delivery_semantics": "at-least-once", // возможны повторы (tries=3, backoff 30/120/600)
  "freshness_window": 600                // рекомендованное окно свежести, секунд
}

Анти-replay поля (delivery_id/timestamp/signature_scheme и их заголовки-дубли) присутствуют в обоих контурах — генерации и agent.message. Источник истины — поля ВНУТРИ тела (оно под подписью); заголовки — удобство до разбора JSON и подделываются, сверяйте их с телом. Рекомендуемый порядок на вашей стороне:

  1. hmac_sha256(raw_body, secret) === X-Vibe-Signature — иначе отбросить;
  2. now − payload.timestamp > 600 — отбросить как устаревшее (защита от replay);
  3. дедуплицировать по payload.delivery_id — доставка at-least-once, повтор несёт тот же id (не путать с generation_id: у одной генерации бывает несколько событий).

Верификация подписи

Подпись считается так:

secret    = ваш webhook_secret        (выдан один раз при создании ключа)
signature = hmac_sha256(request_body, secret)

Легаси-токены (созданные до 2026-07-09, без выделенного webhook_secret) подписываются по старой схеме secret = sha256(your_raw_api_token). Какая схема у вашего ключа — покажет POST /webhook-test (поле secret_formula).

Не сохранили секрет или ключ старый? Кабинет → «API-ключи» → кнопка с круговой стрелкой у нужного ключа. Секрет перевыпускается отдельно от ключа доступа: агент продолжает работать, меняется только значение для проверки подписи. Показывается один раз, прежний умирает сразу — обновите его в конфиге обработчика вебхуков.

Пример Python (новая схема):

import hmac, hashlib

def verify(body_bytes: bytes, webhook_secret: str, header_signature: str) -> bool:
    expected = hmac.new(webhook_secret.encode(), body_bytes, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header_signature)

Пример Node.js (новая схема):

const crypto = require('crypto');

function verify(rawBody, webhookSecret, headerSignature) {
  if (typeof headerSignature !== 'string' || headerSignature.length === 0) return false;
  const expected = crypto.createHmac('sha256', webhookSecret).update(rawBody).digest('hex');
  const a = Buffer.from(expected, 'utf8');
  const b = Buffer.from(headerSignature, 'utf8');
  // timingSafeEqual бросает исключение при разной длине буферов — сначала сверяем длину.
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

Для легаси-ключа замените webhook_secret на sha256(raw_token) (hex).

Важно: проверяйте подпись на raw bytes тела ДО парсинга JSON.


Pre-charge validation и коды ошибок

Все URL-поля (image_urls, reference_image_urls, reference_video_urls, reference_audio_urls, first_frame_url, last_frame_url, character_image_url, reference_video_url) проверяются HEAD-запросом до списания денег. Если хоть один URL недоступен — HTTP 422, баланс не тронут.

🔒 Все передаваемые нам URL (медиа, callback_url, webhook-URL) должны указывать на публичные хосты. Ссылки на приватные, loopback и зарезервированные адреса (127.0.0.1, localhost, 10.x, 192.168.x, 169.254.x/облачная метадата, ::1 и т.п.) — а также редиректы на такие адреса — блокируются на стороне платформы.

Пример отказа

{
  "error": "media_validation_failed",
  "field": "image_urls",
  "url": "https://tmpfiles.org/dl/...",
  "reason": "unreachable",
  "detail": { "ok": false, "code": "unreachable", "http": 404 },
  "hint": "Use POST /api/agent/upload-media to upload the file and get a stable URL."
}

Единый формат ответа об ошибке

Любая ошибка публичного API приходит в одной схеме — её достаточно разобрать один раз:

{
  "status": "error",
  "error": "validation_failed",
  "message": "Поле model обязательно для заполнения. Всего ошибок в запросе: 2 — подробности в поле details.",
  "details": {
    "model": ["Поле model обязательно для заполнения."],
    "type": ["Выбранное значение для type некорректно."]
  },
  "request_id": "0f9c8b7a-2d41-4e6b-9c3a-1b5f7e2d8a04"
}
Поле Всегда есть Назначение
status да всегда error — можно ветвиться, не заглядывая в HTTP-код
error да стабильный машинный код: по нему пишется логика клиента
message да человекочитаемое объяснение на русском: что именно не так и что сделать
details нет разбор по полям (для ошибок валидации)
request_id да назовите его в обращении в поддержку — по нему находится ваш вызов в журнале

Обратная совместимость: у ошибок валидации рядом с details остаётся прежний ключ errors, у 403 insufficient_scope — прежние required и granted, у 402required/balance. Существующие интеграции ломать не нужно.

Коды ошибок

Код HTTP Описание
missing_token 401 Заголовок Authorization: Bearer … не передан
invalid_token 401 Ключ недействителен, отозван или истёк
insufficient_scope 403 У ключа нет нужного права; в required — какое именно
ip_not_allowed 403 Адрес запроса не в списке разрешённых для ключа
not_found 404 Метода нет либо объект не принадлежит владельцу ключа
method_not_allowed 405 Метод вызывается другим HTTP-глаголом
validation_failed 422 Поля запроса не прошли проверку; разбор — в details
media_validation_failed 422 URL недоступен / неверный content-type / превышен размер
invalid_url 422 Переданная ссылка ведёт на внутренний или недоступный адрес
unsupported_media_type 415 Mime не из allowed списка при /upload-media
file_too_large 413 Превышен размер при /upload-media
insufficient_balance 402 Не хватает рублей на балансе
email_confirmation_required 402 Бонусными рублями платят только с подтверждённого адреса. Подтвердите почту в кабинете; ничего не списано (charged: 0)
daily_spend_limit_exceeded 429 Дневной лимит трат ключа
rate_limit_exceeded 429 Превышена частота запросов; в retry_after — через сколько секунд повторить
already_running 429 Этот инструмент уже выполняется для вашего аккаунта
key_cooling_down 429 Ключ на паузе: почти все запросы за последние минуты завершились ошибкой. В retry_after — сколько ждать. Причина всегда одна: клиент повторяет неудачный запрос без задержки
model_not_supported 422 Название модели не распознано (обычно опечатка). Актуальный список — GET /capabilities
session_expired 419 Вы обратились к внутреннему эндпоинту кабинета, а не к публичному API. Публичные методы — только под префиксом /api/agent/*
generation_failed 502 Не удалось запустить генерацию; списание, если было, возвращено
tool_failed / ai_unavailable 502 Инструмент или модель не отработали; средства возвращены
wordstat_upstream_unavailable 503 Внешний сервис Wordstat недоступен, запросы к нему приостановлены. В retry_after — когда пробовать снова
internal_error 500 Внутренняя ошибка; повторите позже, при повторении сообщите request_id

Повторы запросов: обязательное правило

Любой ответ 429 и 503 содержит retry_after (и заголовок Retry-After) — ждите указанное время, не повторяйте раньше. Повтор без задержки приводит к key_cooling_down: если у ключа 80 % и больше ответов в пятиминутном окне — серверные сбои или отказы по лимиту (при 20+ обращениях), ключ уходит на паузу от 5 до 30 минут. Ошибки 4xx (валидация, права) на паузу не влияют — по ним можно спокойно исправлять запрос.

Рабочая схема: пауза 1 с → 2 с → 4 с → 8 с, не больше 5 попыток, затем остановка и сообщение человеку. Для долгих операций опрашивайте статус не чаще раза в 10–20 с, а лучше подпишитесь на вебхук (POST /webhook-url) и не опрашивайте вовсе.

Тексты ошибок сознательно не содержат внутренних подробностей (имён классов, таблиц, поставщиков моделей, путей файлов): для диагностики служит request_id.

При ошибке status=error через polling/webhook — error_message содержит причину, refunded=true если деньги вернулись.


Strict-mode — защита от лишних списаний

По умолчанию /generate берёт только релевантные поля, а лишние молча отбрасывает. Чтобы поймать ошибку ДО списания, передайте strict=true:

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"video","model":"veo3_fast","prompt":"...","image_input":["https://..."],"strict":true}'

Ответ HTTP 422, деньги не тронуты:

{
  "error": "unknown_or_incompatible_params",
  "model": "veo3_fast",
  "rejected": ["image_input"],
  "hint": "image_input is for type=image only. For image-to-video use: image_urls[] + generation_type=image-to-video (veo3*), ...",
  "valid_params": ["type","model","prompt","callback_url","strict","aspect_ratio","duration","resolution","image_urls","generation_type","generate_audio","negative_prompt","seed"]
}

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


Dry-run — POST /generate/estimate

Те же поля, что у /generate, но без запуска генерации и без списания. Pre-flight перед платной операцией:

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate/estimate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"video","model":"veo3_fast","prompt":"...","first_frame_url":"https://..."}'
{
  "valid": true,
  "body_valid": true,
  "funds_ok": true,
  "dry_run": true,
  "model": "veo3_fast",
  "type": "video",
  "estimated_cost_rub": 120,
  "price_rub": 120,
  "applied_tier": null,
  "balance": { "current": 1049, "after": 929 },
  "balance_after": 929,
  "daily_spend": { "limit": 5000, "today": 340, "within_limit": true },
  "validation": {
    "media": { "first_frame_url": [ { "url": "https://...", "ok": true, "code": null, "http": 200 } ] },
    "required_missing": []
  },
  "rejected": [],
  "param_rejections": [],
  "param_adjustments": [],
  "params_validated": true,
  "value_warnings": [],
  "misrouted_media": null,
  "valid_params": ["type","model","prompt","..."],
  "warnings": []
}

price_rubканоническое поле цены во всех ответах (смета, запуск /generate, статус): используйте именно его для предохранителя бюджета, оно есть везде (estimated_cost_rub/cost оставлены для совместимости). balance_after — остаток после списания, тоже единым именем во всех ответах.

body_valid / funds_ok — раздельные признаки: «тело запроса корректно» и «денег/лимита хватает». valid остаётся их конъюнкцией: по valid:false смотрите, ЧТО чинить — запрос (body_valid:false) или баланс (funds_ok:false).

applied_tier — применённая ступень тарифа для ступенчатых моделей ({key, fixed, bounds}): grok-ttv/itv по duration, gemini-omni-video по resolution, seedream-5-pro по quality. fixed:true = позван легаси-ключ с закреплённой ступенью, duration на цену не влияет. null — у модели нет ступеней. Границы ступеней публикует tier_bounds в /capabilities.

param_rejections — значения параметров, которые модель заведомо отвергнет (напр. aspect_ratio:4:5 у z-image): при непустом списке valid:false, в каждом элементе есть hint с допустимыми значениями — запрос не начинайте, замените значение. param_adjustments — значения, которые платформа молча приведёт к рабочим (напр. output_format:jpeg → png): запрос пройдёт, но результат будет в приведённом варианте.

value_warnings — значение не входит в объявленный enum модели ({field, value, allowed, note}): запрос НЕ отклоняется, но исполнитель может молча взять дефолт/дешёвую ступень («заказал 4K — получил 720p»). Сверьте с applied_tier и почините значение. params_validated:false — модели нет в каталоге, поля запроса вообще не проверялись: «valid» ≠ «параметры проверены».

misrouted_media — медиа-поле, которое эта модель НЕ принимает, и правильное поле вместо него ({field, use_instead[]}): без исправления генерация уйдёт без вашего медиа, а деньги спишутся.

Несуществующий тарифный ключ (grok-ttv-40) — valid:false в смете, а /generate ответит 422 unknown_price_tier (раньше такой ключ проходил «годным» с ценой 0 ₽).

valid:false — смотрите body_valid/funds_ok, param_rejections, warnings, rejected, validation.required_missing. Scope: read.


Приёмка результата — блок acceptance (бесплатно)

Пришлите вместе с POST /generate машинопроверяемые критерии — по готовому файлу платформа выполнит детерминированные проверки и отдаст вердикт в GET /generation/{id}/status (поле acceptance). Кто спеку не прислал — получает прежний ответ байт в байт. Вердикт информационный: статус генерации и деньги не меняет.

curl -X POST https://lk.vibemarketolog.ru/api/agent/generate \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"image","model":"z-image","prompt":"логотип на белом фоне","strict":true,
       "acceptance":{"format":"png","aspect_ratio":"1:1","aspect_ratio_tolerance":0.02,"min_width":1024,"not_blank":true}}'

Поддерживаемые проверки (только исполняемые, список — в /capabilitiesacceptance.checks): format (png/jpg/jpeg/webp/gif/mp4/mov/mp3/wav), aspect_ratio "W:H" + aspect_ratio_tolerance (относительный, дефолт 0.02; только изображения), min_width/min_height (px, только изображения), max_file_size_mb, min_file_size_kb, not_blank.

Ответ статуса (только приславшим спеку):

"acceptance": {
  "status": "partial",              // passed | partial | failed | skipped | pending (ещё не complete)
  "checks": [ {"check":"format","passed":true,"actual":"png","expected":"png"},
              {"check":"aspect_ratio","passed":false,"actual":"1024x768 (1.3333)","expected":"1:1 ±0.02"} ],
  "failed_checks": ["aspect_ratio"],
  "unsupported": [],                // ключи спеки, которые платформа исполнить не умеет — честно перечислены
  "note": "Informational verdict: it does not change the generation status or billing."
}

Проверки для видео/аудио ограничены файловыми (format, размеры файла, not_blank) — проверки кадра помечаются passed:null и в вердикт не входят.


Webhook self-test — POST /webhook-test

Проверьте свой listener и верификацию подписи без реальной генерации:

curl -X POST https://lk.vibemarketolog.ru/api/agent/webhook-test \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"callback_url":"https://your-host/webhook"}'
{
  "delivered": true,
  "http_status": 200,
  "response_time_ms": 142,
  "error": null,
  "signature_sent": "9f86d0...",
  "secret_formula": "your webhook_secret (shown once at token creation)",
  "verify": "hmac_sha256(raw_body, webhook_secret) === X-Vibe-Signature header",
  "headers_sent": ["X-Vibe-Event","X-Vibe-Signature","X-Vibe-Token-Id","X-Vibe-Generation","X-Vibe-Timestamp","X-Vibe-Delivery-Id","X-Vibe-Signature-Scheme"],
  "payload_sent": { "event": "webhook.test", "...": "..." }
}

Тестовое событие приходит с X-Vibe-Event: webhook.test. Сверьте signature_sent с тем, что вычисляет ваш код по формуле из раздела «Верификация подписи». Scope: read.


Pixel-fidelity при редактировании изображений

Edit-модели (gpt-image-2-edit, nano-banana-pro-*, nano-banana-2-*, seedream-4.5, seedream-5-pro-edit, qwen-image-3-edit, qwen-image-3-pro-edit, gpt-image-1.5) делают художественную правку и не сохраняют исходные пиксели байт-в-байт — в GET /capabilities у них стоит preserves_input: false. Для брендинга/логотипов, где нужна точность по гайдлайнам, это учитывайте: модель может слегка перерисовать логотип. Маск-инпейнт (точное сохранение вне маски) пока не поддерживается.


Входящие сообщения (Inbox) — Bitrix24 и другие каналы

Клиенты пишут вашему агенту из внешних каналов (Bitrix24, Telegram, кастомные интеграции) — платформа доставляет сообщения агенту и возвращает ответ в канал.

Тарификация: доставка сообщений и ответы ВАШЕГО агента (inbox/webhook) — бесплатны (входят в тариф). Если агент не забрал сообщение и ответил авто-ответчик платформы (reply_source=platform) — списание с баланса владельца по прайсу текстового чата (как на /text): фактическая модель, Claude Opus 4.8 — 10₽/ответ, страховочный Sonnet 4.6 — 8₽/ответ. При нехватке баланса или превышении дневного лимита ключа авто-ответчик молчит.

Как это устроено

Сотрудник пишет боту в Bitrix24
  → обработчик канала зовёт POST /agent/message (Bearer oc_ ключ клиента)
  → платформа доставляет сообщение АГЕНТУ (inbox-очередь или webhook)
  → агент отвечает → обработчик получает {reply} → клиент видит ответ в чате

Канал ждёт ответ синхронно до 22 секунд. Агент должен отвечать быстро.

Endpoints для КАНАЛА (обработчик Bitrix24 и т.п.)

Метод URL Что делает
GET /agent/list Список агентов клиента: [{"id":"agent_N","name":"...","online":true}]
POST /agent/message Сообщение агенту → {"reply":"..."} (ждёт ≤22 сек)
GET /agent/message/{id} Добор «опоздавшего» ответа после таймаута

Эти URL живут без префикса /api (точный формат интеграции Bitrix24), но требуют тот же Authorization: Bearer oc_....

# Список агентов клиента
curl -H "Authorization: Bearer oc_..." https://lk.vibemarketolog.ru/agent/list

# Отправить сообщение и получить ответ
curl -X POST https://lk.vibemarketolog.ru/agent/message \
  -H "Authorization: Bearer oc_..." -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_123",
    "text": "Сколько стоит доставка?",
    "channel": "bitrix",
    "context": {"portal": "b24-xxx.bitrix24.ru", "dialog_id": "chat42", "user_name": "Иван"}
  }'
# → 200 {"reply": "Доставка по Москве — бесплатно от 3000₽", "message_id": 17}

Таймаут (агент не успел за 22 сек):

{"reply": null, "status": "timeout", "message_id": 17,
 "message": "Агент не ответил за 22 сек. Ответ можно забрать позже: GET /agent/message/17"}

HTTP-код всегда 200 — проверяйте поле reply. Поздний ответ агента сохраняется — заберите его GET /agent/message/{id}{"status":"replied","reply":"..."}.

Идемпотентность: повторный запрос с тем же context.dialog_id + text в окне ~60 сек вернёт уже созданное сообщение (ретраи канала не плодят дубли). Для полного контроля передавайте заголовок X-Idempotency-Key.

Вложения (vision) — Bitrix24 v2

Канал может передать в POST /agent/message массив attachments (до 5; для картинок — прямые/подписанные URL, TTL ~1 час):

"attachments": [
  {"type": "image", "url": "https://b24.vibem.ru/attach/<token>.jpg", "mime": "image/jpeg", "name": "photo.jpg"},
  {"type": "file",  "url": "https://...", "name": "бриф.pdf"}
]

CRM-действия (actions) — Bitrix24 v2

Агент может вернуть рядом с reply массив actions — машинные команды Bitrix REST, которые исполняет мост (whitelist crm.* на его стороне):

POST /api/agent/inbox/{id}/reply
{
  "reply": "Создал сделку «Заявка от Ивана» на 50 000 ₽.",
  "actions": [
    {"method": "crm.deal.add", "params": {"fields": {"TITLE": "Заявка от Ивана", "OPPORTUNITY": 50000, "CATEGORY_ID": 0}}}
  ]
}

Endpoints для АГЕНТА (как получать и отвечать)

Вариант А — polling inbox (просто, рекомендуется):

Метод URL Что делает
GET /api/agent/inbox?wait=20&limit=10 Забрать новые сообщения (long-poll до 20 сек)
POST /api/agent/inbox/{id}/reply Ответить: {"reply": "текст"}
POST /api/agent/identify Представиться владельцу: {"telegram_bot","host","version","description"} — данные видны в карточке агента на /agent/
# Цикл агента: забирай и отвечай
while true; do
  MSGS=$(curl -s -H "Authorization: Bearer oc_..." \
    "https://lk.vibemarketolog.ru/api/agent/inbox?wait=20")
  # для каждого messages[].id — сформируй ответ и отправь:
  curl -s -X POST -H "Authorization: Bearer oc_..." -H "Content-Type: application/json" \
    -d '{"reply":"Ответ клиенту"}' \
    "https://lk.vibemarketolog.ru/api/agent/inbox/$ID/reply"
done

Правила inbox:

Вариант Б — push webhook (быстрее):

# Один раз: включить push-режим
curl -X POST https://lk.vibemarketolog.ru/api/agent/webhook-url \
  -H "Authorization: Bearer oc_..." -H "Content-Type: application/json" \
  -d '{"url": "https://your-host.example/hook"}'

Платформа будет слать POST с событием agent.message (подпись X-Vibe-Signature — та же схема HMAC, что у webhook callback генераций: hash_hmac('sha256', body, webhook_secret); для легаси-ключей — sha256(raw_token)). URL должен быть публичным https:// — приватные/loopback/зарезервированные адреса отклоняются. Ответьте синхронно за ≤18 сек:

200 {"reply": "текст ответа"}

Если webhook недоступен — сообщение автоматически падает в inbox (вариант А продолжает работать как fallback). Отключить: {"url": null}.

Лимиты

Endpoint Лимит
POST /agent/message 30 req/min на ключ
GET /api/agent/inbox 120 req/min на ключ (с wait=20 это ~3 req/min)
Остальные 120 req/min (read)

Интеграция с Bitrix24 (для пользователей)

  1. Установите приложение «AGI Агенты VibeMarketolog» из Bitrix24.Маркет.
  2. Создайте API-ключ oc_... на странице /agent/ и вставьте в настройки приложения.
  3. Выберите агента из списка.
  4. Сотрудники пишут боту в чате Bitrix24 — агент отвечает. История диалогов видна на странице /agent/.

Brand Voice — профиль бренда для генераций

Профиль бренда хранит тон, аудиторию, палитру, стоп-слова, фирменный голос и продукты. Передайте brand_id в /generate — и поля профиля подставятся автоматически, но только те, которые принимает схема конкретной модели (GET /capabilities): параметры из запроса всегда выигрывают, ценовые поля (quality/duration/resolution) не подставляются никогда, prompt озвучки и музыки не трогается.

Метод Что делает Scope
GET /api/agent/brands Список брендов с продуктами, активной парой и лимитами read
GET /api/agent/brand/{id} Один бренд read
POST /api/agent/brand Создать/обновить (передайте id) — бесплатно write
DELETE /api/agent/brand/{id} Удалить бренд с продуктами write
POST /api/agent/brand/{id}/product Создать/обновить продукт (type: 0 услуга, 1 товар) write
DELETE /api/agent/product/{id} Удалить продукт write
POST /api/agent/brand/activate {brand_id, product_id} — активная пара (null — выключить) write

Поля бренда: name* , industry, description, website, tagline, target_audience, tone_of_voice, avoid_words, palette (массив #RRGGBB, ≤8), voice_id (из GET /voices), voice_model, defaults ({aspect_ratio, output_format, image_model, video_model, audio_model}), reference_images (≤5 URL). Лимиты: 10 брендов / 50 продуктов на аккаунт.

Параметры генерации: brand_id (чужой → 422 brand_not_found ДО списания), product_id (продукт того же бренда), brand_apply: false — отключить инжект даже при активном бренде. Если brand_id не передан, применяется активная пара аккаунта (POST /brand/activate).

Смета бесплатна: POST /generate/estimate с brand_id возвращает applied_brand_fields[] — ровно то, что будет подставлено, без списания. Ответ /generate содержит то же поле.


FAQ для агентов

Q: Что если я закрою терминал во время генерации? A: Генерация продолжается на стороне Оператора. При возврате просто GET /generation/{id}/status — результат подтянется. Альтернатива — указать callback_url в /generate, и мы сами пришлём результат пушем.

Q: Как использовать image-to-video для Grok? A: Модель grok-itv (Grok 1.5 Preview, базовое имя — тир цены по duration) + ровно один image_urls: ["https://..."], duration 1–15. Параметра mode нет. Картинку загрузите через /upload-media.

Q: Можно ли передать ссылку на tmpfiles.org / imgur / pastebin? A: Можно, но НЕ рекомендуется — такие хосты часто блокируются или истекают. Лучше /upload-media — стабильный URL на нашем домене.

Q: Что делать если pre-charge validation сработала ложно (URL рабочий, но мы отказали)? A: Это значит ваш CDN не отдаёт HEAD-запрос или прячет Content-Type. Загрузите файл через /upload-media — это безопаснее.

Q: Webhook не пришёл — что делать? A: Проверьте логи: callback_url должен возвращать 2xx HTTP. Retry: 3 попытки с backoff 30s/120s/600s. После 3-й неудачи мы прекращаем попытки — опросите /generation/{id}/status руками.

Q: Безопасно ли отдавать API-токен агенту? A: Да, если токен с ограниченным scope (generate или read), expiry-датой и желательно IP-whitelist. Учтите: доступы к внешним сервисам отдаются только под отдельный scope yandex — не добавляйте его без необходимости. Полные права (write/autopilot/yandex) выдавайте только проверенным агентам.

Q: Где смотреть свежий список моделей? A: GET /api/agent/capabilities — самоописывающийся каталог с параметрами всех моделей.


Документ обновляется при изменениях API. Последнее обновление: 2026-07-28 (webhook_secret теперь действительно выдаётся владельцу ключа: показ при создании + отдельная кнопка перевыпуска секрета без замены ключа). Связь с поддержкой: @centrmedia.


Программное управление рекламой

Кампании Яндекс Директа, автопилот ставок, доступы к рекламным кабинетам и исследование спроса в открытую часть API не входят и предоставляются по партнёрскому соглашению — вместе с договорным SLA, выделенными лимитами запросов и приоритетной поддержкой.

Оставить заявку (имя и контакт, ответим в рабочее время): https://vibemarketolog.ru/api#lead

Или напишите напрямую: @centrmedia


<!-- CHANGELOG-START -->

Журнал обновлений

(0.000) Qwen Image 3.0 (2026-08-06): четыре новые модели изображений Alibaba — qwen-image-3 (7 ₽) и qwen-image-3-edit (7 ₽), старшие qwen-image-3-pro (14 ₽) и qwen-image-3-pro-edit (14 ₽). Разрешение 2K стоит столько же, сколько 1K — берите 2K. Сильны в ровном тексте на картинке (вывески, ценники, упаковка). Параметры: resolution (1K|2K), output_format (png|jpeg), negative_prompt (до 5000), seed (0..2147483647), prompt_extend. ⚠️ prompt800 символов — длиннее отклоняется до списания. Режим редактирования принимает 1–10 картинок в image_input. См. примеры. (0.00) PixVerse V6 (2026-08-03): новая видеомодель pixverse-v6самый дешёвый посекундный тариф каталога, от 4 ₽/сек, звук в комплекте, 3–15 с, до 1080p. Пять режимов через pv_mode: text (по описанию), image (оживление одного фото), transition (переход между first_frame_image_url и last_frame_image_url), reference (сцена по 1–7 фото с именами @Image1@Image7) и extend (продление своего готового ролика по video_url или parent_task_id). Тариф — пара «разрешение + звук»: 360p 4/6 ₽/сек, 1080p 15/19 ₽/сек. См. раздел «PixVerse V6». (0.0) MiniMax H3 (2026-08-02): новая видеомодель minimax-h3 (Hailuo 03) — 2K со встроенным стереозвуком, 4–15 с, 37 ₽/сек. Три режима в одной модели через h3_mode: text (по описанию), image (опорные кадры) и reference (мультимодальные референсы: до 9 изображений + до 3 видео + до 3 аудио одним запросом). ⚠️ Провайдер тарифицирует длительность входного видео наравне с результатом, а изображения сверх пятых — по 11 ₽; видео-референс принимается ТОЛЬКО загруженный через POST /upload-media (длительность чужой ссылки измерить нельзя, такой запрос отклоняется до списания). См. раздел «MiniMax H3». (0.1) Gemini TTS (2026-07-19): две новые голосовые модели Google — gemini-flash-tts (Gemini 3.1 Flash TTS, ПОСИМВОЛЬНО 13₽/1000 знаков) и gemini-pro-tts (Gemini 2.5 Pro TTS, 18₽/1000 знаков): одиночная озвучка И диалоги (1–2 голоса), 30 фирменных голосов Google, эмоции inline-тегами [радостно]…[шёпотом], стили Deadpan/Whisper/Newscaster, temperature; лимит 5000 знаков → больше авто «длинная озвучка» (см. раздел «Gemini TTS»). (0) Озвучка (2026-07-16): el-tts-turbo теперь тарифицируется ПОСИМВОЛЬНО — 6₽ за каждую начатую 1000 знаков (флет 29₽ отменён); одиночный запрос — до 5000 знаков; длинная озвучка: prompt от 5001 до 200 000 знаков автоматически нарезается на куски ~4800, озвучивается и склеивается в один mp3 — /generate вернёт voiceover_id + status_url (GET /voiceover/long/{id}) вместо generation_id. (1) Новые модели: seedance-2-mini (бюджетный Seedance, посекундно, все функции) и nano-banana-2-lite (Gemini 3.1 Flash Lite Image — txt2img + img2img по референсу). (2) Grok Imagine 1.5 — теперь ОБА grok-ttv и grok-itv на движке grok-imagine-video-1-5-preview: duration 1–15 сек, без mode (контент-фильтр включён). (3) «Оживить и Озвучить»: omnihuman-1-5, volcengine-lipsync, omnihuman-1-5/human-identification — посекундная оплата. (4) SeeDream 5 Pro (2026-07-14): seedream-5-pro (text-to-image) и seedream-5-pro-edit (image-to-image, до 10 референсов) — фотореализм до 2K, точный текст на изображении; параметры quality (basic=1K / high=2K) и output_format (png/jpeg).