Add Subtitle API¶
Pricing¶
35 credits per request
Fixed cost regardless of video length or subtitle content length.
Overview¶
The Add Subtitle API adds subtitles/captions to videos with timed entries (CapCut style). Text is automatically split into multiple entries based on max_words_per_line and evenly distributed across the video duration.
Domain: api.revidapi.com
Endpoints¶
Main Endpoint¶
POST https://revidapi.com/v1/add-subtitle
Authentication: Required - Header x-api-key
Domain: api.revidapi.com
The main endpoint for adding subtitles with automatic text splitting. Text is automatically divided into timed entries based on max_words_per_line and distributed evenly across the video duration.
Alternative Endpoint: Add Subtitle from SRT File¶
POST https://revidapi.com/v1/add-subtitle-from-srt
Authentication: Required - Header x-api-key
Domain: api.revidapi.com
Accepts an SRT file URL directly. Useful when you already have a formatted SRT file with timing information. See the detailed section below.
Alternative Endpoint: Add Timed Subtitle¶
POST https://revidapi.com/v1/add-timed-subtitle
Authentication: Required - Header X-API-Key
Domain: edit.revidapi.com
Adds subtitles with precise timing control. Requires exact timed entries array, giving you full control over when each subtitle appears. See the detailed section below.
Request¶
Headers¶
x-api-key: Required. Your API key for authentication.Content-Type: Required. Must beapplication/json.
Body Parameters¶
Required Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
video_url |
string (URI) | ✅ Yes | - | URL of the video file (usually the blurred video) |
subtitle_text |
string | ✅ Yes | - | Subtitle text (will be automatically split into entries) |
Optional Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
timed_entries |
array | ❌ No | null |
List of timed entries from TTS (sync with voice) |
audio_duration |
number | ❌ No | null |
Duration of TTS audio (for sync) |
settings |
object | ❌ No | {} |
Styling options (see Settings Schema below) |
webhook_url |
string (URI) | ❌ No | - | URL to receive the result when processing is complete |
id |
string | ❌ No | - | Custom identifier for tracking the request |
Settings Schema¶
{
"text_color": "string (optional)",
"word_color": "string (optional)",
"outline_color": "string (optional)",
"all_caps": "boolean (optional)",
"max_words_per_line": "integer (optional)",
"position_x": "integer (optional)",
"position_y": "integer (optional)",
"position": "string (optional)",
"alignment": "string (optional)",
"font_family": "string (optional)",
"font_size": "integer (optional)",
"bold": "boolean (optional)",
"italic": "boolean (optional)",
"underline": "boolean (optional)",
"strikeout": "boolean (optional)",
"style": "string (optional)",
"outline_width": "integer (optional)",
"spacing": "integer (optional)",
"angle": "integer (optional)",
"shadow_offset": "integer (optional)",
"language": "string (optional)"
}
Settings Parameters¶
Colors¶
| Parameter | Type | Default | Description |
|---|---|---|---|
text_color |
string | "#FFFFFF" |
Main text color (hex format) |
word_color |
string | "#FFFF00" |
Highlight color (used for karaoke/highlight style) |
outline_color |
string | "#000000" |
Outline color (hex format) |
outline_width |
integer | 3 |
Outline thickness (1-10) |
shadow_offset |
integer | 2 |
Shadow offset (0-10) |
Font & Typography¶
| Parameter | Type | Default | Description |
|---|---|---|---|
font_family |
string | "Be Vietnam Pro" |
Font name (see /fonts/{language}) |
font_size |
integer | 48 |
Font size (20-100) |
bold |
boolean | false |
Bold text |
italic |
boolean | false |
Italic text |
underline |
boolean | false |
Underline text |
strikeout |
boolean | false |
Strikethrough text |
all_caps |
boolean | false |
Convert all text to uppercase |
spacing |
integer | 0 |
Character spacing (0-50) |
angle |
integer | 0 |
Rotation angle (degrees, -180 to 180) |
language |
string | "vi" |
Language (for font selection) |
Position¶
| Parameter | Type | Default | Description |
|---|---|---|---|
position_x |
integer | null |
Exact X coordinate (center of caption area) |
position_y |
integer | null |
Exact Y coordinate (center of caption area) |
position |
string | null |
Position preset: top_left, top_center, top_right, middle_left, middle_center, middle_right, bottom_left, bottom_center, bottom_right |
alignment |
string | null |
Text alignment: left, center, right |
⚠️ IMPORTANT:
- Use position_x and position_y (no alias x, y)
- Get from caption_area of detect-caption to match blur position
- Backend automatically uses center alignment when exact position is provided
Calculation:
position_x = caption_area.x + caption_area.w / 2
position_y = caption_area.y + caption_area.h / 2
Style Effects¶
| Parameter | Type | Default | Description |
|---|---|---|---|
style |
string | "classic" |
Style effect: classic, karaoke, highlight, underline, word_by_word |
Style Options:
- classic: Display all text at once, no animation (suitable for regular subtitles)
- karaoke: Highlight words sequentially (using word_color) - like karaoke
- highlight: Display full text, highlight words sequentially (using word_color)
- underline: Display full text, underline words sequentially
- word_by_word: Display one word at a time (fade in/out)
Text Layout¶
| Parameter | Type | Default | Description |
|---|---|---|---|
max_words_per_line |
integer | 6 |
Maximum words per line (3-10) |
Subtitle Logic¶
Auto-split (Default)¶
1. Download video
2. Automatically split text into entries:
- Each entry: max_words_per_line words
- Evenly distributed across video duration
- Example: Video 49s, 100 words → ~2s/entry
3. Create ASS file with styling
4. FFmpeg burn subtitle into video
5. Keep original audio
Sync with TTS (Recommended)¶
Option 1: Use timed_entries
{
"video_url": "...",
"subtitle_text": "...",
"timed_entries": [
{"start_time": 0.0, "end_time": 2.5, "text": "First sentence"},
{"start_time": 2.5, "end_time": 5.0, "text": "Second sentence"}
]
}
Option 2: Use audio_duration
{
"video_url": "...",
"subtitle_text": "...",
"audio_duration": 49.5
}
Option 3: Use SRT File (Separate Endpoint)
Use the /add-subtitle-from-srt endpoint with an SRT file URL.
Alternative Endpoint: Add Subtitle from SRT File¶
Endpoint¶
POST https://revidapi.com/v1/add-subtitle-from-srt
Authentication: Required - Header x-api-key
This endpoint accepts an SRT (SubRip Subtitle) file URL directly. The SRT file contains pre-formatted timed entries, eliminating the need for manual text splitting.
Request Body¶
Required Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
video_url |
string (URI) | ✅ Yes | URL of the video file (usually the blurred video) |
srt_url |
string (URI) | ✅ Yes | URL of the SRT subtitle file |
Optional Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
settings |
object | ❌ No | {} |
Styling options (see Settings Schema above) |
webhook_url |
string (URI) | ❌ No | - | URL to receive the result when processing is complete |
id |
string | ❌ No | - | Custom identifier for tracking the request |
SRT File Format¶
The SRT file should follow the standard SubRip format:
1
00:00:00,000 --> 00:00:02,500
First subtitle line
Second subtitle line
2
00:00:02,500 --> 00:00:05,000
Next subtitle entry
3
00:00:05,000 --> 00:00:07,500
Another subtitle entry
SRT Format Requirements:
- Sequential entry numbers
- Time format: HH:MM:SS,mmm --> HH:MM:SS,mmm
- Each entry separated by blank line
- Text can span multiple lines per entry
Example Request¶
curl -X POST "https://revidapi.com/v1/add-subtitle-from-srt" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"srt_url": "https://example.com/subtitles.srt",
"settings": {
"font_family": "Be Vietnam Pro",
"font_size": 48,
"text_color": "#FFFFFF",
"outline_color": "#000000",
"position_x": 288,
"position_y": 688,
"style": "classic"
}
}'
Response format is identical to the main endpoint (returns task_id, use GET /paid/get/job/status/{task_id} to check status).
Alternative Endpoint: Add Timed Subtitle¶
Endpoint¶
POST https://revidapi.com/v1/add-timed-subtitle
Authentication: Header X-API-Key or x-api-key
Adds subtitles with a pre-defined array of timed entries. Use when you already have timing from TTS or an editor.
Request Body¶
Required Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
video_url |
string (URI) | ✅ Yes | URL of the video file (usually the blurred video) |
subtitles |
array | ✅ Yes | Array [{start_time, end_time, text}, ...] |
Optional Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
settings |
object | ❌ No | {} |
Styling options (see Settings Schema above) |
webhook_url |
string (URI) | ❌ No | - | URL to receive the result when processing is complete |
id |
string | ❌ No | - | Custom identifier for tracking the request |
subtitles Format¶
[{"start_time": 0.0, "end_time": 2.5, "text": "Segment 1"}, {"start_time": 2.5, "end_time": 5.0, "text": "Segment 2"}]
Times in seconds (float). start_time < end_time. Get position_x/position_y from detect caption_area.
Example (Working Payload)¶
{
"video_url": "https://edit.revidapi.com/output/video_xxx.mp4",
"subtitles": [{"start_time": 0.0, "end_time": 2.5, "text": "Segment 1"}],
"settings": {
"text_color": "#FFFFFF",
"word_color": "#FFD700",
"outline_color": "#000000",
"all_caps": true,
"font_family": "Montserrat",
"font_size": 38,
"bold": true,
"style": "classic",
"outline_width": 4,
"spacing": 1,
"shadow_offset": 2,
"position_x": 288,
"position_y": 688
}
}
When to Use This Endpoint¶
Use /api/add-timed-subtitle when:
- ✅ You have precise timing requirements (e.g., from video editing software)
- ✅ You want to sync subtitles frame-by-frame with audio
- ✅ You have existing subtitle timing data (SRT, VTT, etc.)
- ✅ You need full control over each subtitle entry's timing
Use the main /paid/add-subtitle endpoint when:
- ✅ You only have text and want automatic splitting
- ✅ You want to distribute text evenly across video duration
- ✅ You have TTS timing data but prefer automatic distribution
Response format is identical to the main endpoint (returns task_id, use GET /api/get/{task_id} to check status on edit.revidapi.com domain).
Response¶
Immediate Response (Task Created)¶
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"status": "pending",
"message": "Task queued",
"type": "subtitle"
}
Task Status (GET /paid/get/job/status/{task_id})¶
✅ Completed¶
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"type": "subtitle",
"status": "completed",
"progress": 100,
"message": "Added 8 subtitle entries successfully",
"result": {
"video_url": "https://storage.example.com/subtitled_output.mp4",
"entries_count": 8
},
"created_at": "2025-12-22T12:28:01.106964"
}
⏳ Processing¶
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"status": "processing",
"progress": 40,
"message": "Created 8 subtitle entries..."
}
❌ Failed¶
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"status": "failed",
"progress": 50,
"message": "FFmpeg error: ..."
}
Example Requests¶
Example 1: Minimal (Using Defaults)¶
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"subtitle_text": "This is the subtitle text that will be displayed..."
}'
Example 2: Full Settings with Style¶
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"subtitle_text": "This is the subtitle text...",
"settings": {
"font_family": "Be Vietnam Pro",
"font_size": 48,
"text_color": "#FFFFFF",
"word_color": "#FFFF00",
"outline_color": "#000000",
"outline_width": 3,
"shadow_offset": 2,
"bold": false,
"italic": false,
"underline": false,
"strikeout": false,
"all_caps": false,
"spacing": 0,
"angle": 0,
"position_x": 288,
"position_y": 688,
"max_words_per_line": 6,
"language": "vi",
"style": "highlight"
}
}'
Example 3: Sync with TTS¶
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"subtitle_text": "This is the subtitle text...",
"audio_duration": 49.5,
"settings": {
"style": "highlight",
"word_color": "#FFFF00"
}
}'
Style Examples¶
The style parameter controls how subtitles are animated and displayed. Each style provides a different visual effect to enhance readability and engagement.
Classic (Default)¶
Description: All text appears at once with the same color. No animation effects. Best for standard subtitles where readability is the priority.
{
"style": "classic",
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3
}
Use Cases: - Standard video subtitles - Professional presentations - Documentary films - Educational content
Example cURL:
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/video.mp4",
"subtitle_text": "Welcome to our tutorial",
"settings": {
"style": "classic",
"text_color": "#FFFFFF",
"font_size": 48
}
}'
Karaoke¶
Description: Text appears word by word, with each word highlighted sequentially using the word_color. The rest of the text remains in text_color. Perfect for karaoke-style videos.
{
"style": "karaoke",
"text_color": "#FFFFFF",
"word_color": "#FFFF00",
"outline_color": "#000000",
"outline_width": 3
}
Use Cases: - Karaoke videos - Music lyric videos - Interactive reading videos - Language learning content
Example cURL:
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/song.mp4",
"subtitle_text": "Sing along with the lyrics",
"settings": {
"style": "karaoke",
"text_color": "#FFFFFF",
"word_color": "#FFD700",
"font_size": 56,
"max_words_per_line": 4
}
}'
Highlight¶
Description: All text is displayed simultaneously, but words are highlighted sequentially using word_color. This creates a reading guide effect while keeping all text visible.
{
"style": "highlight",
"text_color": "#FFFFFF",
"word_color": "#FFFF00",
"outline_color": "#000000",
"outline_width": 3
}
Use Cases: - Children's educational videos - Reading tutorials - Podcast transcripts - Audiobook visualizations
Example cURL:
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/tutorial.mp4",
"subtitle_text": "Follow along as we read each word",
"settings": {
"style": "highlight",
"text_color": "#E0E0E0",
"word_color": "#4CAF50",
"font_size": 52
}
}'
Underline¶
Description: All text is displayed at once, but words are underlined sequentially as they are spoken. Provides a subtle reading guide without changing text color.
{
"style": "underline",
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3
}
Note: The underline parameter in settings controls the underline styling. When using style: "underline", the animation will automatically underline words sequentially.
Use Cases: - Subtle reading guides - Professional presentations - News broadcasts - Interview transcripts
Example cURL:
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/news.mp4",
"subtitle_text": "Breaking news update",
"settings": {
"style": "underline",
"text_color": "#FFFFFF",
"font_size": 48
}
}'
Word by Word¶
Description: Only one word is displayed at a time with a fade in/out effect. Creates a focused, minimal reading experience.
{
"style": "word_by_word",
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3
}
Use Cases: - Minimalist video style - Focused reading content - Meditation/calm videos - Attention-focused tutorials
Example cURL:
curl -X POST "https://revidapi.com/v1/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/meditation.mp4",
"subtitle_text": "Focus on each word",
"settings": {
"style": "word_by_word",
"text_color": "#FFFFFF",
"font_size": 60,
"bold": true
}
}'
Style Comparison Table¶
| Style | Animation | All Text Visible | Best For |
|---|---|---|---|
classic |
None | ✅ Yes | Standard subtitles |
karaoke |
Word highlight | ❌ No (word by word) | Music videos |
highlight |
Word highlight | ✅ Yes | Educational content |
underline |
Word underline | ✅ Yes | Professional content |
word_by_word |
Fade in/out | ❌ No (one at a time) | Focused reading |
Color Recommendations by Style¶
Karaoke & Highlight:
{
"text_color": "#FFFFFF",
"word_color": "#FFFF00" // Bright yellow for visibility
}
Classic & Underline:
{
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3 // Strong outline for readability
}
Word by Word:
{
"text_color": "#FFFFFF",
"bold": true, // Make single words more prominent
"font_size": 60 // Larger font for single word display
}
Fonts by Language¶
Vietnamese ("vi")¶
- Be Vietnam Pro ⭐
- Montserrat
- Quicksand
- Nunito
- Roboto
Chinese ("zh")¶
- Noto Sans SC
- Noto Sans TC
- WenQuanYi Micro Hei
Japanese ("ja")¶
- Noto Sans JP
- M PLUS Rounded 1c
Korean ("ko")¶
- Noto Sans KR
- NanumGothic
View all: GET /fonts/{language}
Full Workflow¶
1. POST /paid/detect-caption
↓
2. GET /paid/get/job/status/{task_id} (loop)
↓ Get caption_area
3. POST /paid/blur-region (use caption_area)
↓
4. GET /paid/get/job/status/{task_id} (loop)
↓ Get video_url
5. POST /paid/add-subtitle (use video_url + caption_area + TTS timing)
↓
6. GET /paid/get/job/status/{task_id} (loop)
↓
7. Download complete video
Usage Notes¶
- Fixed Pricing: This endpoint charges a fixed 35 credits per request, regardless of video length.
- POST returns immediately with
task_id(does not wait for processing) - GET task status to retrieve results (poll in loop)
- Text automatically split into timed entries (if
timed_entriesnot provided) - Position should use
caption_areafrom detect-caption to match blur position - Original audio is preserved (copy stream)
- Sync with TTS: Use
timed_entriesoraudio_durationto sync accurately with voice
Tips¶
- Text too long: Increase
max_words_per_lineto 8-10 - Subtitle too small: Increase
font_sizeto 60-72 - Subtitle misaligned: Use
position_xandposition_yfromcaption_area - Color not clear: Increase
outline_widthto 4-5 - Sync with voice: Use
timed_entriesfrom TTS service oraudio_duration - Karaoke style: Use
style: "karaoke"withword_color: "#FFFF00" - Rotation: Use
angle: 45to rotate subtitle (degrees) - Character spacing: Use
spacing: 5to increase space between characters - All caps: Use
all_caps: trueto convert all text to uppercase - Position: Only use
position_xandposition_y(no alias x, y)
Common Issues¶
- Invalid SRT Format: Ensure SRT files are properly formatted with valid timestamps
- Font Availability: Some fonts may not be available on the server
- Position Clipping: Ensure subtitle position doesn't get clipped by video edges
Best Practices¶
- Use Webhooks: Always use webhooks for better reliability
- Unique IDs: Provide unique
idvalues for tracking - SRT Validation: Validate SRT file format before submission
- Styling Consistency: Use consistent styling across videos for better user experience
- Color Contrast: Ensure sufficient contrast between text and background for readability