1313 разделов — нажмите для перехода
Что можно создать
Программно создавайте видеопроекты и говорящие аватары в том же аккаунте, с теми же кредитами и историей, что и в веб‑приложении.
REST подходит для backend, автоматизации и продуктовой интеграции. MCP нужен, когда AI‑агент должен сам увидеть инструменты, рассчитать стоимость и отправить задачу.
Публичный v1 работает асинхронно: сохраните ID задачи, опрашивайте статус или принимайте подписанный webhook. Для платной генерации нужен подходящий тариф VlogMe.
- Оценка стоимости до списания кредитов.
- Говорящее видео из портрета и текста с голосом либо из готового аудио.
- Прогресс задачи и временная подписанная ссылка на результат.
- Безопасный повтор платного запроса с Idempotency-Key.
VlogMe Avatar в Replicate
Для простого endpoint «изображение + аудио» публичный VlogMe Avatar bridge также доступен как hosted‑модель Replicate.
Этот вариант удобен, если инфраструктура и биллинг уже построены вокруг Replicate. Прямой API VlogMe остаётся полной поверхностью для кредитов, истории, REST и MCP.
Hosted bridge возвращает вертикальный MP4 с говорящим аватаром и по умолчанию включает субтитры.
Авторизация
Передавайте Bearer token в каждом защищённом запросе. Токен показывается один раз — сохраните его в secret manager.
Создайте токен в Settings → API. Не помещайте его в браузерный JavaScript, мобильное приложение, публичный репозиторий или клиентские логи.
Базовый адрес REST: https://vlogme.ai/api/public/v1. При возможной утечке немедленно ротируйте токен.
Authorization: Bearer vlm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxhttps://dev.vlogme.ai/api/public/v1Быстрый запуск
Создайте токен, рассчитайте запрос, отправьте рендер и опрашивайте его до конечного статуса.
Пример передаёт URL портрета, сценарий, ID голоса и формат кадра. Замените заглушки на файлы, доступные серверу VlogMe.
Успешный POST сразу возвращает 202 Accepted. Проверяйте статус примерно раз в десять секунд или передайте webhook_url.
curl -X POST https://dev.vlogme.ai/api/public/v1/videos \
-H "Authorization: Bearer $VLOGME_TOKEN" \
-H "Idempotency-Key: video-request-001" \
-H "Content-Type: application/json" \
-d '{
"portrait_url": "https://example.com/portrait.jpg",
"aspect_ratio": "16:9",
"script": "Welcome to the demo.",
"voice_id": "EXAVITQu4vr4xnSDxMaL",
"webhook_url": "https://yourapp.com/webhooks/vlogme"
}'REST endpoints
Компактный JSON API со схемой OpenAPI 3.1, стабильными кодами ошибок и rate-limit headers.
Машиночитаемая спецификация: /api/public/v1/openapi.json. Из неё можно создать типизированный клиент или импортировать запросы в Postman и Insomnia.
Каждый ответ содержит X-Request-Id. Асинхронный POST /videos также возвращает Location с URL опроса.
/meID пользователя, тариф и баланс кредитов/voicesID голосов, доступных для синтеза/videosЗапустить асинхронный рендер/videos/:idПолучить статус и подписанную ссылку/videosСписок последних рендеров с пагинацией/videos/estimateОценить кредиты без списания/videos/:idУдалить или отменить доступный рендер/healthПроверка доступности без авторизацииcurl https://dev.vlogme.ai/api/public/v1/videos/$VIDEO_ID \
-H "Authorization: Bearer $VLOGME_TOKEN"Создание ИИ‑видео
Передайте портрет и либо сценарий с voice_id, либо аудиофайл. Рендер выполняется асинхронно.
Используйте portrait_url или portrait_base64. Для речи передайте script + voice_id либо audio_url/audio_base64. Дополнительно доступны aspect_ratio, emotion_preset, live_subtitles, title и webhook_url.
Для каждого платного POST обязателен уникальный Idempotency-Key. Повтор с тем же ключом вернёт исходный рендер без второго списания.
- Форматы: 9:16 по умолчанию, 16:9 и 1:1.
- Массив inserts добавляет b‑roll в режиме overlay или cut.
- audio_mode принимает auto, prompt, asset или off для фонового звука проекта.
- Ответ 202 содержит id, status, credits_charged, estimated_seconds и warnings.
curl -X POST https://dev.vlogme.ai/api/public/v1/videos \
-H "Authorization: Bearer $VLOGME_TOKEN" \
-H "Idempotency-Key: video-request-001" \
-H "Content-Type: application/json" \
-d '{
"portrait_url": "https://example.com/portrait.jpg",
"aspect_ratio": "16:9",
"script": "Welcome to the demo.",
"voice_id": "EXAVITQu4vr4xnSDxMaL",
"webhook_url": "https://yourapp.com/webhooks/vlogme"
}'Грамматика сценариев
Машиночитаемый DSL описывает смену сцен, b‑roll, аудиовставки, паузы и inline‑теги исполнения голоса.
Используйте @imageN для смены говорящей сцены, фигурные скобки для overlay/chain b‑roll, @audioN для аудиоматериалов и теги ElevenLabs вроде [shocked].
Скачиваемая спецификация намеренно сохраняется на языке контракта для инструментов и LLM. MCP‑клиент может получить её через script_grammar_help.
SCRIPT-GRAMMAR.md
# VlogMe Script Grammar — canonical contract
> Single source of truth for two contracts:
>
> **A. Frontend ↔ Backend (script grammar)** — what humans and AI write.
> **B. Backend ↔ Worker (payload)** — the structured JSON the render fleet consumes.
>
> The frontend never builds a worker payload directly. `flatToPayloads()` in
> `src/lib/scenes/flat-script.ts` is the single bridge between A and B.
---
## A. Script grammar (frontend ↔ backend)
A VlogMe script is plain text driving a short-form render. The project-level
`aspect_ratio` decides the frame (`9:16`, `16:9`, or `1:1`); the script grammar
is identical for all three formats. There are **four explicit beat forms**, plus
a plain-text continuation line for the current avatar. The shape of the token
decides the kind — never the card role.
| # | Form | Meaning |
| --- | ---------------------- | ---------------------------------------------------------------------- |
| 1 | `@imageN <text>` | Avatar speaks `<text>`, anchored to photo slot N. |
| 2 | `@imageN { <prompt> }` | Standalone video clip generated from photo N. Prompt is in the braces. |
| 3 | `{ @imageM <prompt> }` | Overlay clip on top of the current avatar, using photo M as 1st frame. |
| 4 | `{ <prompt> }` | Continue — extends the previous clip, no reference image of its own. |
Plus one media token: `@audioN` on its own line drops audio clip N on the
current avatar.
Plain text on its own line continues speech for the current avatar. This is
mainly used after an overlay beat:
```text
@image1 So I open the laptop.
{ @image3 slow push-in on the glowing keyboard }:3
And the cursor starts moving on its own.
```
### Rules
- Whitespace, blank lines and indentation are **insignificant** — only the
token shape matters.
- Avatar text (form 1) preserves its newlines verbatim into the worker
payload's `script` field. Multi-line dialogue stays multi-line end-to-end.
- The current avatar = the most recent avatar speech tag. Forms 3 and 4 anchor
to that avatar/beat.
- Form 4 requires a preceding rendered frame/current avatar to continue from.
- Form 3 starts directly with `@imageN`: `{ @image3 fade out }`.
- In form 4, the optional keyword `continue` is stripped:
`{ continue sparks fly }` works the same as `{ sparks fly }`.
- `@imageN-K` (K in 0..100): cross-fade transition code applied when the
avatar switches (form 1 only).
### Duration override
Any form 2 / 3 / 4 may carry an explicit clip duration in seconds:
- `{ ... }:D` — after the closing brace.
- `@imageN { ... }:D` — same.
Without `:D` the clip uses the system default (3s), capped at 5s.
### Brace body options
Forms 2 / 3 / 4 can use either a plain prompt or an advanced pipe body:
```text
@image2 { slow push-in on a mountain lake }:3
{ @image3 v:glowing OPEN sign, slow push-in | n:watermark, text | s:soft city hum | t5 }:3
{ v:camera keeps drifting upward | am:off }:2
```
Supported segments:
- `v:<visual prompt>` — main visual prompt.
- `n:<negative prompt>` — visual negative prompt.
- `s:<sound prompt>` / `an:<negative sound>` — generated audio prompt fields.
- `@audioM` — uploaded audio clip under this video beat.
- `am:auto|prompt|asset|off` — audio mode.
- `ag:<db>` — audio gain.
- `tK` — transition code, 0..100.
### Examples
```text
@image1 Hey, let me show you something.
@image1 So I open the laptop.
{ @image3 slow push-in on the glowing keyboard }:3
And the cursor starts moving on its own.
@image2 { dolphin breaches in slow motion against the sunrise }:4
{ camera keeps drifting up, sky turns deeper orange }:2
@image1 [shocked] What the hell is happening?
@audio1
```
Breakdown:
- Line 1 — avatar 1 speaks one sentence.
- Line 3 — overlay over the current avatar using photo 3.
- Line 4 — avatar 1 continues speaking.
- Line 6 — standalone video from photo 2 (4s).
- Line 7 — continue clip extending the previous shot (2s, no reference photo).
- Line 9 — avatar 1 again, with an ElevenLabs `[shocked]` audio tag.
- Line 10 — drops audio clip 1 on top of the avatar.
### Legacy back-compat
The old "bare `@imageN` lets the card's role decide" form is still accepted
by the parser. Specifically: an `@imageN` line **without** braces falls back
to `card.role` + `card.effectInsertMode` to pick avatar / video / overlay /
continue. This keeps the timeline editor — which currently edits cards in
the bare form — working unchanged while we migrate the UI to render explicit
brace cards.
When AI generates a script, it should prefer the **four explicit forms**.
Parser/serializer round-trips currently normalize back to the legacy bare form
for the timeline UI; that will change in a follow-up.
### Forbidden
- Mid-line `@imageN` outside of a brace. Each tag is on its own line OR
inside a `{ … }` block.
- Inline overlay inside avatar speech, e.g. `@image1 words {@image2 ...}:3`.
- Bare `@imageN` video instructions from new AI output. Generate
`@imageN { ... }:D` instead.
- Nested braces.
- Anything else not listed in §A.
---
## B. Worker payload (backend ↔ worker)
The worker consumes `ScenePayload[]` (defined in `src/lib/scenes/scenes.ts`).
The frontend never builds these — `flatToPayloads()` is the only producer.
Each scene has an `input_type` discriminator:
| `input_type` | Comes from script form | Key fields |
| --------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `text` | Form 1 | `image_path`, `script` (avatar speech), `voice_id`, `transition` |
| `audio` | `@audioN` | `image_path` (current avatar), `audio_path`, `audio_duration_seconds` |
| `ltx` | Form 2 | `image_path` (source photo), `script` (visual prompt), `audio_duration_seconds` |
| `video_overlay` | Form 3 | `image_path` (anchor avatar), `overlay_source_image_path` (photo M), `overlay_visual_prompt`, `overlay_min_duration_seconds` |
| `video_chain` | Form 4 | `chain_from_previous: true`, `overlay_source_image_path`, `overlay_visual_prompt` |
Insert variants (overlay / cut) for nested timing inside an avatar audio
chunk follow `docs/public-api-inserts-contract.md`. That doc is the contract
between the frontend builder pipeline and the public render API.
The worker payload shape is **stable** — adding new script grammar features
must NOT require worker changes. Map them in `flatToPayloads()` first.
---
## Pipeline (who owns what)
```text
WishesField ← user types brief + uploads media
│
▼
buildScriptFromBrief (server) ← Gemini generates canonical script
│
▼
useFlatScriptBridge ← parses script, mirrors timeline ↔ Code
│
▼
TimelineBlocks ← user-editable cards
│
▼
flatToPayloads() ← THE bridge: script → ScenePayload[]
│
▼
prepare-render (server) ← per-scene asset staging, validation
│
▼
render fleet workers ← Hunyuan / overlay / avatar
```
**Key principle**: the script grammar is the _only_ thing the user (or AI)
authors. Everything downstream — payload shape, worker inputs, asset paths,
voice IDs, transition codes — is derived. Adding new script behavior =
extend `flatToPayloads()`; don't ask AI or users to write payload JSON.
Webhooks
Передайте webhook_url, и VlogMe отправит событие завершения или ошибки с повторными попытками при временной недоступности.
Проверяйте X-Vlogme-Signature по строке timestamp + raw_body с отдельным секретом whsec_ из Settings → API. Отклоняйте timestamp старше пяти минут и удаляйте дубли по X-Vlogme-Event-Id.
Верните любой 2xx за пять секунд. Сетевые ошибки и 5xx повторяются с задержкой, а 4xx считается окончательным отказом. Для просроченной ссылки снова вызовите GET видео.
ts = request.headers["X-Vlogme-Timestamp"]
secret = "whsec_..." # Settings -> API
expected = "sha256=" + hmac_sha256(secret, ts + "." + raw_body).hex()
assert constant_time_eq(expected, request.headers["X-Vlogme-Signature"])
assert abs(now() - int(ts)) < 300MCP‑сервер
Подключите AI‑агента через нативный Streamable HTTP с токеном VlogMe или интерактивным OAuth.
MCP‑инструменты оборачивают REST v1 и используют те же структуры, расчёт кредитов и коды ошибок. Изменения аддитивны, поэтому клиенту следует игнорировать неизвестные поля.
Доступны голоса, баланс, оценка, портреты, запуск, статус, отмена и история. Авторизованные внутренние аккаунты также могут работать с задачами.
POST https://dev.vlogme.ai/api/mcpscript_grammar_helplist_voicesget_balanceestimate_creditslist_portraitsgenerate_videoget_videocancel_videolist_my_videoslist_bugsget_bugreport_bugupdate_bug_statusНастройка клиентов
Claude Code, Cursor и Codex поддерживают Streamable HTTP. Старые stdio‑клиенты подключаются через mcp-remote.
Выберите один режим авторизации: интерактивный OAuth или API token в переменной окружения. Не смешивайте их.
После изменения MCP‑конфигурации начните новую сессию клиента, чтобы он повторно обнаружил инструменты.
# OAuth
codex mcp add vlogme --url https://dev.vlogme.ai/api/mcp
codex mcp login vlogme --scopes mcp:full,mcp:work_items
# or API token
export VLOGME_TOKEN=vlm_live_xxxxxxxxxxxx
codex mcp add vlogme --url https://dev.vlogme.ai/api/mcp --bearer-token-env-var VLOGME_TOKEN{
"mcpServers": {
"vlogme": {
"url": "https://dev.vlogme.ai/api/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN_HERE" }
}
}
}Полный пример работы агента
Запрос на обычном языке превращается в последовательность видимых и проверяемых вызовов инструментов.
Агент может получить список голосов, оценить рендер, запросить подтверждение, вызвать generate_video и проверять get_video до конечного статуса.
Нужны доступный портрет, подходящий тариф и достаточный баланс. Ограничения тарифа одинаковы для MCP и REST.
Create a 16:9 talking-avatar video from this portrait.
Use a warm, natural voice. Estimate the credits first and ask before generating.
After approval, monitor the job and return the final download URL.Skill для агента
Короткая инструкция учит агента оценивать стоимость, запрашивать подтверждение и правильно отслеживать асинхронную задачу.
Опишите, когда применять VlogMe, какие инструменты вызывать, как сохранять идемпотентность и когда прекращать опрос.
Не вставляйте рабочий токен в skill‑файл. Храните его в окружении клиента или OAuth store.
---
name: vlogme-video
description: Estimate and generate VlogMe video jobs through MCP.
---
1. Validate the portrait and requested format.
2. Call estimate_credits before a paid generation.
3. Ask for approval with the estimate.
4. Use a stable idempotency key for transport retries.
5. Poll get_video until a terminal status.Ошибки и повторные запросы
Ошибки имеют форму { error: { code, message } }. В логике используйте стабильный code, а не переводимый текст message.
При обращении в поддержку передайте X-Request-Id. Ответ 429 содержит Retry-After; ошибки авторизации и входных данных нужно исправлять, а не повторять бесконечно.
Полный список схем и ошибок находится в OpenAPI. Успешные ответы содержат limit, remaining и reset для rate limit.
missing_token401{ error: { code: "missing_token", message } }invalid_token401{ error: { code: "invalid_token", message } }token_expired401{ error: { code: "token_expired", message } }plan_required403{ error: { code: "plan_required", message } }insufficient_credits402{ error: { code: "insufficient_credits", message } }invalid_input400{ error: { code: "invalid_input", message } }invalid_asset400{ error: { code: "invalid_asset", message } }invalid_json400{ error: { code: "invalid_json", message } }not_found404{ error: { code: "not_found", message } }method_not_allowed405{ error: { code: "method_not_allowed", message } }already_started409{ error: { code: "already_started", message } }billing_conflict409{ error: { code: "billing_conflict", message } }rate_limited429{ error: { code: "rate_limited", message } }internal_error500{ error: { code: "internal_error", message } }