<!-- /docs/video-api (ru) -->

# Видео API: 10 модулей

REST-контракты операций Alibaba Video, HEYGEN AGENT, MARS, MOON, MiniMax, OMNI, SATURN, VECTOR, VENUS и X. Контракты сверены с исходниками 8 сентября 2026 года; доступ и стоимость зависят от аккаунта и выбранной операции.

## Подключение и общий цикл

Базовый адрес: `https://apergrex.ru/franklab/api`. Все таблицы ниже показывают полный путь. Передавайте собственный ключ FrankLab в `X-API-Key`, для HEYGEN — в `Authorization: Bearer`. Ключ не вставляйте в URL. Make-лейблы и селекторы выбирают ветку запроса, но не всегда являются полями REST.

```bash
export FRANKLAB_BASE_URL="https://apergrex.ru/franklab/api"
# FRANKLAB_KEY is supplied securely by your environment.
```

Сначала проверьте доступность и оценку для конкретной модели. POST генерации может резервировать Франки; единица F — внутренняя учётная единица. Сохраните ID из ответа, затем опрашивайте именно указанный маршрут. HTTP 200, queued/processing и наличие ID не означают готовность. Для успеха нужны терминальный статус и URL результата. 400 — проверьте поля, 401/403 — доступ, 404 — маршрут или ID, 409 — конфликт, 429 — ограничение частоты. Читайте также прикладной code/success и тело ошибки. После таймаута не создавайте новую платную задачу вслепую. Неподтверждённый возврат не считайте состоявшимся.

Пометка required означает обязательность поля выбранной REST-ветки; дополнительные условные требования описаны рядом. Поля пути и query отмечены явно. Не отправляйте все объединённые поля таблицы одновременно.

## Модули

- [FrankLab Alibaba Video](#franklab-alibaba-video)
- [FrankLab HEYGEN AGENT](#franklab-heygen-agent)
- [FrankLab MARS](#franklab-mars)
- [FrankLab MOON](#franklab-moon)
- [FrankLab MiniMax](#franklab-minimax)
- [FrankLab OMNI](#franklab-omni)
- [FrankLab SATURN](#franklab-saturn)
- [FrankLab VECTOR](#franklab-vector)
- [FrankLab VENUS](#franklab-venus)
- [FrankLab X](#franklab-x)

## FrankLab Alibaba Video

**Ограничение на 8 сентября 2026:** проверка HappyHorse 1.1 в `480P` выявила ошибку завершения `lifecycle_conflict`: задача принимается, но результат и окончательный расчёт не выдаются. Пока не используйте `480P`. Если задача уже создана, сохраните ID и обратитесь в поддержку; повторный POST создаст новую задачу.

HappyHorse 1.1 создаёт видео по тексту или первому кадру. В REST обычно не передают `model`: Make-лейбл `happyhorse-1.1` не является значением REST. Для WAN передайте `model:"wan3.0-video"`. Make-селекторы `wan_t2v`, `wan_i2v`, `wan_r2v`, `wan_edit`, `wan_extend`, `wan_file`, `wan_link` соответствуют семи REST-операциям в таблице; `hh10_edit` — это `video_edit` с `model:"happyhorse-1.0-video-edit"`.

REST не принимает `wan3.0-video-prime`, хотя этот вариант есть в Make. HappyHorse 1.1 принимает `480P`/`720P`/`1080P`; HappyHorse 1.0 edit — 720P/1080P. Перед отправкой проверьте доступ к выбранной операции, особенно WAN edit/extend/file/link и HappyHorse edit.

Дескриптор изображения: `{storedFileId,url,mimeType,width,height,sizeBytes}` собственного файла. Видео WAN: `{storedFileId,url,mimeType:"video/mp4",sizeBytes}`. Видео HappyHorse edit дополнительно требует измеренные `width,height,durationSeconds,fps`, допустимы MP4/MOV. Документ требует собственные ID/URL, допустимый MIME и размер; необязательный `pageCount` не больше 50. Не выдумывайте ID или размеры. `/franklab/jobs/upload` возвращает только URL, поэтому одного ответа загрузки недостаточно для полного дескриптора Alibaba — это отдельное условие интеграции.

В WAN references поле `media:[{type:"reference_image",url:ownedURL}]` принимает до 10 изображений. REST DTO также содержит `referenceVideos` и `referenceAudios` с метаданными; текущая Make communication эти массивы не отправляет. `referenceVideo` — другое поле: редактируемый клип. Автодлительность WAN `-1` резервирует объём для 30 секунд.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `happyhorse_text_to_video` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `happyhorse_image_to_video` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_t2v` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_i2v` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_r2v` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_edit` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_extend` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_file` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `wan_link` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `hh10_edit` | POST | `/franklab/api/make/alibaba/videos` | Нужны медиа согласно модели/операции ниже и действующий допуск. Значение Make wan3.0-video-prime текущий DTO отклоняет. |
| `poll_status` | GET | `/franklab/api/make/alibaba/status/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `estimate` | POST | `/franklab/api/make/alibaba/estimate` | Только оценка, без резерва и вызова провайдера. При HTTP 200 прикладной code может означать ошибку. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | POST | `/franklab/api/make/alibaba/estimate` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. Тело media=image; проверка отклоняет только 401/403 и не оценивает стоимость видео. {"media": "image"} |

### Параметры REST

`happyhorse_text_to_video`, `happyhorse_image_to_video`, `wan_t2v`, `wan_i2v`, `wan_r2v`, `wan_edit`, `wan_extend`, `wan_file`, `wan_link`, `hh10_edit`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `operation` | string | да | text_to_video/image_to_video/reference_to_video/video_edit/video_extend/file_to_video/link_to_video. |
| `model` | string | условно / нет | Для HappyHorse 1.1 можно не передавать; для других семейств wan3.0-video или happyhorse-1.0-video-edit. |
| `prompt` | string | да | Непустое значение, до 5000 кодовых точек в сервисе. |
| `resolution` | string | да | 480P/720P/1080P в верхнем регистре; HappyHorse 1.1 принимает все три, HappyHorse 1.0 edit — только 720P/1080P. |
| `durationSeconds` | integer | да | HappyHorse 3–15; WAN 2–30 либо -1 (авто с резервом для 30 секунд). |
| `ratio` | string | условно / нет | Обязательно для HappyHorse по тексту; adaptive — только для разрешённых сочетаний модели/операции. |
| `seed` | integer | условно / нет | Неотрицательное зерно генерации. |
| `audio` | boolean | условно / нет | Звук WAN. |
| `prompt_extend` | boolean | условно / нет | Расширение промпта WAN. |
| `watermark` | boolean | условно / нет | Водяной знак. |
| `firstFrame` | object | условно / нет | Дескриптор собственного изображения для image_to_video. |
| `lastFrame` | object | условно / нет | Необязательный последний кадр WAN image_to_video. |
| `media` | array | условно / нет | WAN reference images: [{type:reference_image,url:ownedURL}]. |
| `referenceVideo` | object | условно / нет | Дескриптор собственного видео для WAN edit/extend. |
| `file` | object | условно / нет | Дескриптор собственного документа для file_to_video. |
| `link` | string | условно / нет | Публичная HTTPS-страница для link_to_video; взаимоисключается с file. |
| `video` | object | условно / нет | Дескриптор видео для HappyHorse edit. |
| `referenceImages` | array | условно / нет | Дескрипторы изображений HappyHorse edit, до 5. |
| `audioSetting` | string | условно / нет | HappyHorse edit: auto/origin. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`estimate`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `media` | string | да | video. |
| `operation` | string | да | Та же операция, что при создании. |
| `model` | string | условно / нет | Та же модель, что при создании. |
| `resolution` | string | да | То же разрешение, что при создании. |
| `durationSeconds` | integer | да | Та же длительность, что при создании. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Формат code/msg/data. Создание: data.taskId, status=queued. Опрос: queued/processing/completed/failed/error. Готовое видео — data.videoUrl. final_cost_franks, refunded_cost_franks и cost_status описывают расчёт.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/alibaba/videos" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"operation":"text_to_video","prompt":"A blue paper cube rotates on a white background.","resolution":"720P","durationSeconds":3,"ratio":"16:9"}'
```

Оценка: `POST /franklab/api/make/alibaba/estimate`. Для Alibaba добавьте media=video и передайте только поля схемы estimate.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/alibaba/status/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab HEYGEN AGENT

Авторизация — партнёрский guard; в REST используйте Bearer с ключом FrankLab. Для `partner_heygen` нужен ID ранее сохранённого аккаунта этого же партнёра. При создании, опросе, чтении ресурсов и RPC сохраняйте тот же режим аккаунта и credential ID. Основной пример использует FrankLab и не содержит секрет провайдера.

Поля Make `avatarId`, `voiceId`, `styleId`, `brandKitId`, `callbackUrl`, `callbackId`, `incognitoMode` преобразуются в REST snake_case ниже. `filesJson` становится настоящим JSON-массивом `files`. Пагинация: `limit` и `token`, в ответе возможны `hasMore` и `nextToken`. Для аватара нужен ID конкретного look, а не группы.

Для `generate_from_prompt` создайте сессию с `mode:"generate"`, опрашивайте сессию до появления video ID, затем `/v1/heygen/videos/{videoId}` до успешного видео с URL. Ошибка, остановка и отмена терминальны; пустой URL не означает готовность. После таймаута или `submission_unknown` сначала сверяйте существующие записи сессии/задачи, не повторяйте POST вслепую. Сообщение сессии может запустить новую генерацию и не считается бесплатным чтением. Stop не является возвратом; биллинг собственного и FrankLab-аккаунта различается.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `generate_from_prompt` | POST | `/franklab/api/v1/heygen/video-agents` | Make generate_from_prompt объединяет создание, опрос сессии и опрос видео; это не маршрут /generate. |
| `create_session` | POST | `/franklab/api/v1/heygen/video-agents` | Make generate_from_prompt объединяет создание, опрос сессии и опрос видео; это не маршрут /generate. |
| `list_sessions` | GET | `/franklab/api/v1/heygen/video-agents` |  |
| `list_styles` | GET | `/franklab/api/v1/heygen/video-agents/styles` |  |
| `get_session` | GET | `/franklab/api/v1/heygen/video-agents/{sessionId}` |  |
| `get_resource` | GET | `/franklab/api/v1/heygen/video-agents/{sessionId}/resources/{resourceId}` |  |
| `list_videos` | GET | `/franklab/api/v1/heygen/video-agents/{sessionId}/videos` |  |
| `get_video` | GET | `/franklab/api/v1/heygen/videos/{videoId}` |  |
| `send_message` | POST | `/franklab/api/v1/heygen/video-agents/{sessionId}/messages` |  |
| `stop_session` | POST | `/franklab/api/v1/heygen/video-agents/{sessionId}/stop` | Остановка изменяет состояние и сама по себе не доказывает возврат. |
| `save_heygen_credential` | POST | `/franklab/api/v1/heygen/credentials` | Настройка аккаунта — отдельная операция с секретом. Не включайте ключ провайдера в запросы генерации или публичные примеры. |
| `getHeygenCredentials` | GET | `/franklab/api/v1/heygen/credentials` | Вспомогательный Make RPC; имя RPC-функции не входит в REST URL. |
| `getHeygenVideoAgentStyles` | GET | `/franklab/api/v1/heygen/video-agents/styles` | Вспомогательный Make RPC; имя RPC-функции не входит в REST URL. |
| `getHeygenAgentAvatarLooks` | GET | `/franklab/api/v1/heygen/avatars/looks` | Вспомогательный Make RPC; имя RPC-функции не входит в REST URL. |
| `getHeygenVoices` | GET | `/franklab/api/v1/heygen/voices` | Вспомогательный Make RPC; имя RPC-функции не входит в REST URL. |
| `getHeygenBrandKits` | GET | `/franklab/api/v1/heygen/brand/kits` | Вспомогательный Make RPC; имя RPC-функции не входит в REST URL. |
| `getHeygenVideoAgentSessions` | GET | `/franklab/api/v1/heygen/video-agents` | Вспомогательный Make RPC; имя RPC-функции не входит в REST URL. |
| `connection_probe` | GET | `/franklab/api/v1/heygen/credentials` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {} |

### Параметры REST

`generate_from_prompt`, `create_session`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `prompt` | string | да | 1–10000 символов. |
| `mode` | string | условно / нет | generate либо chat. |
| `avatar_id` | string | условно / нет | ID конкретного вида аватара (look). |
| `voice_id` | string | условно / нет | ID голоса. |
| `style_id` | string | условно / нет | ID стиля. |
| `brand_kit_id` | string | условно / нет | ID бренд-кита. |
| `orientation` | string | условно / нет | landscape/portrait. |
| `files` | array | условно / нет | Массив до 20 файлов; не строка с сериализованным JSON. |
| `callback_url` | string | условно / нет | URL callback. |
| `callback_id` | string | условно / нет | ID корреляции callback со стороны клиента. |
| `incognito_mode` | boolean | условно / нет | Признак приватной сессии. |

`list_sessions`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `limit` | integer | условно / нет | 1–100. |
| `token` | string | условно / нет | Токен пагинации. |

`list_styles`, `getHeygenVideoAgentStyles`, `getHeygenBrandKits`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |

`get_session`, `list_videos`, `stop_session`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `sessionId` | string | да | ID сессии в пути. |

`get_resource`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `sessionId` | string | да | ID сессии в пути. |
| `resourceId` | string | да | ID ресурса в пути. |

`get_video`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `videoId` | string | да | ID видео в пути. |

`send_message`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `sessionId` | string | да | ID сессии в пути. |
| `message` | string | да | 1–10000 символов. |

`save_heygen_credential`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `label` | string | да | Отображаемое название. |
| `apiKey` | secret | да | Ключ собственного HeyGen; передавайте только в хранилище учётных данных. |

`getHeygenAgentAvatarLooks`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `ownership` | string | условно / нет | private для собственного аккаунта партнёра. |
| `limit` | integer | условно / нет | 50 в Make. |

`getHeygenVoices`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `type` | string | условно / нет | private для собственного аккаунта партнёра. |
| `limit` | integer | условно / нет | 100 в Make. |

`getHeygenVideoAgentSessions`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `providerAccountMode` | string | условно / нет | franklab (по умолчанию) либо partner_heygen. |
| `providerCredentialId` | string | условно / нет | Обязательно для partner_heygen; только ID сохранённого аккаунта. |
| `limit` | integer | условно / нет | 50 в Make. |

### Ответ и завершение

Формат success=true,data,meta. ID сессии и видео различаются. В сессии: data.sessionId/videoId/status/providerStatus; готовое видео читайте через отдельный endpoint в data.video, videoUrl/downloadUrl. Ошибки: failureCode/failureMessage. Наличие сессии не означает готовность результата.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/heygen/video-agents" \
  -H "Authorization: Bearer $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"providerAccountMode":"franklab","prompt":"Create a short video of a blue paper cube rotating on a white background.","mode":"generate"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/heygen/video-agents/$SESSION_ID" \
  -H "Authorization: Bearer $FRANKLAB_KEY"
```


## FrankLab MARS

Для текста/изображения используется `model_name:"mars-v1-5"`, 3–15 секунд, `mode:"std"|"pro"|"4k"`. Тип входа задаёт маршрут: Make `mode:"text2video"` нельзя передавать в REST как качество. Для изображения обязателен `image` либо `image_list`. Текст не принимает элементы. Для изображения доступны до трёх элементов, совместное использование с голосами отклоняется. Мультисцены задаются через `multi_shot`, `shot_type`, `multi_prompt:[{index,prompt,duration}]`.

Эффекты требуют точный `effect` и сцену, например `effect_scene:"single_character",effect:"zoom_out",image:ownedURL`; для двух персонажей нужен `image_tail`. Полный список значений сохранён в машинном контракте. Перенос траектории использует API VECTOR с преобразованием старых Make-алиасов. Опрос ведите по соответствующему семейству маршрутов, сохраняйте весь массив `task_result.videos`, при ошибке читайте `task_status_msg`.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `text2video` | POST | `/franklab/api/v1/videos/text2video` | Make quality_mode → REST mode; Make задаёт model_name=mars-v1-5. |
| `poll_status` | GET | `/franklab/api/v1/videos/text2video/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `image2video` | POST | `/franklab/api/v1/videos/image2video` | Make quality_mode → REST mode; Make задаёт model_name=mars-v1-5. |
| `poll_status` | GET | `/franklab/api/v1/videos/image2video/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `effects` | POST | `/franklab/api/v1/videos/effects` | Make effect_name → REST effect. Полный каталог эффектов по сценам сохранён в selectorValues машинного контракта. |
| `poll_status` | GET | `/franklab/api/v1/videos/effects/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `trajectory_transfer` | POST | `/franklab/api/v1/videos/motion-control` | Совместимый алиас motion_control использует тот же маршрут. Make video → video_url; image → image и image_url; anchor_source → character_orientation. |
| `poll_status` | GET | `/franklab/api/v1/videos/motion-control/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `getAllKusoks` | GET | `/franklab/api/make/kusok/elements` | Вспомогательный RPC: элементы в data.result, голоса в data. |
| `getElementVoices` | GET | `/franklab/api/v1/elements/voices` | Вспомогательный RPC: элементы в data.result, голоса в data. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/v1/videos/text2video` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {"pageNum": 1, "pageSize": 1} |

### Параметры REST

`text2video`, `image2video`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `prompt` | string | условно / нет | Описание сцены. |
| `duration` | integer | да | Длительность клипа 3–15 секунд. |
| `model_name` | string | условно / нет | Публичный алиас модели. |
| `mode` | string | условно / нет | Режим качества. |
| `aspect_ratio` | string | условно / нет | Соотношение сторон результата. |
| `callback_url` | string | условно / нет | Необязательный HTTPS callback. |
| `external_task_id` | string | условно / нет | ID корреляции клиента, не ID провайдера. |
| `negative_prompt` | string | условно / нет | Не больше 2500 символов. |
| `cfg_scale` | number | условно / нет | Коэффициент следования промпту. |
| `sound` | boolean | условно / нет | Нативный звук; Make on/off преобразуется в boolean. |
| `multi_shot` | boolean | условно / нет | Включить несколько сцен. |
| `shot_type` | string | условно / нет | customize/intelligence. |
| `multi_prompt` | array | условно / нет | [{index,prompt,duration}], длительность сцены — положительное целое. |
| `voice_list` | array | условно / нет | [{voice_id}]. |
| `image` | string | условно / нет | URL первого кадра для image2video. |
| `image_tail` | string | условно / нет | URL последнего кадра. |
| `image_list` | array | условно / нет | [{image_url,type?}]. |
| `element_list` | array | условно / нет | [{element_id}], до 3 для mars-v1-5 image2video; нельзя вместе с voice_list. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`effects`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `effect_scene` | string | да | single_character/dual_character. |
| `effect` | string | да | Точный код эффекта из списка значений. |
| `image` | string | да | HTTPS URL входного изображения. |
| `image_tail` | string | условно / нет | Второе изображение обязательно для сцены с двумя персонажами. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | ID корреляции. |

`trajectory_transfer`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `image` | string | да | URL опорного изображения либо допустимый base64. |
| `image_file_data` | string | условно / нет | Альтернативные данные файла в base64/native. |
| `image_file_name` | string | условно / нет | Имя файла для native-данных. |
| `video` | string | да | Публичный URL референс-видео. |
| `character_orientation` | string | да | image/video. |
| `mode` | string | условно / нет | std/pro. |
| `generation_profile` | string | условно / нет | auto/studio/cinema. |
| `keep_original_sound` | string | условно / нет | yes/no. |
| `prompt` | string | условно / нет | Не больше 2500 символов. |
| `duration` | string | да | Обязательная строка: секунды 3–30, при ориентации image не больше 10. Должно соответствовать референс-клипу. |
| `element_list` | array | условно / нет | [{element_id}]. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | Не больше 100 символов. |

`getAllKusoks`, `getElementVoices`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `pageNum` | integer | условно / нет | Нумерация с 1. |
| `pageSize` | integer | условно / нет | Make запрашивает 500. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Proxy-формат: code=0 (некоторые маршруты также используют 200), data.task_id. Опрашивайте data.task_status; успешный task_result.videos[] содержит url/id/duration. При ошибке читайте task_status_msg. Поле final_cost_franks интерпретируется вместе с cost_status/cost_unit; reserved не является окончательным расчётом.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/text2video" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"model_name":"mars-v1-5","prompt":"A blue paper cube rotates on a white background.","duration":3,"mode":"std","aspect_ratio":"16:9"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/text2video/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab MOON

В Make `moon_fast` предлагает 480p/720p; `moon_base` добавляет 1080p/4k; `moon_pro` — 480p/720p/1080p и mp4/mov. `moon_mini` доступен в выборе генерации по референсам. Допустимость сочетаний определяют валидаторы модели, а не объединённый список значений.

Первый кадр передаётся как `first_frame_image_url`, последний — `last_frame_image_url`. Референсы — массивы строк URL. Обычные ограничения: 9 изображений, 3 видео, 3 аудио. `moon_pro` расширяет референсы до 30/10/10 с дополнительными общими лимитами; старое поле `image_list` с первыми кадрами остаётся ограничено девятью. Для edit/extend нужен URL исходного видео; для осмысленного изменения добавьте промпт.

Оценку запрашивайте с тем же телом, отправляйте задачу со стабильным `idempotency_key`, сохраняйте ID и опрашивайте `/make/moon/status/{taskId}`. Проверяйте `code`, `phase`, `status`, URL и расчёт вместе: `final_cost_franks` при `cost_status=estimated/reserved` ещё не означает окончательное списание.

Длительность — целое 4–15 для обычных моделей. moon_pro допускает -1 (авто) или 4–30; для moon_pro video_edit поле не передавайте либо укажите -1. Для moon_pro edit/extend и первого/последнего кадра ratio не задавайте либо используйте adaptive.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `text_to_video` | POST | `/franklab/api/make/moon/videos` | Передайте operation=text_to_video. Make moon_model → moonModel; reference_image_url → first_frame_image_url. |
| `image_to_video` | POST | `/franklab/api/make/moon/videos` | Передайте operation=image_to_video. Make moon_model → moonModel; reference_image_url → first_frame_image_url. |
| `reference_to_video` | POST | `/franklab/api/make/moon/videos` | Передайте operation=reference_to_video. Make moon_model → moonModel; reference_image_url → first_frame_image_url. |
| `video_edit` | POST | `/franklab/api/make/moon/videos` | Передайте operation=video_edit. Make moon_model → moonModel; reference_image_url → first_frame_image_url. |
| `video_extend` | POST | `/franklab/api/make/moon/videos` | Передайте operation=video_extend. Make moon_model → moonModel; reference_image_url → first_frame_image_url. |
| `poll_status` | GET | `/franklab/api/make/moon/status/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `estimate` | POST | `/franklab/api/make/moon/estimate` | То же тело, что при создании; только оценка, без вызова провайдера. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/v1/moon/videos/tasks/_connection_test_` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. Служебный ID _connection_test_ использует статусный маршрут; 404 не считается ошибкой авторизации. {} |

### Параметры REST

`text_to_video`, `image_to_video`, `reference_to_video`, `video_edit`, `video_extend`, `estimate`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `operation` | string | да | text_to_video/image_to_video/reference_to_video/video_edit/video_extend. |
| `moonModel` | string | условно / нет | moon_fast/moon_base/moon_pro/moon_mini. |
| `prompt` | string | условно / нет | Осмысленный текст либо медиа согласно выбранной операции. |
| `duration` | integer | условно / нет | 4–15 секунд; moon_pro допускает -1 (авто) либо 4–30. Для moon_pro video_edit: -1 либо не передавать. |
| `ratio` | string | условно / нет | 21:9/16:9/4:3/1:1/3:4/9:16/adaptive. Для moon_pro edit/extend и кадровых режимов: adaptive либо не передавать. |
| `resolution` | string | условно / нет | В зависимости от модели 480p/720p/1080p/4k. |
| `output_format` | string | условно / нет | Только moon_pro mp4/mov. |
| `first_frame_image_url` | string | условно / нет | URL первого кадра. |
| `last_frame_image_url` | string | условно / нет | Необязательный последний кадр. |
| `reference_images` | array | условно / нет | Строки URL. |
| `reference_videos` | array | условно / нет | Строки URL. |
| `reference_video_url` | string | условно / нет | Альтернативный URL одного видео. |
| `reference_audios` | array | условно / нет | Строки URL. |
| `reference_audio_url` | string | условно / нет | Альтернативный URL одного аудио. |
| `return_last_frame` | boolean | условно / нет | Вернуть последний кадр. |
| `generate_audio` | boolean | условно / нет | Генерация звука. |
| `watermark` | boolean | условно / нет | Водяной знак. |
| `priority` | integer | условно / нет | 0–9. |
| `safety_identifier` | string | условно / нет | Печатный ASCII, до 64 символов. |
| `execution_expires_after` | integer | условно / нет | 3600–259200 секунд. |
| `callback_url` | string | условно / нет | URL callback. |
| `idempotency_key` | string | условно / нет | Не больше 200 символов. |
| `external_task_id` | string | условно / нет | ID корреляции, до 200 символов. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Формат code/msg/data. При создании: data.taskId/task_id, status=queued, phase и метаданные идемпотентности. Состояния: queued/processing/completed/failed. Результат: data.videoUrl либо нормализованный URL внутри result, last_frame_url при запросе. При ошибке задачи возможен HTTP 200 с code=500. final_cost_franks при reserved ещё не окончательный расчёт.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/moon/videos" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"operation":"text_to_video","moonModel":"moon_fast","prompt":"A blue paper cube rotates on a white background.","duration":4,"resolution":"480p","ratio":"16:9","generate_audio":false}'
```

Оценка: `POST /franklab/api/make/moon/estimate`. Используйте то же тело.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/moon/status/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab MiniMax

REST со stored-file поддерживает все пять сценариев. Для текста нужны конкретное соотношение сторон (21:9,16:9,4:3,1:1,3:4,9:16) и отсутствие референсов. Кадровые сценарии требуют соответствующие собственные ID, `ratio:"adaptive"` и отсутствие массивов референсов. Для reference нужен хотя бы один образ или видео; одного аудио недостаточно. Повтор ID между массивами отклоняется.

Загрузка URL: `{source_type:"url",kind:"image",url:"https://your-public-host.example/synthetic.png"}`. Для байтов — multipart `source_type=make_file`, `kind=image`, `media_file=@synthetic.png`; data URI передавайте текстовым файлом `data_url_file=@source.dataurl` с `source_type=data_url`. Транспортный предел одного файла 64 MiB; пределы медиа меньше: изображение 30 MiB, видео 50 MiB, аудио 15 MiB. Повторно используйте `stored_file_id` из ответа.

Direct принимает один JSON-файл, а не JSON-тело. Содержимое для первого кадра: `{version:"minimax_h3_direct_v1",idempotency_key:"video-docs-frame-001",scenario:"first_frame_to_video",prompt:"A paper cube rotates.",resolution:"768P",duration:4,first_frame:{source_type:"stored_file",stored_file_id:"OWNED_FILE_ID"}}`. Make преобразует бинарные файлы в data URL до создания JSON. В direct разрешены stored_file/url/data_url; make_file как тип внутри JSON не принимается.

Для сверки того же запроса сохраняйте ключ идемпотентности. Другое тело с тем же ключом вызывает конфликт; `repeat_token` означает намеренную новую генерацию. Учитывайте 429 и интервалы повторов: ошибка GET не отменяет уже созданное видео. Отдельный маршрут MiniMax estimate в этом контроллере не найден.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `upload_media` | POST | `/franklab/api/make/minimax/media` | Большой data URI передавайте файлом, не обычным полем формы. Ответ: stored_file_id, media_kind, mime_type, size_bytes. |
| `issue_idempotency_key` | POST | `/franklab/api/make/minimax/idempotency-key` | Возвращает data.idempotency_key; новый ключ не является безопасным способом повторить неизвестный запрос. |
| `create_video:text_to_video` | POST | `/franklab/api/make/minimax/videos` | REST принимает stored-file форму. В Make JSON-маршрут используется для текста, референсы идут через videos/direct. |
| `create_video:first_frame_to_video` | POST | `/franklab/api/make/minimax/videos` | REST принимает stored-file форму. В Make JSON-маршрут используется для текста, референсы идут через videos/direct. |
| `create_video:last_frame_to_video` | POST | `/franklab/api/make/minimax/videos` | REST принимает stored-file форму. В Make JSON-маршрут используется для текста, референсы идут через videos/direct. |
| `create_video:first_last_frame_to_video` | POST | `/franklab/api/make/minimax/videos` | REST принимает stored-file форму. В Make JSON-маршрут используется для текста, референсы идут через videos/direct. |
| `create_video:reference_to_video` | POST | `/franklab/api/make/minimax/videos` | REST принимает stored-file форму. В Make JSON-маршрут используется для текста, референсы идут через videos/direct. |
| `create_video:direct` | POST | `/franklab/api/make/minimax/videos/direct` | Внутри JSON: version=minimax_h3_direct_v1, idempotency_key, scenario (кроме текста), prompt, resolution, duration, необязательный repeat_token. first_frame/last_frame либо массивы reference_images/reference_videos/reference_audios содержат source_type=stored_file/url/data_url с соответствующим stored_file_id/url/data_url. Для кадровых режимов ratio не передают; для референсов допустимо. |
| `get_video_task` | GET | `/franklab/api/make/minimax/videos/{taskId}` |  |
| `list_video_tasks` | GET | `/franklab/api/make/minimax/videos` | Также обслуживает RPC getMiniMaxVideoTasks: страница 1, размер 100. |
| `cancel_or_delete_video_task:cancel` | POST | `/franklab/api/make/minimax/videos/{taskId}/action` | Изменяющая операция; терминальное состояние и расчёт проверяются отдельно. |
| `cancel_or_delete_video_task:delete` | POST | `/franklab/api/make/minimax/videos/{taskId}/action` | Изменяющая операция; терминальное состояние и расчёт проверяются отдельно. |
| `connection_probe` | GET | `/franklab/api/make/minimax/videos` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {"page_num": 1, "page_size": 1, "model": "MiniMax-H3", "task_type": "generation"} |

### Параметры REST

`upload_media`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `source_type` | string | да | url/make_file/data_url. |
| `kind` | string | да | image/video/audio. |
| `url` | string | условно / нет | HTTPS URL для загрузки по ссылке. |
| `media_file` | binary | условно / нет | Multipart-файл для make_file. |
| `data_url_file` | binary | условно / нет | Текстовый multipart-файл с содержимым data URI. |

`create_video:text_to_video`, `create_video:first_frame_to_video`, `create_video:last_frame_to_video`, `create_video:first_last_frame_to_video`, `create_video:reference_to_video`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `idempotency_key` | string | да | Стабильный непустой ключ, до 200 символов. |
| `scenario` | string | да | text_to_video/first_frame_to_video/last_frame_to_video/first_last_frame_to_video/reference_to_video. |
| `prompt` | string | да | Непустое значение, до 7000 символов. |
| `resolution` | string | да | 768P/2K. |
| `duration` | integer | да | 4–15 секунд. |
| `ratio` | string | условно / нет | Для текста конкретное соотношение сторон; для кадровых режимов adaptive. |
| `first_frame_stored_file_id` | string | условно / нет | ID собственного первого изображения. |
| `last_frame_stored_file_id` | string | условно / нет | ID собственного последнего изображения. |
| `reference_image_stored_file_ids` | array | условно / нет | До 9 уникальных собственных ID. |
| `reference_video_stored_file_ids` | array | условно / нет | До 3 уникальных собственных ID. |
| `reference_audio_stored_file_ids` | array | условно / нет | До 3 уникальных собственных ID. |
| `repeat_token` | string | условно / нет | Только намеренный повтор, до 64 символов. |

`create_video:direct`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `request_file` | binary | да | Один multipart-файл JSON в UTF-8, MIME application/json, до 96 MiB. |

`get_video_task`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Локальный ID задачи в пути. |
| `wait_seconds` | integer | условно / нет | Целое query-поле 0–30; по умолчанию 0. |

`list_video_tasks`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `page_num` | integer | условно / нет | Нумерация с 1. |
| `page_size` | integer | условно / нет | Целое query-поле 1–100; по умолчанию 20. |
| `status` | string | условно / нет | queued/running/succeeded/failed/cancelled. |
| `task_ids` | array | условно / нет | Необязательные ID. |
| `model` | string | условно / нет | MiniMax-H3. |
| `task_type` | string | условно / нет | generation. |

`cancel_or_delete_video_task:cancel`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Локальный ID задачи в пути. |
| `action` | string | да | cancel. |

`cancel_or_delete_video_task:delete`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Локальный ID задачи в пути. |
| `action` | string | да | delete. |

### Ответ и завершение

Формат code=200,msg=OK,data. task_id; состояния queued/running/succeeded/failed/cancelled, при succeeded — video с собственным stored_file_id и URL. Поля расчёта: reserved_cost_franks, final_cost_franks, cost_status, usage, error. Списки: data.items/page_num/page_size/total.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/minimax/videos" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"idempotency_key":"video-docs-synthetic-001","scenario":"text_to_video","prompt":"A blue paper cube rotates on a white background.","resolution":"768P","duration":4,"ratio":"16:9"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/minimax/videos/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab OMNI

Режим Google subscription обслуживается отдельным оператором. В проверке 8 сентября 2026 запрос оставался в очереди ручной обработки; автоматическое завершение и срок ожидания не подтверждены. Это ограничение режима подписки, а не всех моделей OMNI.

OMNI — отдельный модуль от старого SATURN-алиаса `/v1/videos/omni-video`. Используйте `/make/omni/videos`. В Make `model=omni` выбирает `omni_version`, `model=veo` — `veo_version`; REST-поле `model` содержит итоговое конкретное значение. `poll_status` означает GET, а не операцию создания.

Для image-to-video нужен один источник изображения, для reference-to-video — массив объектов, например `{source:"url",image_url:ownedURL,label:"cube"}`. В edit/extend передавайте полученный `interaction_id` этого же партнёра. Extend поддерживает только `omni_1_1`, версия `omni` 1.0 его отклоняет. Veo использует свои 4/6/8 секунд, разрешение и negative prompt; эти поля не добавляют возможностей движку Omni. GET `/make/omni` описывает возможности, но не доказывает успешную генерацию.

`google_flow_sub` использует отдельный маршрут подписки с `execution_mode:"google_subscription"` и массивом строк URL. Формат опроса отличается. Обычная загрузка возвращает URL; для file-ID нужен настоящий stored-file. Отдельный estimate в Make OMNI-контроллере отсутствует.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `text_to_video` | POST | `/franklab/api/make/omni/videos` | extend требует omni_1_1; Make omni_version/veo_version → REST model. |
| `image_to_video` | POST | `/franklab/api/make/omni/videos` | extend требует omni_1_1; Make omni_version/veo_version → REST model. |
| `reference_to_video` | POST | `/franklab/api/make/omni/videos` | extend требует omni_1_1; Make omni_version/veo_version → REST model. |
| `edit` | POST | `/franklab/api/make/omni/videos` | extend требует omni_1_1; Make omni_version/veo_version → REST model. |
| `extend` | POST | `/franklab/api/make/omni/videos` | extend требует omni_1_1; Make omni_version/veo_version → REST model. |
| `veo3` | POST | `/franklab/api/make/omni/videos` | Маршрут модели Veo требует действующего допуска. Make по умолчанию отправляет operation=text_to_video; image_file_id задаёт первый кадр. |
| `veo3_fast` | POST | `/franklab/api/make/omni/videos` | Маршрут модели Veo требует действующего допуска. Make по умолчанию отправляет operation=text_to_video; image_file_id задаёт первый кадр. |
| `poll_status` | GET | `/franklab/api/make/omni/status/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `capabilities` | GET | `/franklab/api/make/omni` | Описание операций/моделей и текущего состояния допуска Veo. |
| `google_flow_sub` | POST | `/franklab/api/v1/videos/google-sub` | Отдельный маршрут подписки; model=google_flow_sub не передаётся в make/omni/videos. |
| `poll_status` | GET | `/franklab/api/v1/videos/google-sub/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/make/omni` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {} |

### Параметры REST

`text_to_video`, `image_to_video`, `reference_to_video`, `edit`, `extend`, `veo3`, `veo3_fast`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `operation` | string | да | text_to_video/image_to_video/reference_to_video/edit/extend. |
| `model` | string | условно / нет | omni/omni_1_1/veo3/veo3_fast. |
| `prompt` | string | да | Непустое значение, до 2500 символов. |
| `aspect_ratio` | string | условно / нет | 16:9/9:16. |
| `image_url` | string | условно / нет | Источник — URL изображения. |
| `image_file_id` | string | условно / нет | ID собственного изображения. |
| `image_file_data` | string | условно / нет | Источник файла base64/native. |
| `image_file_name` | string | условно / нет | Имя файла для переданных данных. |
| `image_base64` | string | условно / нет | Источник в base64. |
| `reference_images` | array | условно / нет | [{source,image_url / image_file_id / image_base64 / image_file_data,image_file_name?,label?}]. |
| `previous_interaction_id` | string | условно / нет | Для edit/extend обязателен существующий interaction этого партнёра. |
| `duration_seconds` | integer | условно / нет | Только Veo 4/6/8. |
| `resolution` | string | условно / нет | Только Veo 720p/1080p/4k. |
| `negative_prompt` | string | условно / нет | Только Veo, до 1000 символов. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`google_flow_sub`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `execution_mode` | string | да | google_subscription. |
| `prompt` | string | да | Описание сцены. |
| `duration_seconds` | number | условно / нет | Значения Make 4/6/8/10. |
| `aspect_ratio` | string | условно / нет | 16:9/9:16/1:1/4:3/3:4. |
| `reference_images` | array | условно / нет | Строки URL. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Make OMNI: code/msg/data; taskId/task_id, status, videoUrl/video_url, interaction_id и поля расчёта. Опрос: completed/failed/processing. Сохраните interaction для edit/extend. google-sub использует proxy task_status/task_result.videos.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/omni/videos" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"model":"omni_1_1","operation":"text_to_video","prompt":"A blue paper cube rotates on a white background.","aspect_ratio":"16:9"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/make/omni/status/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab SATURN

Передавайте `model_name:"saturn-v1"` или `"saturn-v1-5"`, а не Make-селектор `version`. Стандартный SATURN принимает текст, изображения, видео-референсы, элементы, голоса и управление несколькими сценами в рамках ограничений модели. Объект изображения — `{image_url:ownedURL}`; источник в каждом объекте ровно один. Native/base64 ограничен 10 MiB на изображение. Видео-объекты используют `video_url`, необязательные `refer_type` и `keep_original_sound`; голосов не больше двух.

У Turbo два отдельных маршрута и модель `saturn-v1-5-turbo`; стандартные параметры референсов, мультисцен, звука и качества туда не переносятся. В image Turbo формат определяется изображением, в text Turbo задаётся aspect_ratio. Для продолжения нужен настоящий `video_id` или собственный `source_task_id`. Генерация из нескольких изображений имеет отдельные create/status маршруты.

Список и запуск AI presets есть в Make и методах сервиса, но соответствующие controller-маршруты в текущих исходниках отсутствуют: статус BLOCKED. Сохраняйте правильный маршрут опроса для каждого варианта. Старый task ID не должен приводить к новому POST. Legacy `/videos/omni-video` относится к SATURN, не к Gemini OMNI.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `v1` | POST | `/franklab/api/v1/videos/saturn` | Make version выбирает model_name=saturn-v1. |
| `v1-5` | POST | `/franklab/api/v1/videos/saturn` | Make version выбирает model_name=saturn-v1-5. |
| `v1-5-turbo:text` | POST | `/franklab/api/v1/videos/saturn-turbo/text-to-video` | Не передавайте в Turbo стандартные SATURN-поля multi-shot/reference/sound/mode. |
| `v1-5-turbo:image` | POST | `/franklab/api/v1/videos/saturn-turbo/image-to-video` | Не передавайте в Turbo стандартные SATURN-поля multi-shot/reference/sound/mode. |
| `video_extend` | POST | `/franklab/api/v1/videos/video-extend` | Нужно существующее исходное видео; Make не передаёт requested duration в extension. |
| `multi_image2video` | POST | `/franklab/api/v1/videos/multi-image2video` |  |
| `ai_presets:list` | GET | `/franklab/api/v1/general/ai-multi-shot` | BLOCKED: Make communication и методы сервиса есть, но соответствующий Nest controller-маршрут в исходниках отсутствует. Не вызывайте как поддерживаемый REST. |
| `ai_presets:generate` | POST | `/franklab/api/v1/general/ai-multi-shot/{presetId}` | BLOCKED: Make communication и методы сервиса есть, но соответствующий Nest controller-маршрут в исходниках отсутствует. Не вызывайте как поддерживаемый REST. |
| `poll_status` | GET | `/franklab/api/v1/videos/saturn/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `poll_status` | GET | `/franklab/api/v1/videos/saturn-turbo/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `poll_status` | GET | `/franklab/api/v1/videos/video-extend/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `poll_status` | GET | `/franklab/api/v1/videos/multi-image2video/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `getAllKusoks` | GET | `/franklab/api/make/kusok/elements` | Вспомогательный RPC; сохраняйте полученные ID. |
| `getElementVoices` | GET | `/franklab/api/v1/elements/voices` | Вспомогательный RPC; сохраняйте полученные ID. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/v1/videos/saturn` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {"pageNum": 1, "pageSize": 1} |

### Параметры REST

`v1`, `v1-5`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `prompt` | string | условно / нет | Описание сцены. |
| `duration` | integer | да | Длительность клипа 3–15 секунд. |
| `model_name` | string | условно / нет | Публичный алиас модели. |
| `mode` | string | условно / нет | Режим качества. |
| `aspect_ratio` | string | условно / нет | Соотношение сторон результата. |
| `callback_url` | string | условно / нет | Необязательный HTTPS callback. |
| `external_task_id` | string | условно / нет | ID корреляции клиента, не ID провайдера. |
| `sound` | string | условно / нет | on/off. |
| `image_list` | array | условно / нет | Ровно один источник image_url/image_base64/image_file_data на элемент; необязательные image_file_name/type. |
| `video_list` | array | условно / нет | [{video_url,refer_type?,keep_original_sound?}]. |
| `element_list` | array | условно / нет | [{element_id}]. |
| `voice_list` | array | условно / нет | [{voice_id}], at most 2. |
| `multi_shot` | boolean | условно / нет | Несколько сцен. |
| `shot_type` | string | условно / нет | customize/intelligence. |
| `multi_prompt` | array | условно / нет | [{index,prompt,duration}]. |

`v1-5-turbo:text`, `v1-5-turbo:image`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `model_name` | string | условно / нет | saturn-v1-5-turbo. |
| `prompt` | string | условно / нет | Обязательно для текста. |
| `image` | string | условно / нет | Обязательно для изображения. |
| `duration` | integer | условно / нет | 3–15; по умолчанию 5. |
| `resolution` | string | условно / нет | 720p/1080p. |
| `aspect_ratio` | string | условно / нет | Только текст 16:9/9:16/1:1. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | ID корреляции. |

`video_extend`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `video_id` | string | условно / нет | ID существующего выходного видео. |
| `source_task_id` | string | условно / нет | Собственная исходная задача для определения видео. |
| `prompt` | string | условно / нет | Не больше 2500 символов. |
| `negative_prompt` | string | условно / нет | Не больше 500. |
| `cfg_scale` | number | условно / нет | 0–1. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | ID корреляции. |

`multi_image2video`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `image_list` | array | да | [{image_url,type?}]. |
| `model_name` | string | условно / нет | Публичная модель. |
| `prompt` | string | условно / нет | До 2500 символов. |
| `duration` | integer | условно / нет | 3–15. |
| `mode` | string | условно / нет | Качество. |
| `aspect_ratio` | string | условно / нет | Соотношение сторон. |
| `sound` | boolean | условно / нет | Нативный звук. |
| `element_list` | array | условно / нет | [{element_id}]. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | ID корреляции. |

`ai_presets:list`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `pageNum` | integer | условно / нет | Страница списка. |
| `pageSize` | integer | условно / нет | Размер страницы списка. |

`ai_presets:generate`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `presetId` | string | да | ID пресета в пути; маршрут пока не зарегистрирован. |
| `prompt` | string | условно / нет | Описание сцены. |
| `duration` | integer | да | Длительность клипа 3–15 секунд. |
| `model_name` | string | условно / нет | Публичный алиас модели. |
| `mode` | string | условно / нет | Режим качества. |
| `aspect_ratio` | string | условно / нет | Соотношение сторон результата. |
| `callback_url` | string | условно / нет | Необязательный HTTPS callback. |
| `external_task_id` | string | условно / нет | ID корреляции клиента, не ID провайдера. |
| `sound` | string | условно / нет | on/off. |
| `image_list` | array | условно / нет | Ровно один источник image_url/image_base64/image_file_data на элемент; необязательные image_file_name/type. |
| `video_list` | array | условно / нет | [{video_url,refer_type?,keep_original_sound?}]. |
| `element_list` | array | условно / нет | [{element_id}]. |
| `voice_list` | array | условно / нет | [{voice_id}], at most 2. |
| `multi_shot` | boolean | условно / нет | Несколько сцен. |
| `shot_type` | string | условно / нет | customize/intelligence. |
| `multi_prompt` | array | условно / нет | [{index,prompt,duration}]. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`getAllKusoks`, `getElementVoices`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `pageNum` | integer | условно / нет | Нумерация с 1. |
| `pageSize` | integer | условно / нет | Make запрашивает 500. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Proxy-формат: code=0 (некоторые маршруты также используют 200), data.task_id. Опрашивайте data.task_status; успешный task_result.videos[] содержит url/id/duration. При ошибке читайте task_status_msg. Поле final_cost_franks интерпретируется вместе с cost_status/cost_unit; reserved не является окончательным расчётом.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/saturn" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"model_name":"saturn-v1","prompt":"A blue paper cube rotates on a white background.","duration":3,"mode":"std","aspect_ratio":"16:9"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/saturn/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab VECTOR

VECTOR переносит движение из видео на опорное изображение. Нужны изображение и публичный URL видео; Make описывает клип 3–30 секунд. `character_orientation:"image"|"video"` выбирает источник ориентации, `keep_original_sound:"yes"|"no"` — сохранение звука. Профили: auto/studio/cinema; REST также принимает старые vector-v1/vector-v1-5. Качество std/pro.

Изображение передаётся URL, base64/data URI либо `image_file_data` с `image_file_name`. Make-контракт описывает JPG/PNG/WebP до 10 MiB. Необязательные элементы — объекты `{element_id}`. `list_tasks` использует GET с query-параметрами, без тела создания. Make-селекторы action/task не являются REST-полями. Для генерации нужны референс-видео и опорное изображение; список задач возвращает только их метаданные.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `create` | POST | `/franklab/api/v1/videos/motion-control` | Make anchor_image→image, anchor_video→video, anchor_source→character_orientation, quality_mode→mode, preserve_reference_audio→keep_original_sound, reference_anchor_list→element_list. |
| `list_tasks` | GET | `/franklab/api/v1/videos/motion-control` | Список задач текущего партнёра в data и pagination. |
| `poll_status` | GET | `/franklab/api/v1/videos/motion-control/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/v1/videos/motion-control` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {"pageNum": 1, "pageSize": 1} |

### Параметры REST

`create`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `image` | string | да | URL опорного изображения либо допустимый base64. |
| `image_file_data` | string | условно / нет | Альтернативные данные файла в base64/native. |
| `image_file_name` | string | условно / нет | Имя файла для native-данных. |
| `video` | string | да | Публичный URL референс-видео. |
| `character_orientation` | string | да | image/video. |
| `mode` | string | условно / нет | std/pro. |
| `generation_profile` | string | условно / нет | auto/studio/cinema. |
| `keep_original_sound` | string | условно / нет | yes/no. |
| `prompt` | string | условно / нет | Не больше 2500 символов. |
| `duration` | string | да | Обязательная строка: секунды 3–30, при ориентации image не больше 10. Должно соответствовать референс-клипу. |
| `element_list` | array | условно / нет | [{element_id}]. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | Не больше 100 символов. |

`list_tasks`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `pageNum` | integer | условно / нет | По умолчанию 1. |
| `pageSize` | integer | условно / нет | По умолчанию 30. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Proxy-формат: code=0 (некоторые маршруты также используют 200), data.task_id. Опрашивайте data.task_status; успешный task_result.videos[] содержит url/id/duration. При ошибке читайте task_status_msg. Поле final_cost_franks интерпретируется вместе с cost_status/cost_unit; reserved не является окончательным расчётом.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/motion-control" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"generation_profile":"studio","mode":"std","image":"OWNED_SYNTHETIC_IMAGE_URL","video":"OWNED_SYNTHETIC_MOTION_VIDEO_URL","character_orientation":"image","keep_original_sound":"no","duration":"3"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/motion-control/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab VENUS

Передайте изображение и либо `sound_file` (URL/base64/native файл), либо существующий `audio_id`. Make описывает MP3/WAV/M4A/AAC до 5 MiB, 2–60 секунд; для audio ID — 2–300 секунд, не старше 30 дней. Native-поля: image_file_data/image_file_name и sound_file_data/sound_file_name. Не отправляйте оба источника аудио одновременно.

Make создаёт задачу через `/v1/videos/avatar/image2video`, затем опрашивает `/v1/tasks/{taskId}`. Успех требует видео в `task_result.videos`. Сервис имеет учитываемый и старый proxy-путь, выбираемые runtime-флагом; отсутствие полей стоимости не означает нулевую цену или подтверждённый возврат. Расчёт проверяется отдельно.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `create_avatar_video` | POST | `/franklab/api/v1/videos/avatar/image2video` | Один источник изображения и один аудио; Make image_source/audio_source/sound_input_source не являются REST-полями. |
| `poll_status` | GET | `/franklab/api/v1/tasks/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `avatar_status` | GET | `/franklab/api/v1/videos/avatar/image2video/{taskId}` | Отдельный статусный алиас; Make использует v1/tasks. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/v1/videos/avatar/image2video` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. {"pageNum": 1, "pageSize": 1} |

### Параметры REST

`create_avatar_video`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `image` | string | да | URL изображения либо base64. |
| `image_file_data` | string | условно / нет | Альтернативные байты изображения native/base64. |
| `image_file_name` | string | условно / нет | Имя файла. |
| `sound_file` | string | условно / нет | URL/base64 аудио; альтернатива audio_id. |
| `sound_file_data` | string | условно / нет | Альтернативные аудиоданные native/base64. |
| `sound_file_name` | string | условно / нет | Имя файла. |
| `audio_id` | string | условно / нет | Существующий совместимый TTS audio ID; альтернатива sound_file. |
| `prompt` | string | условно / нет | Необязательный промпт поведения персонажа. |
| `mode` | string | да | std/pro. |
| `callback_url` | string | условно / нет | Callback. |
| `external_task_id` | string | условно / нет | ID корреляции. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`avatar_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | ID задачи из ответа. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Proxy-формат: code=0 (некоторые маршруты также используют 200), data.task_id. Опрашивайте data.task_status; успешный task_result.videos[] содержит url/id/duration. При ошибке читайте task_status_msg. Поле final_cost_franks интерпретируется вместе с cost_status/cost_unit; reserved не является окончательным расчётом.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/avatar/image2video" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"image":"OWNED_SYNTHETIC_AVATAR_URL","sound_file":"OWNED_SYNTHETIC_AUDIO_URL","mode":"std"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/tasks/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```


## FrankLab X

Передайте `operation:"generation"` и текст, `image_url` либо `reference_images:[{url:ownedURL}]`. Изображение и массив референсов взаимоисключающие. `source_mode` — только Make-селектор. Для edit/extension нужен `video_url`, без изображений и референсов; extension допускает отсутствие промпта. Длительность generation/edit 1–15 секунд, extension 2–10; Make предлагает более узкие удобные значения.

Если распознанная модель явно не задана, одно изображение выбирает новейшую image-to-video модель; текст и референсы — совместимую. 1080p допускается только для новейшей генерации по одному изображению. `execution_mode:"supergrok"` поддерживает лишь генерацию по тексту/изображениям/референсам, требует публичный HTTPS для изображений и отдельный допуск партнёра. Edit/extend и видео-вход не поддерживаются. Не выводите доступность подписки из списка параметров и не переключайте режим после ошибки автоматически.

POST возвращает FrankLab task ID; опрашивайте тот же X-маршрут до терминального статуса и рабочего URL. Сохраняйте cost_status вместе с final_cost_franks. Отдельный estimate в контроллере отсутствует; перед разрешённой генерацией нужна актуальная партнёрская оценка.

### Маршруты и операции

| Операция | HTTP | Путь | Условие / назначение |
|---|---|---|---|
| `generation:text_to_video` | POST | `/franklab/api/v1/videos/xai` | Make source_mode выбирает входные REST-поля; автоматического переключения режима при ошибке нет. |
| `generation:image_to_video` | POST | `/franklab/api/v1/videos/xai` | Make source_mode выбирает входные REST-поля; автоматического переключения режима при ошибке нет. |
| `generation:reference_to_video` | POST | `/franklab/api/v1/videos/xai` | Make source_mode выбирает входные REST-поля; автоматического переключения режима при ошибке нет. |
| `edit` | POST | `/franklab/api/v1/videos/xai` | Make source_mode выбирает входные REST-поля; автоматического переключения режима при ошибке нет. |
| `extension` | POST | `/franklab/api/v1/videos/xai` | Make source_mode выбирает входные REST-поля; автоматического переключения режима при ошибке нет. |
| `poll_status` | GET | `/franklab/api/v1/videos/xai/{taskId}` | Сохраните ID из ответа; опрос читает существующую задачу и не создаёт новую. |
| `upload_source` | POST | `/franklab/api/franklab/jobs/upload` | Партнёрская авторизация. Ответ {success:true,data:{url}}, хранение 7 дней. Нет storedFileId и измеренных метаданных. |
| `connection_probe` | GET | `/franklab/api/v1/images/omni-image` | Проверка соединения Make; не доказывает генерацию или доступность провайдера. Читает список задач изображений; это не загрузка файла и не генерация X. {"pageNum": 1, "pageSize": 1} |

### Параметры REST

`generation:text_to_video`, `generation:image_to_video`, `generation:reference_to_video`, `edit`, `extension`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `operation` | string | да | generation/edit/extension. |
| `execution_mode` | string | условно / нет | xai_api/supergrok. |
| `prompt` | string | условно / нет | Обязательно, кроме extension. |
| `image_url` | string | условно / нет | Одно входное изображение. |
| `reference_images` | array | условно / нет | [{url}], альтернатива image_url. |
| `video_url` | string | условно / нет | Обязательно для edit/extension. |
| `aspect_ratio` | string | условно / нет | Соотношение сторон при генерации. |
| `resolution` | string | условно / нет | 480p/720p; 1080p — только новейшая генерация по одному изображению. |
| `duration` | number | условно / нет | Генерация/edit 1–15; extension 2–10; по умолчанию 5. |

`poll_status`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `taskId` | string | да | Путь: FrankLab task ID из ответа создания. |

`upload_source`

| Поле | Тип | Обязательно | Значение / ограничение |
|---|---|---|---|
| `file` | binary | да | Multipart-файл до 150 MiB; допустимый MIME изображения/видео/аудио. |

### Ответ и завершение

Proxy-формат: code=0 (некоторые маршруты также используют 200), data.task_id. Опрашивайте data.task_status; успешный task_result.videos[] содержит url/id/duration. При ошибке читайте task_status_msg. Поле final_cost_franks интерпретируется вместе с cost_status/cost_unit; reserved не является окончательным расчётом.

### Минимальный пример

Замените OWNED_* ссылками на собственные файлы. Перед отправкой проверьте доступ к модели, оценку стоимости и доступный баланс.

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/xai" \
  -H "X-API-Key: $FRANKLAB_KEY" \
  -H "Content-Type: application/json" \
  --data '{"operation":"generation","execution_mode":"xai_api","prompt":"A blue paper cube rotates on a white background.","duration":1,"resolution":"480p","aspect_ratio":"16:9"}'
```

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/v1/videos/xai/$TASK_ID" \
  -H "X-API-Key: $FRANKLAB_KEY"
```

## Загрузка и сохранение результатов

```bash
curl --fail-with-body -sS "$FRANKLAB_BASE_URL/franklab/jobs/upload" \
  -H "Authorization: Bearer $FRANKLAB_KEY" \
  -F "file=@synthetic.png;type=image/png"
```

Ответ загрузки: `{"success":true,"data":{"url":"..."}}`. Используйте фактический URL ответа. Здесь нет storedFileId, ширины, высоты, fps или длительности. Для параметров с ID и дескрипторами нужна отдельная подтверждённая запись собственного файла. Скачивайте готовый результат до истечения срока хранения; не публикуйте подписанные URL в логах и отчётах.
