Webhooks
Webhooks provide real-time notifications when your video generation tasks complete. Instead of polling the API, your server receives an HTTP POST request when the task finishes.
Setting Up Webhooks
Include a webhook_url in your slideshow request:
curl -X POST https://api.vibepeak.ai/v1/real-estate/narrated-slideshow \
-H "Authorization: Bearer vpk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"images": [
"https://example.com/living-room.jpg",
"https://example.com/kitchen.jpg",
"https://example.com/bedroom.jpg",
"https://example.com/bathroom.jpg",
"https://example.com/backyard.jpg"
],
"webhook_url": "https://yourserver.com/webhooks/vibepeak"
}'
Webhook Payload
When a task completes (successfully or with an error), VibePeak sends a POST request to your webhook URL:
Successful Completion
{
"event" : "task.completed" ,
"task_id" : "task_abc123xyz" ,
"status" : "completed" ,
"created_at" : "2026-01-04T12:00:00Z" ,
"completed_at" : "2026-01-04T12:15:00Z" ,
"result" : {
"video_url" : "https://storage.vibepeak.ai/videos/task_abc123xyz.mp4" ,
"cover_image_url" : "https://storage.googleapis.com/vibepeak-audio/covers/task_abc123xyz.jpg" ,
"duration_seconds" : 45 ,
"resolution" : "1080p" ,
"expires_at" : "2026-01-11T12:15:00Z"
}
}
Failed Task
{
"event" : "task.failed" ,
"task_id" : "task_abc123xyz" ,
"status" : "failed" ,
"created_at" : "2026-01-04T12:00:00Z" ,
"completed_at" : "2026-01-04T12:06:00Z" ,
"error" : {
"code" : "IMAGE_PROCESSING_FAILED" ,
"message" : "Failed to process image at index 2: Invalid image format"
}
}
Each webhook request includes the following headers:
Header Description Content-Typeapplication/jsonX-VibePeak-SignatureHMAC-SHA256 signature for verification X-VibePeak-TimestampUnix timestamp when the webhook was sent X-VibePeak-EventEvent type (task.completed or task.failed)
Webhook Secret
Each API key has an associated webhook secret used for signing webhook payloads. You can find your webhook secret in the VibePeak Dashboard under your API key settings.
Your webhook secret is displayed only once when you create an API key. Store it securely - if you lose it, you’ll need to regenerate your API key.
Verifying Webhooks
Always verify webhook signatures to ensure requests are from VibePeak.
Webhooks are signed using HMAC-SHA256 with your webhook secret. Verify the signature before processing:
const crypto = require ( 'crypto' );
function verifyWebhook ( payload , signature , timestamp , secret ) {
const signedPayload = ` ${ timestamp } . ${ JSON . stringify ( payload ) } ` ;
const expectedSignature = crypto
. createHmac ( 'sha256' , secret )
. update ( signedPayload )
. digest ( 'hex' );
return crypto . timingSafeEqual (
Buffer . from ( signature ),
Buffer . from ( expectedSignature )
);
}
// Express.js example
app . post ( '/webhooks/vibepeak' , express . json (), ( req , res ) => {
const signature = req . headers [ 'x-vibepeak-signature' ];
const timestamp = req . headers [ 'x-vibepeak-timestamp' ];
if ( ! verifyWebhook ( req . body , signature , timestamp , process . env . WEBHOOK_SECRET )) {
return res . status ( 401 ). json ({ error: 'Invalid signature' });
}
// Process the webhook
const { event , task_id , result , error } = req . body ;
if ( event === 'task.completed' ) {
console . log ( `Video ready: ${ result . video_url } ` );
console . log ( `Cover image: ${ result . cover_image_url } ` );
} else if ( event === 'task.failed' ) {
console . log ( `Task failed: ${ error . message } ` );
}
res . status ( 200 ). json ({ received: true });
});
Webhook Requirements
Your webhook endpoint must:
HTTPS Only Webhook URLs must use HTTPS for security
Respond Quickly Return a 2xx response within 30 seconds
Be Idempotent Handle duplicate deliveries gracefully
Publicly Accessible Be reachable from the internet
Retry Policy
If your webhook endpoint fails to respond with a 2xx status code, VibePeak will retry the delivery with exponential backoff:
Attempt Delay 1st retry 1 second 2nd retry 2 seconds 3rd retry 4 seconds
After 3 failed attempts, the webhook is marked as failed. You can still retrieve the task status via the API by polling /v1/tasks/{taskId}.
Testing Webhooks
For local development, use a tunneling service like ngrok :
# Start ngrok
ngrok http 3000
# Use the ngrok URL in your request
curl -X POST https://api.vibepeak.ai/v1/real-estate/narrated-slideshow \
-H "Authorization: Bearer vpk_test_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"images": ["..."],
"webhook_url": "https://abc123.ngrok.io/webhooks/vibepeak"
}'
Best Practices
Process webhooks asynchronously. Return a 200 response immediately, then process the payload in a background job.
Return quickly - Acknowledge receipt with a 200 response before processing
Use a queue - Process webhook payloads asynchronously
Store the task_id - Always log the task_id for debugging
Handle duplicates - Use the task_id to deduplicate events
Verify signatures - Always validate the webhook signature
Download promptly - Video URLs expire after 7 days