Documentation Index Fetch the complete documentation index at: https://docs.audiopod.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
AudioPod AI’s Voice Management API provides comprehensive tools for managing custom and pre-built voices. Browse available voices, organize custom voice collections, preview voices, and manage voice metadata for text-to-speech and voice cloning workflows.
Key Features
Voice Browsing : Explore available pre-built voices by category
Custom Voice Creation : Create new voice models from audio samples
Custom Voice Management : Organize and manage cloned voices
Voice Collections : Group voices into organized collections
Voice Preview : Generate preview samples to test voices
Metadata Management : Update voice names, descriptions, and tags
Voice Analytics : Track usage and performance metrics
Batch Operations : Manage multiple voices efficiently
Authentication
All endpoints require authentication. Use one of these methods:
API Key (Recommended) : X-API-Key: your_api_key header
JWT Token : Authorization: Bearer your_jwt_token (for session-based auth)
Voice Discovery
List Available Voices
Browse all available voices including pre-built and custom voices.
GET /api/v1/voice/voice-profiles?limit=50
X-API-Key : {api_key}
import requests
response = requests.get(
"https://api.audiopod.ai/api/v1/voice/voice-profiles" ,
headers = { "X-API-Key" : api_key},
params = {
"limit" : 50 ,
"skip" : 0
}
)
if response.status_code == 200 :
voices_data = response.json()
for voice in voices_data[ "voices" ]:
print ( f "Voice: { voice[ 'name' ] } ( { voice[ 'voice_id' ] } )" )
print ( f " Category: { voice[ 'category' ] } " )
print ( f " Language: { voice[ 'language' ] } " )
print ( f " Gender: { voice[ 'gender' ] } " )
print ( f " Preview: { voice[ 'preview_url' ] } " )
print ()
curl -X GET "https://api.audiopod.ai/api/v1/voice/voice-profiles" \
-H "X-API-Key: your_api_key"
Filter Parameters:
voice_type : CUSTOM, STANDARD
is_public : true, false
include_public : true, false
skip : Number to skip for pagination
limit : Number of results to return (max 50)
Response:
{
"voices" : [
{
"voice_id" : "voice_abc123def456" ,
"name" : "Sarah Professional" ,
"category" : "professional" ,
"language" : "en" ,
"gender" : "female" ,
"age_range" : "adult" ,
"style" : "conversational" ,
"description" : "Clear, professional female voice perfect for business presentations" ,
"preview_url" : "https://api.audiopod.ai/voice-previews/sarah_professional.mp3" ,
"is_custom" : false ,
"created_by" : null ,
"tags" : [ "business" , "clear" , "professional" ],
"usage_stats" : {
"total_generations" : 15420 ,
"avg_rating" : 4.7
},
"supported_features" : {
"speed_control" : true ,
"pitch_control" : true ,
}
},
{
"voice_id" : "voice_xyz789ghi012" ,
"name" : "My Custom Voice" ,
"category" : "custom" ,
"language" : "en" ,
"gender" : "male" ,
"age_range" : "adult" ,
"style" : "conversational" ,
"description" : "Custom voice cloned from my recordings" ,
"preview_url" : "https://api.audiopod.ai/voice-previews/custom_xyz789.mp3" ,
"is_custom" : true ,
"created_by" : "550e8400-e29b-41d4-a716-446655440000" ,
"created_at" : "2024-01-10T15:30:00Z" ,
"tags" : [ "personal" , "english" ],
"clone_job_id" : 456 ,
"training_status" : "completed" ,
"supported_features" : {
"speed_control" : true ,
"pitch_control" : true ,
}
}
],
"total" : 127 ,
"hasMore" : true ,
"filters_applied" : {
"category" : "professional" ,
"language" : "en"
}
}
Get Voice Details
Retrieve detailed information about a specific voice.
GET /api/v1/voice/voices/{voice_id}/status
X-API-Key : {api_key}
voice_id = 123 # Voice ID is actually an integer
response = requests.get(
f "https://api.audiopod.ai/api/v1/voice/voices/ { voice_id } /status" ,
headers = { "X-API-Key" : api_key}
)
if response.status_code == 200 :
voice = response.json()
print ( f "Voice Name: { voice[ 'name' ] } " )
print ( f "Description: { voice[ 'description' ] } " )
print ( f "Language: { voice[ 'language' ] } " )
print ( f "Category: { voice[ 'category' ] } " )
if voice[ 'is_custom' ]:
print ( f "Custom voice created: { voice[ 'created_at' ] } " )
print ( f "Training status: { voice[ 'training_status' ] } " )
# Check supported features
features = voice[ 'supported_features' ]
print ( f "Speed control: { features[ 'speed_control' ] } " )
print ( f "Pitch control: { features[ 'pitch_control' ] } " )
Create Custom Voices
Upload Single Audio Sample
Create a custom voice model from a single audio file.
POST /api/v1/voice/voice-profiles
X-API-Key : {api_key}
Content-Type : multipart/form-data
name : My Custom Voice
description : Professional voice for presentations
file : (audio file)
denoise : true
import requests
with open ( "voice_sample.wav" , "rb" ) as audio_file:
response = requests.post(
"https://api.audiopod.ai/api/v1/voice/voice-profiles" ,
headers = { "X-API-Key" : api_key},
data = {
"name" : "My Custom Voice" ,
"description" : "Professional voice for presentations" ,
"denoise" : True
},
files = { "file" : audio_file}
)
if response.status_code == 200 :
voice_data = response.json()
voice_id = voice_data[ "id" ]
print ( f "Voice created with ID: { voice_id } " )
curl -X POST "https://api.audiopod.ai/api/v1/voice/voice-profiles" \
-H "X-API-Key: your_api_key" \
-F "name=My Custom Voice" \
-F "description=Professional voice for presentations" \
-F "denoise=true" \
-F "file=@voice_sample.wav"
Response:
{
"id" : 123 ,
"uuid" : "550e8400-e29b-41d4-a716-446655440000" ,
"name" : "My Custom Voice" ,
"description" : "Professional voice for presentations" ,
"voice_type" : "CUSTOM" ,
"status" : "PROCESSING" ,
"created_at" : "2024-01-15T10:30:00Z" ,
"processed_at" : null ,
"is_public" : false ,
"file_path" : "/voices/custom/voice_123.wav"
}
Upload Multiple Audio Samples
Create a higher-quality voice model using multiple audio samples.
POST /api/v1/voice/voice-profiles/multi-sample
X-API-Key : {api_key}
Content-Type : multipart/form-data
name : High Quality Voice
description : Multi-sample voice for better quality
is_public : false
voice_files : (multiple audio files)
voice_files = [
"sample1.wav" ,
"sample2.wav" ,
"sample3.wav"
]
files = []
for i, file_path in enumerate (voice_files):
files.append(( 'voice_files' , open (file_path, 'rb' )))
response = requests.post(
"https://api.audiopod.ai/api/v1/voice/voice-profiles/multi-sample" ,
headers = { "X-API-Key" : api_key},
data = {
"name" : "High Quality Voice" ,
"description" : "Multi-sample voice for better quality" ,
"is_public" : False
},
files = files
)
# Close files
for _, file_obj in files:
file_obj.close()
Audio Quality Requirements
For best voice creation results:
Duration : 10-60 seconds of clean audio per sample
Format : WAV, MP3, or M4A
Sample Rate : 22kHz or higher
Quality : Clear speech without background noise
Content : Natural speech with varied intonation
Multiple Samples : 2-5 samples recommended for higher quality
Voice Preview
Generate Voice Preview
Create a preview sample to test how a voice sounds.
GET /api/v1/voice/voice-profiles/{voice_identifier}/preview?audio_format=mp3
X-API-Key : {api_key}
voice_identifier = "123" # Voice ID or UUID
response = requests.get(
f "https://api.audiopod.ai/api/v1/voice/voice-profiles/ { voice_identifier } /preview" ,
headers = { "X-API-Key" : api_key},
params = {
"audio_format" : "mp3" ,
"generate_if_missing" : True
}
)
if response.status_code == 200 :
preview_result = response.json()
print ( f "Preview URL: { preview_result[ 'audio_url' ] } " )
print ( f "Duration: { preview_result[ 'duration' ] } seconds" )
# Download preview audio
audio_response = requests.get(preview_result[ 'audio_url' ])
with open ( "voice_preview.mp3" , "wb" ) as f:
f.write(audio_response.content)
print ( "Preview saved as voice_preview.mp3" )
Batch Preview Generation
Generate previews for multiple voices with the same text.
POST /api/v1/voice/preview/batch
X-API-Key : {api_key}
Content-Type : application/json
{
"voice_ids" : [ "voice_abc123" , "voice_def456" , "voice_ghi789" ],
"text" : "Compare how different voices sound with this text." ,
"speed" : 1.0
}
batch_preview_data = {
"voice_ids" : [ "voice_abc123" , "voice_def456" , "voice_ghi789" ],
"text" : "Compare how different voices sound with this text." ,
"speed" : 1.0 ,
"pitch" : 0.0 ,
"format" : "mp3"
}
response = requests.post(
"https://api.audiopod.ai/api/v1/voice/preview/batch" ,
headers = {
"X-API-Key" : api_key,
"Content-Type" : "application/json"
},
json = batch_preview_data
)
if response.status_code == 200 :
batch_result = response.json()
print ( f "Generated { len (batch_result[ 'previews' ]) } voice previews" )
for i, preview in enumerate (batch_result[ "previews" ]):
print ( f "Voice { i + 1 } : { preview[ 'voice_name' ] } " )
print ( f " URL: { preview[ 'audio_url' ] } " )
print ( f " Duration: { preview[ 'duration' ] } s" )
Custom Voice Management
List Custom Voices
Get all custom voices created by the authenticated user.
GET /api/v1/voice/voice-profiles?voice_type=CUSTOM&limit=25
X-API-Key : {api_key}
response = requests.get(
"https://api.audiopod.ai/api/v1/voice/voice-profiles" ,
headers = { "X-API-Key" : api_key},
params = {
"voice_type" : "CUSTOM" , # Filter for custom voices only
"limit" : 25 ,
"skip" : 0
}
)
if response.status_code == 200 :
custom_voices = response.json()
for voice in custom_voices[ "voices" ]:
print ( f "Custom Voice: { voice[ 'name' ] } " )
print ( f " Voice ID: { voice[ 'voice_id' ] } " )
print ( f " Status: { voice[ 'training_status' ] } " )
print ( f " Created: { voice[ 'created_at' ] } " )
print ( f " Clone Job: { voice[ 'clone_job_id' ] } " )
print ()
Update Custom Voice
Update metadata and settings for a custom voice.
PATCH /api/v1/voice/voices/{voice_id}
X-API-Key : {api_key}
Content-Type : application/json
{
"name" : "Updated Voice Name" ,
"description" : "My updated custom voice description" ,
"is_public" : false
}
voice_id = 123 # Voice ID is an integer
update_data = {
"name" : "Updated Voice Name" ,
"description" : "My updated custom voice description" ,
"is_public" : False # Keep voice private
}
response = requests.patch(
f "https://api.audiopod.ai/api/v1/voice/voices/ { voice_id } " ,
headers = {
"X-API-Key" : api_key,
"Content-Type" : "application/json"
},
json = update_data
)
if response.status_code == 200 :
updated_voice = response.json()
print ( f "Voice updated successfully:" )
print ( f " Name: { updated_voice[ 'name' ] } " )
print ( f " Description: { updated_voice[ 'description' ] } " )
print ( f " Tags: { ', ' .join(updated_voice[ 'tags' ]) } " )
Delete Custom Voice
Remove a custom voice and all associated data.
DELETE /api/v1/voice/voices/{voice_id}
X-API-Key : {api_key}
voice_id = 123 # Voice ID is an integer or an UUID
response = requests.delete(
f "https://api.audiopod.ai/api/v1/voice/voices/ { voice_id } " ,
headers = { "X-API-Key" : api_key}
)
if response.status_code == 204 :
print ( "Custom voice deleted successfully" )
elif response.status_code == 404 :
print ( "Voice not found or already deleted" )
else :
print ( f "Error deleting voice: { response.status_code } " )
Voice Collections
Create Voice Collection
Organize voices into collections for better management.
POST /api/v1/voice/collections
X-API-Key : {api_key}
Content-Type : application/json
{
"name" : "My Podcast Voices" ,
"description" : "Voices for podcast production" ,
"voice_ids" : [ "voice_abc123" , "voice_def456" ],
"tags" : [ "podcast" , "production" ]
}
collection_data = {
"name" : "My Podcast Voices" ,
"description" : "Voices for podcast production" ,
"voice_ids" : [ "voice_abc123" , "voice_def456" ],
"tags" : [ "podcast" , "production" ],
"is_public" : False
}
response = requests.post(
"https://api.audiopod.ai/api/v1/voice/collections" ,
headers = {
"X-API-Key" : api_key,
"Content-Type" : "application/json"
},
json = collection_data
)
if response.status_code == 201 :
collection = response.json()
print ( f "Collection created: { collection[ 'name' ] } " )
print ( f "Collection ID: { collection[ 'collection_id' ] } " )
print ( f "Contains { len (collection[ 'voice_ids' ]) } voices" )
List Voice Collections
Get all voice collections for the authenticated user.
GET /api/v1/voice/collections?limit=25
X-API-Key : {api_key}
response = requests.get(
"https://api.audiopod.ai/api/v1/voice/collections" ,
headers = { "X-API-Key" : api_key},
params = { "limit" : 25 , "skip" : 0 }
)
if response.status_code == 200 :
collections = response.json()
for collection in collections[ "collections" ]:
print ( f "Collection: { collection[ 'name' ] } " )
print ( f " Description: { collection[ 'description' ] } " )
print ( f " Voices: { len (collection[ 'voice_ids' ]) } " )
print ( f " Created: { collection[ 'created_at' ] } " )
print ()
Add Voices to Collection
Add voices to an existing collection.
POST /api/v1/voice/collections/{collection_id}/voices
X-API-Key : {api_key}
Content-Type : application/json
{
"voice_ids" : [ "voice_ghi789" , "voice_jkl012" ]
}
collection_id = "collection_abc123"
new_voices = {
"voice_ids" : [ "voice_ghi789" , "voice_jkl012" ]
}
response = requests.post(
f "https://api.audiopod.ai/api/v1/voice/collections/ { collection_id } /voices" ,
headers = {
"X-API-Key" : api_key,
"Content-Type" : "application/json"
},
json = new_voices
)
if response.status_code == 200 :
updated_collection = response.json()
print ( f "Added voices to collection" )
print ( f "Collection now has { len (updated_collection[ 'voice_ids' ]) } voices" )
Voice Analytics
Get Voice Usage Statistics
Retrieve usage statistics for voices.
GET /api/v1/voice/analytics/usage?voice_id=voice_abc123&period=30d
X-API-Key : {api_key}
voice_id = "voice_abc123"
response = requests.get(
"https://api.audiopod.ai/api/v1/voice/analytics/usage" ,
headers = { "X-API-Key" : api_key},
params = {
"voice_id" : voice_id,
"period" : "30d" , # 7d, 30d, 90d, 1y
"breakdown" : "daily" # daily, weekly, monthly
}
)
if response.status_code == 200 :
analytics = response.json()
print ( f "Usage for voice { voice_id } :" )
print ( f " Total generations: { analytics[ 'total_generations' ] } " )
print ( f " Total characters: { analytics[ 'total_characters' ] } " )
print ( f " Total duration: { analytics[ 'total_duration' ] } seconds" )
print ( f " Average rating: { analytics[ 'avg_rating' ] :.2f} " )
# Daily breakdown
for day_data in analytics[ "daily_breakdown" ]:
print ( f " { day_data[ 'date' ] } : { day_data[ 'generations' ] } generations" )
Error Handling
404 Not Found - Voice Not Found
Causes: - Voice ID doesn’t exist - Voice was deleted - Access denied to private voice
Solutions: - Verify voice ID is correct - Check if voice still exists - Ensure you have access permissions
400 Bad Request - Invalid Parameters
Causes: - Invalid filter parameters - Malformed voice collection data - Invalid preview text
Solutions: - Check parameter values - Validate collection structure - Ensure preview text is not empty
403 Forbidden - Access Denied
Causes: - Trying to modify another user’s custom voice - Accessing private voice without permission
Solutions: - Only modify your own custom voices - Use public voices or get proper access
402 Payment Required - Insufficient Credits
Causes: - Not enough credits for voice preview generation
Solutions: - Purchase additional credits - Check credit requirements
Use Cases & Examples
Voice Selection Assistant
def find_best_voice_for_content ( content_type , language , gender_preference , api_key ):
"""Help users find the best voice for their content"""
# Define voice selection criteria based on content type
criteria_map = {
"podcast" : { "category" : "professional" , "style" : "conversational" },
"audiobook" : { "category" : "professional" , "style" : "narrative" },
"assistant" : { "category" : "professional" , "style" : "assistant" },
"character" : { "category" : "character" , "style" : "character" },
"casual" : { "category" : "casual" , "style" : "conversational" }
}
criteria = criteria_map.get(content_type, { "category" : "professional" })
# Search for matching voices
params = {
"language" : language,
"limit" : 10
}
if gender_preference:
params[ "gender" ] = gender_preference
if "category" in criteria:
params[ "category" ] = criteria[ "category" ]
if "style" in criteria:
params[ "style" ] = criteria[ "style" ]
response = requests.get(
"https://api.audiopod.ai/api/v1/voice/voices" ,
headers = { "X-API-Key" : api_key},
params = params
)
if response.status_code != 200 :
return { "error" : "Failed to fetch voices" }
voices_data = response.json()
voices = voices_data[ "voices" ]
# Rank voices by suitability
ranked_voices = []
for voice in voices:
score = 0
# Prefer voices with higher ratings
if voice.get( "usage_stats" , {}).get( "avg_rating" ):
score += voice[ "usage_stats" ][ "avg_rating" ] * 10
# Prefer voices with proven usage
if voice.get( "usage_stats" , {}).get( "total_generations" , 0 ) > 1000 :
score += 20
# Prefer exact style matches
if voice.get( "style" ) == criteria.get( "style" ):
score += 30
ranked_voices.append({
"voice" : voice,
"suitability_score" : score
})
# Sort by score
ranked_voices.sort( key = lambda x : x[ "suitability_score" ], reverse = True )
return {
"content_type" : content_type,
"language" : language,
"criteria" : criteria,
"recommended_voices" : ranked_voices[: 5 ], # Top 5 recommendations
"total_matches" : len (voices)
}
# Usage
recommendations = find_best_voice_for_content(
content_type = "podcast" ,
language = "en" ,
gender_preference = "female" ,
api_key = "your_api_key"
)
print ( f "Top recommendations for { recommendations[ 'content_type' ] } in { recommendations[ 'language' ] } :" )
for i, rec in enumerate (recommendations[ "recommended_voices" ], 1 ):
voice = rec[ "voice" ]
print ( f " { i } . { voice[ 'name' ] } (Score: { rec[ 'suitability_score' ] :.1f} )" )
print ( f " Category: { voice[ 'category' ] } , Style: { voice.get( 'style' , 'N/A' ) } " )
print ( f " Rating: { voice.get( 'usage_stats' , {}).get( 'avg_rating' , 'N/A' ) } " )
print ()
Voice Collection Manager
def organize_voices_by_project ( voices_to_organize , api_key ):
"""Organize voices into project-based collections"""
# Group voices by characteristics for project organization
voice_groups = {
"narrative_voices" : [],
"character_voices" : [],
"professional_voices" : [],
"multilingual_voices" : []
}
for voice_id in voices_to_organize:
# Get voice details
response = requests.get(
f "https://api.audiopod.ai/api/v1/voice/voices/ { voice_id } " ,
headers = { "X-API-Key" : api_key}
)
if response.status_code == 200 :
voice = response.json()
# Categorize voice
style = voice.get( "style" , "" )
category = voice.get( "category" , "" )
if style == "narrative" or "audiobook" in voice.get( "tags" , []):
voice_groups[ "narrative_voices" ].append(voice_id)
elif category == "character" or style == "character" :
voice_groups[ "character_voices" ].append(voice_id)
elif category == "professional" :
voice_groups[ "professional_voices" ].append(voice_id)
# Check if multilingual
if voice.get( "language" ) != "en" or "multilingual" in voice.get( "tags" , []):
voice_groups[ "multilingual_voices" ].append(voice_id)
# Create collections for non-empty groups
created_collections = []
collection_configs = {
"narrative_voices" : {
"name" : "Narrative & Audiobook Voices" ,
"description" : "Voices optimized for storytelling and long-form content"
},
"character_voices" : {
"name" : "Character & Creative Voices" ,
"description" : "Unique voices for character work and creative projects"
},
"professional_voices" : {
"name" : "Professional & Business Voices" ,
"description" : "Clear, professional voices for business content"
},
"multilingual_voices" : {
"name" : "International & Multilingual Voices" ,
"description" : "Voices for international content and multiple languages"
}
}
for group_name, voice_ids in voice_groups.items():
if voice_ids: # Only create collection if there are voices
config = collection_configs[group_name]
collection_data = {
"name" : config[ "name" ],
"description" : config[ "description" ],
"voice_ids" : voice_ids,
"tags" : [group_name.replace( "_" , "-" ), "auto-organized" ]
}
response = requests.post(
"https://api.audiopod.ai/api/v1/voice/collections" ,
headers = {
"X-API-Key" : api_key,
"Content-Type" : "application/json"
},
json = collection_data
)
if response.status_code == 201 :
collection = response.json()
created_collections.append({
"collection_id" : collection[ "collection_id" ],
"name" : collection[ "name" ],
"voice_count" : len (voice_ids),
"voices" : voice_ids
})
return {
"organized" : True ,
"collections_created" : len (created_collections),
"collections" : created_collections,
"total_voices_organized" : sum ( len (group) for group in voice_groups.values())
}
# Usage
voice_list = [ "voice_abc123" , "voice_def456" , "voice_ghi789" , "voice_jkl012" ]
organization_result = organize_voices_by_project(voice_list, "your_api_key" )
print ( f "Organized { organization_result[ 'total_voices_organized' ] } voices into { organization_result[ 'collections_created' ] } collections:" )
for collection in organization_result[ "collections" ]:
print ( f " { collection[ 'name' ] } : { collection[ 'voice_count' ] } voices" )
Best Practices
Voice Selection Guidelines
# Guidelines for choosing the right voice for different use cases
voice_selection_guide = {
"content_types" : {
"podcast" : {
"recommended_categories" : [ "professional" , "casual" ],
"preferred_styles" : [ "conversational" ],
"features_needed" : [ "speed_control" ],
"avoid" : [ "character" , "synthetic" ]
},
"audiobook" : {
"recommended_categories" : [ "professional" ],
"preferred_styles" : [ "narrative" ],
"features_needed" : [ "pitch_control" , "speed_control" ],
"duration_considerations" : "Choose voices with consistent quality for long content"
},
"e_learning" : {
"recommended_categories" : [ "professional" ],
"preferred_styles" : [ "assistant" , "educational" ],
"features_needed" : [ "speed_control" ],
"clarity_priority" : "High clarity and pronunciation accuracy required"
},
"marketing" : {
"recommended_categories" : [ "professional" , "character" ],
"preferred_styles" : [ "promotional" , "conversational" ],
"brand_alignment" : "Choose voice that matches brand personality"
}
},
"technical_considerations" : {
"processing_speed" : "Pre-built voices are faster than custom voices" ,
"customization" : "Custom voices offer more personalization but require training time" ,
"quality" : "Professional category voices generally have higher quality" ,
"cost" : "Custom voices have training costs, pre-built voices are pay-per-use"
}
}
Pricing
Voice management operations have different pricing structures:
Operation Cost Description Custom Voice Creation Free Create new voice model from audio samples Voice Preview Free Generate preview samples (up to 50 words) Voice Listing Free Browse available voices Collection Management Free Create and manage voice collections Custom Voice Updates Free Update custom voice metadata
Next Steps
Text-to-Speech Generate speech using both standard and custom voices.
Voice Changer Transform existing audio to use different voice characteristics.