Skip to main content
VMEG offers two independent Open APIs. They share authentication, idempotency, and the response envelope, but their data is separate: use one API end to end for a job (upload → create → poll).

When to use which

  • Standalone — fully automated back-end pipelines that need webhooks, TTS, or text translation, and never open the website.
  • App-Synced — you want API submission but still edit subtitles, voices, or timing in the VMEG editor and export from the website.

Protocol differences (App-Synced)

Access
  • The API key must belong to a VMEG website account (create it on the website); other keys get 401.
  • Voice cloning requires a plan with voice cloning; otherwise 403.
Creating a job
  • options is optional; defaults match a website job with automatic voice cloning.
  • source accepts exactly one of materialId or youtubeUrl (a YouTube link, no upload needed). taskType must match the material: vt for video, at for audio.
  • title sets the job name in My tasks; it defaults to the file name or YouTube video title.
  • Optional subtitle files (source.subtitleMaterialId, source.targetSubtitleMaterialId) must be .srt materials.
  • options.voiceClone.style also accepts auto, tutorial, drama, and smart.
  • Manual voice picking (voiceSpeakers.selectedVoicesList) accepts sv_* system voices and cv_* voices from List cloned voices. It cannot be combined with voiceClone, and dubbingVersion: V2 cannot be combined with either.
  • Burned-in subtitles use options.subtitle (type plus an optional templateId from List subtitle templates) instead of options.text. They are off by default, as on the website; with type but no templateId, the website’s default style is used.
  • options.lipsync requires a video of at least 360 × 360 px, as on the website; lower resolutions return 400. YouTube sources are not pre-checked.
  • Subtitle removal and on-screen text translation from the website form are not supported yet; jobs are created with both turned off.
  • source.sourceUrl, options.text, output, extraData, and the material mimeType filter return 400. Other unknown fields are ignored.
  • Single-file uploads are de-duplicated by fileHash: a file already in your website library returns the existing material, and deleting it also removes it from My assets.
Results
  • The acceptance response and job detail include editorUrl.
  • Job detail returns result.outputs, newest first; result.outputs[0] is the latest successful render.
  • finished is not permanent: re-exporting on the website sets the job back to running, and a failed re-export ends in failed while earlier outputs stay in the list.
Voice cloning
  • The call is synchronous and returns the new cv_* voice; it can take tens of seconds.
  • Accepts refAudioMaterialId (an uploaded material) as an alternative to refAudio; voiceName and sampleText are required.
Material IDs, cloned voice IDs (cv_*), and task IDs are not interchangeable: an ID from the Standalone API returns 404 on App-Synced, and vice versa. System voice IDs (sv_*) work on both.

Workflow

1

Upload

POST /openapi/v1/app/assets/material/upload/gen-upload-url, PUT the file, then .../upload/complete (or the multipart endpoints for large files). For YouTube videos, skip upload and pass source.youtubeUrl.
2

Pick voices (optional)

List .../assets/voice/basic/list and .../assets/voice/clone/list, or clone one with .../task/clone-voice/create.
3

Create the job

POST /openapi/v1/app/task/media-translation/create-async with X-Idempotency-Key.
4

Poll

GET /openapi/v1/app/tasks/detail?taskId=... until status is finished or failed. Open editorUrl to edit and re-export. The status matches the website, so set a polling timeout: if a job stays running far longer than usual, contact support with the taskId.
See the full App-Synced API reference. Guides linked from the reference are written for the Standalone API; the steps are the same with the /openapi/v1/app prefix.