Veed Subtitles API Documentation
Playground
Try it on WaveSpeedAI!VEED Subtitles is a fast AI video subtitle generation model that adds styled captions to videos using automatic transcription or supplied SRT files and subtitle content. Ready-to-use REST inference API for subtitled MP4 generation, social media videos, creator content, marketing clips, accessibility workflows, video localization, and professional captioning with simple integration, no coldstarts, and affordable pricing.
Features
VEED Subtitles adds styled subtitles to videos using automatic transcription or an optional SRT subtitle file. Choose subtitle presets, positions, shadow styles, languages, and output resolution tiers.
Why Choose This?
-
Automatic transcription
Upload a video and automatically generate subtitles. -
Optional SRT subtitles
Upload an SRT file or provide raw SRT content when exact subtitle text and timing are required. -
Multiple subtitle styles
Choose from standard and dynamic subtitle presets. -
Position and shadow controls
Adjust subtitle placement and shadow strength for better readability. -
Multiple resolution tiers
Generate subtitled videos in480p,720p, or1080p.
Parameters
| Parameter | Required | Description |
|---|---|---|
| video | Yes | Input video. |
| target_resolution | No | Output resolution tier: 480p, 720p, or 1080p. Default: 720p. |
| preset | No | Subtitle visual preset. Default: simple. Standard and dynamic presets are supported. Dynamic presets use a higher pricing tier. |
| position | No | Subtitle position: top, center, or bottom. Default: bottom. |
| shadow | No | Text shadow strength: none, min, mid, or max. Default: mid. |
| language | No | Optional transcription language locale, such as en-US or zh-CN. Leave empty to automatically detect the language. |
| file | No | Optional SRT subtitle file. Do not use together with srt_content. |
| srt_content | No | Optional raw SRT subtitle content. Do not use together with file. |
How to Use
- Upload a video — Select the video you want to subtitle.
- Choose a resolution — Select
480p,720p, or1080p. - Choose a preset — Select a standard or dynamic subtitle style.
- Set position and shadow — Adjust subtitle placement and readability if needed.
- Choose a language optional — Select a transcription language or leave it empty for automatic detection.
- Provide subtitles optional — Upload an SRT
fileor enter rawsrt_content. - Submit — Generate and download the subtitled video.
Pricing
Pricing depends on input video duration, selected resolution, and whether the selected subtitle preset is standard or dynamic.
Billing Rules
- Base price: $0.11 per input-video minute
- Minimum billed duration: 60 seconds
- Maximum processed and billed duration: 120 seconds
- Duration is rounded up to the next whole second
480pand720puse the base resolution multiplier1080puses a 2× resolution multiplier- Dynamic presets use an additional 2× preset multiplier
- Resolution and dynamic-preset multipliers are cumulative
position,shadow,language,file, andsrt_contentdo not affect pricing
Example Costs
| Billed Duration | 480p / 720p Standard | 480p / 720p Dynamic | 1080p Standard | 1080p Dynamic |
|---|---|---|---|---|
| 60 seconds | $0.11 | $0.22 | $0.22 | $0.44 |
| 90 seconds | $0.165 | $0.33 | $0.33 | $0.66 |
| 120 seconds | $0.22 | $0.44 | $0.44 | $0.88 |
Best Use Cases
- Social media videos — Add styled captions to reels, shorts, and promotional clips.
- Interviews and talking-head videos — Improve accessibility and viewer retention.
- Branded content — Choose subtitle presets that match the visual tone of your content.
- Multilingual content — Select a supported transcription language when automatic detection is not preferred.
- SRT workflows — Burn existing subtitle files or raw SRT content into a video.
Pro Tips
- Leave
languageempty when you want automatic language detection. - Use either
fileorsrt_content, not both. - Use a standard preset for lower-cost subtitle generation.
- Dynamic presets provide more animated styling but cost twice as much as standard presets.
- Selecting
1080pdoubles the resolution price. - Combining
1080pwith a dynamic preset results in a 4× total multiplier. - Videos longer than 120 seconds are processed only up to the first 120 seconds.
Notes
videois required.target_resolutiondefaults to720p.presetdefaults tosimple.positiondefaults tobottom.shadowdefaults tomid.- The maximum processed video duration is 120 seconds.
- Uploading both
fileandsrt_contentin the same request is not supported.
Authentication
For authentication details, please refer to the Authentication Guide.
API Endpoints
Submit Task & Query Result
set -euo pipefail
export WAVESPEED_API_KEY="your-api-key"
REQUEST_BODY=$(cat <<'JSON'
{
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"target_resolution": "720p",
"preset": "simple",
"position": "bottom",
"shadow": "mid",
"language": "af-ZA"
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/veed/subtitles" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}")
TASK=$(printf '%s' "${SUBMIT_RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "${TASK}" | jq -r '.id // empty')
if [ -z "${PREDICTION_ID}" ]; then
printf 'Submission response did not contain a prediction id
' >&2
exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"
# 2. Poll until the prediction finishes.
while true; do
RESPONSE=$(curl --silent --show-error --fail-with-body \
"${RESULT_URL}" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}")
RESULT=$(printf '%s' "${RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')
case "${STATUS}" in
completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
failed|cancelled|timeout|deleted) printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
*) sleep 2 ;;
esac
doneParameters
Task Submission Parameters
Request Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
| video | string | Yes | - | Input video URL. | |
| target_resolution | string | No | 720p | 480p, 720p, 1080p | Maximum resolution box used before subtitle generation. |
| preset | string | No | simple | simple, plain, glass, whisper, glide2, fusion, glide, terminal, handwritten, backdrop, backdrop2, beans, corpo, boo, shadeplay, casper, capri, lowkey, vinta, diego, ali, slay, kitty, hustle, karl, sprout, flex, mint, rizz, vegas | Subtitle visual preset. |
| position | string | No | bottom | top, center, bottom | Subtitle position. |
| shadow | string | No | mid | none, min, mid, max | Text shadow strength. |
| language | string | No | - | af-ZA, am-ET, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IL, ar-IQ, ar-JO, ar-KW, ar-LB, ar-MA, ar-MR, ar-OM, ar-PS, ar-QA, ar-SA, ar-TN, ar-YE, az-AZ, bg-BG, bn-BD, bn-IN, bs-BA, ca-ES, cs-CZ, cy-GB, da-DK, de-AT, de-CH, de-DE, el-GR, en-AU, en-CA, en-GB, en-GH, en-HK, en-IE, en-IN, en-KE, en-NG, en-NZ, en-PH, en-PK, en-SG, en-TZ, en-US, en-ZA, es-AR, es-BO, es-CL, es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, es-GQ, es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, eu-ES, fa-IR, fi-FI, fil-PH, fr-BE, fr-CA, fr-CH, fr-FR, gl-ES, gu-IN, he-IL, hi-IN, hr-HR, hu-HU, hy-AM, id-ID, is-IS, it-CH, it-IT, ja-JP, jv-ID, ka-GE, kk-KZ, km-KH, kn-IN, ko-KR, lo-LA, lt-LT, lv-LV, mk-MK, ml-IN, mn-MN, mr-IN, ms-MY, my-MM, ne-NP, nl-BE, nl-NL, no-NO, pa-Guru-IN, pl-PL, ps-AF, pt-BR, pt-PT, ro-RO, ru-RU, si-LK, sk-SK, sl-SI, so-SO, sq-AL, sr-RS, su-ID, sv-SE, sw-KE, sw-TZ, ta-IN, ta-LK, ta-MY, ta-SG, te-IN, th-TH, tr-TR, uk-UA, ur-IN, ur-PK, uz-UZ, vi-VN, zh-CN, zh-HK, zh-TW, zu-ZA | Optional transcription language locale, such as en-US or zh-CN. Leave empty to auto-detect. |
| file | string | No | - | - | Optional SRT subtitle file. Do not use together with srt_content. |
| srt_content | string | No | - | - | Optional raw SRT subtitle content. Do not use together with file. |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data.id | string | Unique identifier for the prediction, Task Id |
| data.model | string | Model ID used for the prediction |
| data.outputs | array | Output values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed) |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Task status. completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses. |
| data.created_at | string | ISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”) |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |
Result Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | Yes | - | Task ID |
Result Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data | object | The prediction data object containing all details |
| data.id | string | Unique identifier for the prediction |
| data.model | string | Model ID used for the prediction |
| data.outputs | array<string | object> | Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model. |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Status: completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses |
| data.created_at | string | ISO timestamp of when the request was created |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |