curl --request POST \
--url https://api.captioncraft.studio/v1/subtitles \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"video_url": "https://your-cdn.example/video.mp4",
"preset": "highlight",
"max_duration_seconds": 60,
"style": {
"highlight_color": "#7651E8"
}
}
'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
video_url: 'https://your-cdn.example/video.mp4',
preset: 'highlight',
max_duration_seconds: 60,
style: {highlight_color: '#7651E8'}
})
};
fetch('https://api.captioncraft.studio/v1/subtitles', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.captioncraft.studio/v1/subtitles"
payload = {
"video_url": "https://your-cdn.example/video.mp4",
"preset": "highlight",
"max_duration_seconds": 60,
"style": { "highlight_color": "#7651E8" }
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "example_job_id",
"status": "ingesting",
"status_url": "https://api.captioncraft.studio/v1/jobs/example_job_id",
"replayed": false
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}Create subtitles
Create a captioned video and reserve prepaid seconds.
curl --request POST \
--url https://api.captioncraft.studio/v1/subtitles \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"video_url": "https://your-cdn.example/video.mp4",
"preset": "highlight",
"max_duration_seconds": 60,
"style": {
"highlight_color": "#7651E8"
}
}
'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
video_url: 'https://your-cdn.example/video.mp4',
preset: 'highlight',
max_duration_seconds: 60,
style: {highlight_color: '#7651E8'}
})
};
fetch('https://api.captioncraft.studio/v1/subtitles', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.captioncraft.studio/v1/subtitles"
payload = {
"video_url": "https://your-cdn.example/video.mp4",
"preset": "highlight",
"max_duration_seconds": 60,
"style": { "highlight_color": "#7651E8" }
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "example_job_id",
"status": "ingesting",
"status_url": "https://api.captioncraft.studio/v1/jobs/example_job_id",
"replayed": false
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}subtitles:write. Submit a direct HTTPS video URL and poll the returned status_url every five seconds.
Choose any of the 16 presets and optionally override typography, layout, background, outline, shadow, and applicable highlight colors through style. Omitted fields inherit the preset, including fields within nested objects. Caption styles explains all controls and preset-specific behavior.
max_duration_seconds. This limit does not trim the video. Successful jobs are billed for actual duration rounded up; failed and canceled jobs release the reservation.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Reuse with the same input to retry safely. Different input with the same key returns 409.
8 - 128^[A-Za-z0-9._:-]{8,128}$Body
Direct HTTPS MP4, MOV, or WebM URL. No redirects or extra auth headers. Maximum 500 MiB; must remain valid until downloaded.
4096"https://your-cdn.example/video.mp4"
Caption preset. Omitted style properties use this preset's defaults.
classic, highlight, smash, box, push, elegant, ogre, outline, paper-ink, action, prompter, storytelling, karaoke, glow, thin&bold, background Optional lowercase two- or three-letter language code supported by transcription. Omit for automatic language detection. Does not translate.
^[a-z]{2,3}$"en"
Hard duration limit and initial prepaid reservation. Does not trim the video. Actual duration must fit this limit.
1 <= x <= 600Optional caption style overrides. Omitted fields (including nested fields) inherit the selected preset. GET /v1/presets lists defaults, supported controls and preset-specific behavior.
Show child attributes
Show child attributes