Create AI Subtitles

Generate AI subtitles (TRANSCRIPTION from audio or TRANSLATION of an existing subtitle) for a video.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

POST /aiworkflow

Generate AI subtitles for a video using artificial intelligence. This endpoint drives two subtitle operations, selected by the type field:

  • TRANSCRIPTION — generates a brand-new subtitle from the video audio (use when the video has no subtitle in the source language yet). Supports generating several languages at once via additional_langs.
  • TRANSLATIONtranslates an existing subtitle into one or more target languages (use when the video already has a subtitle in from_lang).

Both consume AI credits.

📘

Authorization

Send your API token in the Authorization header. For sub-accounts, use the parent account's API token.

🚧

Parameters go in the JSON request body — not the query string

All fields below are sent in the request body (Content-Type: application/json). The body may be a single object or an array of objects (batch — used to translate into several languages in one call).

🚧

TRANSLATION requires an existing source subtitle

TRANSLATION does not create a subtitle from scratch — it translates one that already exists. The video must already have a subtitle in from_lang, otherwise the request fails with 400 "You need to create a from_lang subtitle first".

To subtitle a video that has no subtitles yet, use TRANSCRIPTION first (it reads the audio), then TRANSLATION for the extra languages — or generate the extra languages in one shot with TRANSCRIPTION + additional_langs.

HTTP Method & Path

POST /aiworkflow

Base URL: https://api-v2.pandavideo.com.br

Authentication Requirements

Security SchemeHeaderNote
apiKeyAuthorizationYour API token (no "Bearer" prefix)

Parameters

ParameterTypeRequiredDescription
AuthorizationstringYesYour API token

Request Body

Content-Type: application/json

Body Parameters

ParameterTypeRequiredDescription
typestringYesOperation type. For subtitles: TRANSCRIPTION (from audio) or TRANSLATION (translate an existing subtitle).
video_idstring (uuid)YesThe video ID that will receive the subtitles.
from_langstringYes*Source language of the video/subtitle. The accepted set depends on tier: on essential only pt-BR, es and en are accepted, and auto is rejected with 403 Forbidden ("Language 'auto' is not available for the Essential tier"). On advanced and pro, auto is accepted and triggers language auto-detection. Required for TRANSCRIPTION and TRANSLATION. For TRANSLATION, a subtitle in this language must already exist.
to_langstringCond.Target language. Required for TRANSLATION. Not used by TRANSCRIPTION (use additional_langs instead). Must not already exist as a subtitle.
tierstringYes*AI processing level: essential, pro or advanced. *Required for TRANSCRIPTION and TRANSLATION.
additional_langsarray<object>No(TRANSCRIPTION) Extra target languages generated in the same request. Array of objects, e.g. [{ "lang": "en" }, { "lang": "es" }] — not plain strings.
⚠️

Required fields depend on type

type and video_id are always required. from_lang is required for both operations. to_lang is required only for TRANSLATION. tier is required for both.

Operation modes

TRANSCRIPTION — create a subtitle from the audio

Send a single object with type: "TRANSCRIPTION", from_lang, tier, and (optionally) additional_langs for extra languages.

{
  "type": "TRANSCRIPTION",
  "video_id": "b5f1a2c3-....-uuid",
  "from_lang": "pt-BR",
  "tier": "essential",
  "additional_langs": [{ "lang": "en" }, { "lang": "es" }]
}
⚠️

A language is transcribed only once

TRANSCRIPTION fails with 400 "Subtitles already exist for this lang, please delete them first" when the video already has an AI-generated or uploaded subtitle in from_lang.

In most cases you don't need to transcribe again:

  • To get subtitles in other languages, use TRANSLATION (from_lang = the language you already have, to_lang = the new one). It reuses the existing subtitle — no deletion required.
  • Only delete and re-transcribe if you specifically want to regenerate the source-language subtitle itself.

Only one transcription per video can run at a time — a second concurrent call returns 400 "There is already a transcription work in progress for video ...".

TRANSLATION — translate an existing subtitle

The body is an array, one object per target language. Each object needs to_lang.

[
  { "type": "TRANSLATION", "video_id": "b5f1a2c3-....-uuid", "from_lang": "pt-BR", "to_lang": "en", "tier": "essential" },
  { "type": "TRANSLATION", "video_id": "b5f1a2c3-....-uuid", "from_lang": "pt-BR", "to_lang": "es", "tier": "essential" }
]
📘

Language codes

Both from_lang/to_lang accept BCP-47-style codes: pt-BR, en, en-US, es, it, fr, de, ja, zh, hi, ko, nl, tr, pl, sv, ru, ar, and more. from_lang also accepts auto (transcription only).

Response

Success Response (200)

Returns the created workflow item(s). Processing is asynchronous — the item starts in QUEUE/RUNNING and finishes later. Poll GET /aiworkflow?video_id={video_id} to track status.

{
  "id": "work-uuid",
  "video_id": "b5f1a2c3-....-uuid",
  "type": "TRANSCRIPTION",
  "status": "QUEUE",
  "from_lang": "pt-BR",
  "to_lang": null,
  "metadata": {},
  "created_at": "2026-07-03T12:00:00.000Z"
}
📘

Status lifecycle

QUEUERUNNINGFINISHED, or ERROR / SKIPPED.

Error Responses

  • 400 Bad Request — one of:
    • from_lang is required / to_lang is required for TRANSLATION / tier is required — missing required field for the chosen type.
    • You need to create a from_lang subtitle firstTRANSLATION on a video that has no subtitle in from_lang. Create it with TRANSCRIPTION first.
    • You need to delete the to_lang subtitle firstTRANSLATION target language already has a subtitle.
    • Subtitles already exist for this lang, please delete them firstTRANSCRIPTION on a from_lang that already has a subtitle (use TRANSLATION for other languages instead).
    • There is already a transcription work in progress for video ... / There is already a translation in progress for this video — a matching job is already running (one at a time per video/language).
    • Organization not found for user — the token's user has no organization.
  • 401 Unauthorized — missing or invalid API token.
  • 404 Not FoundVideo with id {video_id} not found.
  • 500 Internal Server Error — unexpected server error.

Example Usage

cURL — TRANSCRIPTION

curl --request POST \
  --url https://api-v2.pandavideo.com.br/aiworkflow \
  --header 'Authorization: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"type":"TRANSCRIPTION","video_id":"<video_id>","from_lang":"pt-BR","tier":"essential","additional_langs":[{"lang":"en"}]}'

cURL — TRANSLATION

curl --request POST \
  --url https://api-v2.pandavideo.com.br/aiworkflow \
  --header 'Authorization: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '[{"type":"TRANSLATION","video_id":"<video_id>","from_lang":"pt-BR","to_lang":"en","tier":"essential"}]'
Body Params
string
required
string
enum
required
string
enum
required
string
enum
required
Allowed:
string
required
Defaults to TRANSCRIPTION
additional_langs
array

en, pt, es, en-UK, pt-BR, es-MX, en-US, it, it-ch, fr, fr-be, fr-ca, fr-lu, fr-ch, de, de-at, de-li, de-lu, de-ch, ja, zh, hi, ko, vi, th, no, hu, sw, sr, id, nl, tr, fil, pl, sv, bg, ro, ar, cs, el, fi, hr, sk, da, uk, ru, ta, ms, uz

additional_langs
Responses

Language
Credentials
Header
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json