What are Webhooks?
Webhooks allow you to receive real-time notifications when your video generation or export jobs complete. Instead of polling the status endpoint repeatedly, Hoox will send an HTTP POST request to your specified URL when the job finishes.
Benefits
Real-time Updates Get notified immediately when jobs complete, no need to poll
Reduced API Calls Save on rate limits by eliminating status polling
Better UX Provide instant feedback to your users
Automation Trigger downstream processes automatically
How Webhooks Work
Configure Webhook URL
Include a webhook_url in your generation or export request
Job Processing
Hoox processes your video generation or export job
Webhook Delivery
When the job completes (success or failure), Hoox sends a POST request to your URL
Acknowledgment
Your endpoint should respond with a 200 status code to confirm receipt
Webhook Payload
Successful Generation
{
"job_id" : "run_01234567890abcdef" ,
"status" : "completed" ,
"result" : {
"video_id" : "video_abcdef1234567890" ,
"thumbnail_url" : "https://cdn.hoox.video/thumbnails/video_123.jpg" ,
"cost" : 5 ,
"created_at" : "2024-01-15T10:30:00Z"
}
}
Failed Generation
{
"job_id" : "run_01234567890abcdef" ,
"status" : "failed" ,
"error" : {
"code" : "insufficient_credits" ,
"message" : "Not enough credits to complete video generation"
}
}
Successful Export
{
"job_id" : "run_fedcba0987654321" ,
"status" : "completed" ,
"result" : {
"video_url" : "https://cdn.hoox.video/exports/video_456.mp4" ,
"thumbnail_url" : "https://cdn.hoox.video/thumbnails/video_456.jpg" ,
"cost" : 3 ,
"created_at" : "2024-01-15T10:35:00Z"
}
}
Setting Up Webhooks
1. Create an Endpoint
Your webhook endpoint should:
Accept POST requests
Respond with 200 status code
Process the payload asynchronously if needed
Node.js/Express
Python/Flask
PHP
app . post ( '/webhook/hoox' , express . json (), ( req , res ) => {
const { job_id , status , result , error } = req . body ;
console . log ( `Webhook received for job ${ job_id } : ${ status } ` );
if ( status === 'completed' ) {
// Handle successful completion
console . log ( 'Video ready:' , result . video_id );
// Update your database
updateJobStatus ( job_id , 'completed' , result );
// Notify user
notifyUser ( job_id , result );
} else if ( status === 'failed' ) {
// Handle failure
console . error ( 'Job failed:' , error );
// Update your database
updateJobStatus ( job_id , 'failed' , null , error );
// Notify user of failure
notifyUserOfFailure ( job_id , error );
}
// Always respond with 200
res . status ( 200 ). send ( 'OK' );
});
2. Use in API Calls
Include your webhook URL when starting jobs:
const response = await fetch ( 'https://app.hoox.video/api/public/v1/generation/start' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer hx_live_your_api_key_here' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
prompt: "Create a video about space exploration" ,
voice_id: "en-US-JennyNeural" ,
webhook_url: "https://your-app.com/webhook/hoox"
})
});
Security Considerations
1. Validate Requests
Verify that webhook requests are coming from Hoox:
// Check User-Agent header
const userAgent = req . headers [ 'user-agent' ];
if ( ! userAgent || ! userAgent . includes ( 'Hoox-API' )) {
return res . status ( 401 ). send ( 'Unauthorized' );
}
// Check for Hoox webhook header
const isHooxWebhook = req . headers [ 'x-hoox-webhook' ];
if ( isHooxWebhook !== 'true' ) {
return res . status ( 401 ). send ( 'Unauthorized' );
}
2. Use HTTPS
Always use HTTPS URLs for your webhook endpoints to ensure data is encrypted in transit.
3. Implement Idempotency
Handle duplicate webhook deliveries gracefully:
const processedJobs = new Set ();
app . post ( '/webhook/hoox' , ( req , res ) => {
const { job_id } = req . body ;
// Check if we've already processed this job
if ( processedJobs . has ( job_id )) {
console . log ( `Duplicate webhook for job ${ job_id } , ignoring` );
return res . status ( 200 ). send ( 'OK' );
}
// Process the webhook
processWebhook ( req . body );
// Mark as processed
processedJobs . add ( job_id );
res . status ( 200 ). send ( 'OK' );
});
Retry Behavior
Hoox will retry webhook deliveries if your endpoint:
Returns a non-2xx status code
Times out (after 10 seconds)
Is unreachable
Retry Schedule:
1st retry: After 1 second
2nd retry: After 2 seconds
3rd retry: After 4 seconds
Maximum : 3 retry attempts
If all retries fail, the webhook will be discarded. Ensure your endpoint is reliable and responds quickly.
Testing Webhooks
1. Use ngrok for Local Development
# Install ngrok
npm install -g ngrok
# Expose your local server
ngrok http 3000
# Use the HTTPS URL in your webhook_url
# https://abc123.ngrok.io/webhook/hoox
RequestBin : Create temporary endpoints to inspect payloads
Webhook.site : Test and debug webhook deliveries
Postman : Mock webhook requests for testing
3. Test Endpoint
Create a simple test endpoint to verify webhook delivery:
app . post ( '/webhook/test' , ( req , res ) => {
console . log ( 'Webhook Headers:' , req . headers );
console . log ( 'Webhook Body:' , JSON . stringify ( req . body , null , 2 ));
res . status ( 200 ). send ( 'Webhook received successfully' );
});
Best Practices
Respond with 200 status as quickly as possible
Process heavy operations asynchronously
Use queues for complex workflows
Log all webhook deliveries for debugging
Handle malformed payloads gracefully
Implement monitoring and alerting
Use load balancers for high-volume webhooks
Implement rate limiting on your endpoint
Consider using message queues for processing
Common Issues
Issue Cause Solution Webhooks not received Endpoint unreachable Check URL and firewall settings Duplicate processing No idempotency check Implement job ID tracking Slow processing Heavy operations in handler Move to background jobs Missing webhooks Endpoint returning errors Fix endpoint logic and status codes
Always test your webhook endpoints thoroughly before using them in production.