AI: Texts & Animated Subtitles
The AI features of the post form, from the API: write a post’s texts from what is said in a video, and burn animated subtitles into it.
Billed in credits: 1 AI minute per started minute of video, from the plan’s monthly AI minutes first, then purchased credits. A video is transcribed and billed once: generating its texts and then its subtitles pays once. Rendering the subtitles is included. Videos up to 30 minutes. In a team, the team owner’s plan pays. GET /x-credits returns what is left in ai.
mediaUrl is a video you uploaded (presign or a previous post), or any public https video URL.
Texts from a video
POST /api/v1/ai/post-text — scope posts:write.
| Field | Required | Description |
|---|---|---|
mediaUrl | Yes | The video. |
platforms | Yes | Platforms to write for, e.g. ["tiktok", "instagram", "youtube"]. |
accountIds | No | Accounts the post will go to: their best-performing hashtags are reused. |
draft | No | Your own draft or instructions to take into account (5,000 characters max). |
curl -X POST https://api.multi-upload-tool.com/api/v1/ai/post-text \
-H "x-api-key: YOUR_API_TOKEN" -H "Content-Type: application/json" \
-d '{ "mediaUrl": "https://example.com/video.mp4", "platforms": ["tiktok", "youtube"] }'{
"success": true,
"data": {
"title": "3 tips for short videos",
"description": "Three simple tips to get more views on your short videos. #shortvideo #tips",
"hashtags": ["shortvideo", "tips"],
"captions": [
{ "platform": "tiktok", "text": "3 tips nobody tells you 👇 #shortvideo #tips" },
{ "platform": "youtube", "text": "Three simple tips to get more views on your short videos." }
],
"language": "en",
"minutesCharged": 1
}
}Texts are written in the video’s language. Nothing is published: pass them to POST /upload. minutesCharged is 0 when the video was already transcribed.
Animated subtitles
POST /api/v1/ai/captions — scope posts:write. Transcribes the video, lets the AI pick the keywords (and emojis), then renders the subtitles into a new video in the background, usually in under a minute.
| Field | Default | Description |
|---|---|---|
mediaUrl | — | The video (required). |
theme | hormozi | hormozi (bold uppercase, spoken word in yellow), beast, box (text on a dark box), single (one word at a time), minimal, podcast. |
position | theme’s | Vertical centre of the line: 0 top, 1 bottom. |
scale | 1 | Text size, 0.5 to 2. |
wordsPerLine | theme’s | 1 to 8. More words per line = lines change less often, a calmer pace. |
highlights | true | Keywords in colour. |
emojis | false | One emoji above each line when the AI picked one. |
emojiStyle | noto | noto (flat Google emojis) or fluent (3D). |
colors | theme’s | { "text", "active", "highlight" } as #RRGGBB: text, spoken word, keywords. |
enter | theme’s | How a line comes in: pop, fade or none. |
exit | none | How a line goes out: fade or none. |
curl -X POST https://api.multi-upload-tool.com/api/v1/ai/captions \
-H "x-api-key: YOUR_API_TOKEN" -H "Content-Type: application/json" \
-d '{ "mediaUrl": "https://example.com/video.mp4", "theme": "minimal", "enter": "fade", "exit": "fade" }'{ "success": true, "data": { "jobId": "1234", "minutesCharged": 1 } }Get the captioned video
GET /api/v1/ai/captions/{jobId} — scope posts:read. Poll every few seconds until state is completed (with url) or failed (with error).
{ "success": true, "data": { "state": "completed", "url": "https://api.multi-upload-tool.com/api/public/image-proxy/public-api/42/1730000000000-captioned.mp4" } }Publish url with POST /upload instead of the original video.
Errors
| Status | When |
|---|---|
400 | Unknown theme (checked before anything is billed). |
402 | Not enough AI minutes or credits for this video. |
403 | The URL points to another user’s upload. |
409 | The same video is already being transcribed by another call: retry in a minute, it will not be billed twice. |
422 | The file is not a readable video, is longer than 30 minutes, or has no speech (not billed). |
404 | Unknown jobId, or a render started by another user. |