API Workflow Overview
The Hoox API follows a simple workflow to create professional videos:Step 1: Get your API key
- Log in to your Hoox dashboard
- Go to Your Space > Settings > API
- Click Generate API Key
- Copy and save your key (it will only be shown once)
Keep your API key secret! Never share it publicly or commit it to version control.
Step 2: Discover Available Resources
Before creating videos, explore the voices and avatars available for your account:Get Available Voices
Explore all available voices using the voices API endpoint:curl -X GET "https://app.hoox.video/api/public/v1/voice/list" \
-H "Authorization: Bearer your_api_key"
import requests
response = requests.get(
'https://app.hoox.video/api/public/v1/voice/list',
headers={'Authorization': 'Bearer your_api_key'}
)
voices = response.json()['voices']
print(f"Found {len(voices)} voices")
# Find a professional English voice
professional_voices = [
voice for voice in voices
if voice['language'] == 'en' and 'professional' in voice['tags']
]
selected_voice = professional_voices[0] if professional_voices else voices[0]
print(f"Selected voice: {selected_voice['name']} ({selected_voice['id']})")
const response = await fetch('https://app.hoox.video/api/public/v1/voice/list', {
headers: {
'Authorization': 'Bearer your_api_key'
}
});
const data = await response.json();
const voices = data.voices;
// Find a professional English voice
const selectedVoice = voices.find(voice =>
voice.language === 'en' && voice.tags.includes('professional')
) || voices[0];
console.log(`Selected voice: ${selectedVoice.name} (${selectedVoice.id})`);
Get Available Avatars
Discover available avatars using the avatars API endpoint:curl -X GET "https://app.hoox.video/api/public/v1/avatar/list?place=office&action=presenting" \
-H "Authorization: Bearer your_api_key"
response = requests.get(
'https://app.hoox.video/api/public/v1/avatar/list',
headers={'Authorization': 'Bearer your_api_key'},
params={'place': 'office', 'action': 'presenting'}
)
avatars = response.json()['avatars']
print(f"Found {len(avatars)} business avatars")
# Select a business avatar
selected_avatar = avatars[0] if avatars else None
if selected_avatar:
print(f"Selected avatar: {selected_avatar['name']} ({selected_avatar['id']})")
const avatarResponse = await fetch(
'https://app.hoox.video/api/public/v1/avatar/list?place=office&action=presenting',
{
headers: {
'Authorization': 'Bearer your_api_key'
}
}
);
const avatarData = await avatarResponse.json();
const selectedAvatar = avatarData.avatars[0];
if (selectedAvatar) {
console.log(`Selected avatar: ${selectedAvatar.name} (${selectedAvatar.id})`);
}
Step 3: Generate Your First Video
You can generate videos in two ways: directly from a prompt, or by first generating a script for review.Option A: Direct Video Generation
Generate videos directly from prompts using the video generation API:curl -X POST "https://app.hoox.video/api/public/v1/generation/start" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Create an explanatory video about sustainable energy solutions",
"duration": 60,
"voice_id": "voice_en_us_female_sarah",
"avatar_id": "avatar_business_woman_office_1",
"format": "vertical",
"web_search": {
"script": true,
"images": true
},
"animate_image": true
}'
# Direct video generation from prompt
generation_response = requests.post(
'https://app.hoox.video/api/public/v1/generation/start',
headers={
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
json={
'prompt': 'Create an explanatory video about sustainable energy solutions',
'duration': 60,
'voice_id': selected_voice['id'], # From step 2
'avatar_id': selected_avatar['id'] if selected_avatar else None,
'format': 'vertical',
'web_search': {
'script': True,
'images': True
},
'animate_image': True
}
)
generation_data = generation_response.json()
job_id = generation_data['job_id']
estimated_cost = generation_data['estimated_credits']
print(f"Generation started!")
print(f"Job ID: {job_id}")
print(f"Estimated cost: {estimated_cost} credits")
// Direct video generation from prompt
const generationResponse = await fetch('https://app.hoox.video/api/public/v1/generation/start', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: "Create an explanatory video about sustainable energy solutions",
duration: 60,
voice_id: selectedVoice.id,
avatar_id: selectedAvatar?.id,
format: "vertical",
web_search: {
script: true,
images: true
},
animate_image: true
})
});
const generationData = await generationResponse.json();
console.log(`Generation started! Job ID: ${generationData.job_id}`);
console.log(`Estimated cost: ${generationData.estimated_credits} credits`);
Option B: Generate Script First
For better control, generate a script first using the script generation API:# First, generate a script
curl -X POST "https://app.hoox.video/api/public/v1/script/generate" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Create an explanatory video about sustainable energy solutions",
"duration": 60,
"webSearch": true
}'
# Step 1: Generate script for review and cost estimation
script_response = requests.post(
'https://app.hoox.video/api/public/v1/script/generate',
headers={
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
json={
'prompt': 'Create an explanatory video about sustainable energy solutions',
'duration': 60,
'webSearch': True
}
)
script_data = script_response.json()['data']
generated_script = script_data['script']
script_cost = script_data['cost']
print(f"Script generated! Cost: {script_cost} credits")
print(f"Script preview: {generated_script[:200]}...")
# Step 2: Use the script to generate video
video_response = requests.post(
'https://app.hoox.video/api/public/v1/generation/start',
headers={
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
json={
'script': generated_script,
'voice_id': selected_voice['id'],
'avatar_id': selected_avatar['id'] if selected_avatar else None,
'format': 'vertical',
'animate_image': True
}
)
video_data = video_response.json()
job_id = video_data['job_id']
print(f"Video generation started! Job ID: {job_id}")
// Step 1: Generate script first
const scriptResponse = await fetch('https://app.hoox.video/api/public/v1/script/generate', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: "Create an explanatory video about sustainable energy solutions",
duration: 60,
webSearch: true
})
});
const scriptData = await scriptResponse.json();
const generatedScript = scriptData.data.script;
console.log(`Script generated! Preview: ${generatedScript.substring(0, 200)}...`);
// Step 2: Use script to generate video
const videoResponse = await fetch('https://app.hoox.video/api/public/v1/generation/start', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
script: generatedScript,
voice_id: selectedVoice.id,
avatar_id: selectedAvatar?.id,
format: "vertical",
animate_image: true
})
});
const videoData = await videoResponse.json();
console.log(`Video generation started! Job ID: ${videoData.job_id}`);
curl -X GET "https://app.hoox.video/api/public/v1/generation/status/{job_id}" \
-H "Authorization: Bearer your_api_key"
import time
def wait_for_generation_completion(job_id, max_wait=600):
"""Wait for video generation to complete"""
start_time = time.time()
while time.time() - start_time < max_wait:
status_response = requests.get(
f'https://app.hoox.video/api/public/v1/generation/status/{job_id}',
headers={'Authorization': 'Bearer your_api_key'}
)
status_data = status_response.json()
status = status_data['status']
progress = status_data.get('progress_step', 0)
current_step = status_data.get('current_step', 'Processing')
print(f"Status: {status} ({progress}%) - {current_step}")
if status == 'completed':
video_id = status_data['result']['video_id']
cost = status_data['result']['cost']
print(f"✅ Generation completed! Video ID: {video_id}, Cost: {cost} credits")
return video_id
elif status == 'failed':
error = status_data.get('error', {})
print(f"❌ Generation failed: {error.get('message', 'Unknown error')}")
return None
time.sleep(10) # Wait 10 seconds before checking again
print("⏰ Generation timed out")
return None
# Usage
video_id = wait_for_generation_completion(job_id)
async function waitForGenerationCompletion(jobId, maxWait = 600000) {
const startTime = Date.now();
while (Date.now() - startTime < maxWait) {
const statusResponse = await fetch(
`https://app.hoox.video/api/public/v1/generation/status/${job_id}`,
{
headers: {
'Authorization': 'Bearer your_api_key'
}
}
);
const statusData = await statusResponse.json();
const status = statusData.status;
const progress = statusData.progress_step || 0;
const currentStep = statusData.current_step || 'Processing';
console.log(`Status: ${status} (${progress}%) - ${currentStep}`);
if (status === 'completed') {
const videoId = statusData.result.video_id;
const cost = statusData.result.cost;
console.log(`✅ Generation completed! Video ID: ${videoId}, Cost: ${cost} credits`);
return videoId;
} else if (status === 'failed') {
const error = statusData.error || {};
console.log(`❌ Generation failed: ${error.message || 'Unknown error'}`);
return null;
}
await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds
}
console.log('⏰ Generation timed out');
return null;
}
// Usage
const videoId = await waitForGenerationCompletion(generationData.job_id);
Step 5: Export the Video
Export your video to a downloadable MP4 file using the export start API:curl -X POST "https://app.hoox.video/api/public/v1/export/start" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"video_id": "YOUR_VIDEO_ID",
"format": "vertical"
}'
def export_and_download_video(video_id, format="vertical"):
"""Export video and download the MP4 file"""
# Start export
export_response = requests.post(
'https://app.hoox.video/api/public/v1/export/start',
headers={
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
json={
'video_id': video_id,
'format': format
}
)
export_data = export_response.json()
export_job_id = export_data['job_id']
print(f"Export started! Job ID: {export_job_id}")
# Wait for export completion
while True:
export_status_response = requests.get(
f'https://app.hoox.video/api/public/v1/export/status/{export_job_id}',
headers={'Authorization': 'Bearer your_api_key'}
)
export_status = export_status_response.json()
status = export_status['status']
progress = export_status.get('progress', 0)
print(f"Export status: {status} ({progress}%)")
if status == 'completed':
video_url = export_status['result']['video_url']
print(f"✅ Export completed! Download URL: {video_url}")
# Download the video
video_response = requests.get(video_url)
with open(f'video_{video_id}.mp4', 'wb') as f:
f.write(video_response.content)
print(f"📥 Video downloaded as video_{video_id}.mp4")
return video_url
elif status == 'failed':
print(f"❌ Export failed: {export_status.get('error', {}).get('message', 'Unknown error')}")
return None
time.sleep(5) # Wait 5 seconds before checking again
# Usage
if video_id:
download_url = export_and_download_video(video_id)
async function exportAndDownloadVideo(videoId, format = "vertical") {
// Start export
const exportResponse = await fetch('https://app.hoox.video/api/public/v1/export/start', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
video_id: videoId,
format: format
})
});
const exportData = await exportResponse.json();
const exportJobId = exportData.job_id;
console.log(`Export started! Job ID: ${exportJobId}`);
// Wait for export completion
while (true) {
const exportStatusResponse = await fetch(
`https://app.hoox.video/api/public/v1/export/status/${exportJobId}`,
{
headers: {
'Authorization': 'Bearer your_api_key'
}
}
);
const exportStatus = await exportStatusResponse.json();
const status = exportStatus.status;
const progress = exportStatus.progress || 0;
console.log(`Export status: ${status} (${progress}%)`);
if (status === 'completed') {
const videoUrl = exportStatus.result.video_url;
console.log(`✅ Export completed! Download URL: ${videoUrl}`);
return videoUrl;
} else if (status === 'failed') {
const error = exportStatus.error || {};
console.log(`❌ Export failed: ${error.message || 'Unknown error'}`);
return null;
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
}
}
// Usage
if (videoId) {
const downloadUrl = await exportAndDownloadVideo(videoId);
}
Free first export for API Videos: Videos created through the API have export costs included in the generation price, so first export is free.
Next Steps
Pricing & Credits
Understand costs and optimize your usage
API Reference
Complete API documentation and examples

