Generate AD audio
curl --request POST \
--url https://api.viddyscribe.com/enterprise/api/generate_ad_audio \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"input": {
"type": "media_id",
"media_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"filename": "<string>"
},
"generation_config": {
"format": "json",
"language": "en-US",
"video_category": "Auto",
"voice": "Achernar",
"custom_instructions": "",
"auto_fit": true,
"allow_descriptions_over_music": true,
"volume_level_db": -5,
"audio_track_type": "mixed",
"description_content": "<string>"
}
}
'import requests
url = "https://api.viddyscribe.com/enterprise/api/generate_ad_audio"
payload = {
"input": {
"type": "media_id",
"media_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"filename": "<string>"
},
"generation_config": {
"format": "json",
"language": "en-US",
"video_category": "Auto",
"voice": "Achernar",
"custom_instructions": "",
"auto_fit": True,
"allow_descriptions_over_music": True,
"volume_level_db": -5,
"audio_track_type": "mixed",
"description_content": "<string>"
}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
input: {
type: 'media_id',
media_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
filename: '<string>'
},
generation_config: {
format: 'json',
language: 'en-US',
video_category: 'Auto',
voice: 'Achernar',
custom_instructions: '',
auto_fit: true,
allow_descriptions_over_music: true,
volume_level_db: -5,
audio_track_type: 'mixed',
description_content: '<string>'
}
})
};
fetch('https://api.viddyscribe.com/enterprise/api/generate_ad_audio', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.viddyscribe.com/enterprise/api/generate_ad_audio",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'input' => [
'type' => 'media_id',
'media_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'filename' => '<string>'
],
'generation_config' => [
'format' => 'json',
'language' => 'en-US',
'video_category' => 'Auto',
'voice' => 'Achernar',
'custom_instructions' => '',
'auto_fit' => true,
'allow_descriptions_over_music' => true,
'volume_level_db' => -5,
'audio_track_type' => 'mixed',
'description_content' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.viddyscribe.com/enterprise/api/generate_ad_audio"
payload := strings.NewReader("{\n \"input\": {\n \"type\": \"media_id\",\n \"media_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"filename\": \"<string>\"\n },\n \"generation_config\": {\n \"format\": \"json\",\n \"language\": \"en-US\",\n \"video_category\": \"Auto\",\n \"voice\": \"Achernar\",\n \"custom_instructions\": \"\",\n \"auto_fit\": true,\n \"allow_descriptions_over_music\": true,\n \"volume_level_db\": -5,\n \"audio_track_type\": \"mixed\",\n \"description_content\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.viddyscribe.com/enterprise/api/generate_ad_audio")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"input\": {\n \"type\": \"media_id\",\n \"media_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"filename\": \"<string>\"\n },\n \"generation_config\": {\n \"format\": \"json\",\n \"language\": \"en-US\",\n \"video_category\": \"Auto\",\n \"voice\": \"Achernar\",\n \"custom_instructions\": \"\",\n \"auto_fit\": true,\n \"allow_descriptions_over_music\": true,\n \"volume_level_db\": -5,\n \"audio_track_type\": \"mixed\",\n \"description_content\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.viddyscribe.com/enterprise/api/generate_ad_audio")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": {\n \"type\": \"media_id\",\n \"media_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"filename\": \"<string>\"\n },\n \"generation_config\": {\n \"format\": \"json\",\n \"language\": \"en-US\",\n \"video_category\": \"Auto\",\n \"voice\": \"Achernar\",\n \"custom_instructions\": \"\",\n \"auto_fit\": true,\n \"allow_descriptions_over_music\": true,\n \"volume_level_db\": -5,\n \"audio_track_type\": \"mixed\",\n \"description_content\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"job_id": "task_abc123xyz",
"status": "queued",
"media_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}Audio Generation
Generate AD Audio
Generate an audio-only track with Audio Descriptions.
Supports Input via media_id, url, or direct file upload.
Returns a job_id for tracking progress.
POST
/
enterprise
/
api
/
generate_ad_audio
Generate AD audio
curl --request POST \
--url https://api.viddyscribe.com/enterprise/api/generate_ad_audio \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"input": {
"type": "media_id",
"media_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"filename": "<string>"
},
"generation_config": {
"format": "json",
"language": "en-US",
"video_category": "Auto",
"voice": "Achernar",
"custom_instructions": "",
"auto_fit": true,
"allow_descriptions_over_music": true,
"volume_level_db": -5,
"audio_track_type": "mixed",
"description_content": "<string>"
}
}
'import requests
url = "https://api.viddyscribe.com/enterprise/api/generate_ad_audio"
payload = {
"input": {
"type": "media_id",
"media_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"filename": "<string>"
},
"generation_config": {
"format": "json",
"language": "en-US",
"video_category": "Auto",
"voice": "Achernar",
"custom_instructions": "",
"auto_fit": True,
"allow_descriptions_over_music": True,
"volume_level_db": -5,
"audio_track_type": "mixed",
"description_content": "<string>"
}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
input: {
type: 'media_id',
media_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
filename: '<string>'
},
generation_config: {
format: 'json',
language: 'en-US',
video_category: 'Auto',
voice: 'Achernar',
custom_instructions: '',
auto_fit: true,
allow_descriptions_over_music: true,
volume_level_db: -5,
audio_track_type: 'mixed',
description_content: '<string>'
}
})
};
fetch('https://api.viddyscribe.com/enterprise/api/generate_ad_audio', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.viddyscribe.com/enterprise/api/generate_ad_audio",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'input' => [
'type' => 'media_id',
'media_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'filename' => '<string>'
],
'generation_config' => [
'format' => 'json',
'language' => 'en-US',
'video_category' => 'Auto',
'voice' => 'Achernar',
'custom_instructions' => '',
'auto_fit' => true,
'allow_descriptions_over_music' => true,
'volume_level_db' => -5,
'audio_track_type' => 'mixed',
'description_content' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.viddyscribe.com/enterprise/api/generate_ad_audio"
payload := strings.NewReader("{\n \"input\": {\n \"type\": \"media_id\",\n \"media_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"filename\": \"<string>\"\n },\n \"generation_config\": {\n \"format\": \"json\",\n \"language\": \"en-US\",\n \"video_category\": \"Auto\",\n \"voice\": \"Achernar\",\n \"custom_instructions\": \"\",\n \"auto_fit\": true,\n \"allow_descriptions_over_music\": true,\n \"volume_level_db\": -5,\n \"audio_track_type\": \"mixed\",\n \"description_content\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.viddyscribe.com/enterprise/api/generate_ad_audio")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"input\": {\n \"type\": \"media_id\",\n \"media_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"filename\": \"<string>\"\n },\n \"generation_config\": {\n \"format\": \"json\",\n \"language\": \"en-US\",\n \"video_category\": \"Auto\",\n \"voice\": \"Achernar\",\n \"custom_instructions\": \"\",\n \"auto_fit\": true,\n \"allow_descriptions_over_music\": true,\n \"volume_level_db\": -5,\n \"audio_track_type\": \"mixed\",\n \"description_content\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.viddyscribe.com/enterprise/api/generate_ad_audio")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": {\n \"type\": \"media_id\",\n \"media_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"filename\": \"<string>\"\n },\n \"generation_config\": {\n \"format\": \"json\",\n \"language\": \"en-US\",\n \"video_category\": \"Auto\",\n \"voice\": \"Achernar\",\n \"custom_instructions\": \"\",\n \"auto_fit\": true,\n \"allow_descriptions_over_music\": true,\n \"volume_level_db\": -5,\n \"audio_track_type\": \"mixed\",\n \"description_content\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"job_id": "task_abc123xyz",
"status": "queued",
"media_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}{
"error": "invalid_input",
"message": "video_id is required"
}This endpoint is available for Standard AD only. Descriptions are placed in existing dialogue gaps without changing the runtime. See Standard AD vs Extended AD if you need pauses inserted for fuller descriptions. Extended AD is supported on the video and text endpoints.
Usage Examples
1. Using an existing Media ID
If you have already uploaded media and have amedia_id, use this method.
curl -X POST https://api.viddyscribe.com/enterprise/api/generate_ad_audio \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"type": "media_id",
"media_id": "550e8400-e29b-41d4-a716-446655440000"
},
"generation_config": {
"language": "en-US"
}
}'
2. Using a Public URL
Upload from a URL and generate in a single step.curl -X POST https://api.viddyscribe.com/enterprise/api/generate_ad_audio \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"type": "url",
"url": "https://example.com/video.mp4"
},
"generation_config": {
"language": "en-US"
}
}'
3. Uploading a Local File
Upload a file directly and generate in a single step.Direct multipart upload supports local files up to 32 MB. For larger local files, see Large Local File Upload.
curl -X POST https://api.viddyscribe.com/enterprise/api/generate_ad_audio \
-H "X-API-Key: YOUR_API_KEY" \
-F 'input={"type": "file"}' \
-F "file=@/path/to/video.mp4" \
-F 'generation_config={"language": "en-US"}'
Generation Config Options
| Option | Type | Description |
|---|---|---|
auto_fit | boolean | Fits descriptions into detected no-speech zones when possible. |
allow_descriptions_over_music | boolean | Allows descriptions over detected music when no better timing is available. |
custom_captions | object | Uses provided captions for transcript/context instead of auto-generating them. Send { "content": "<VTT/SRT/plaintext>" }; format and filename are optional hints. The server parses, validates, and normalizes the cues automatically. |
volume_option | auto or max | Use max to set a target max peak level for the AD track, or auto for the default. |
volume_level_db | number | Max peak level in dBFS when volume_option is max. Supported range is -10 to 0. |
audio_track_type | mixed or ad_only | Which audio track is returned as audio_signed_url. mixed (default) is the source dialogue plus AD narration. ad_only is just the narration WAV. |
Troubleshooting
For the full list of API error codes, see Error Codes.| Error | HTTP Status | Description |
|---|---|---|
upload_not_ready | 409 | Returned in the code field when the referenced media is still being verified after upload. Retry shortly. |
upload_failed | 409 | Returned in the code field when the referenced media failed upload verification. Re-upload the video and try again. |
concurrency_limit_exceeded | 429 | Too many concurrent submissions are being validated for the current team. Retry after a short delay. |
Authorizations
API key for authentication. Obtain from your team admin.
Example: X-API-Key: vsk_abc123def456ghi789jkl012mno345pqr678stu901vwx234yz
Body
application/jsonmultipart/form-data
⌘I

