Webhook Integration Guide for TTS and Video APIs
Long-running jobs (video generation, batch audiobook creation) shouldn't block your request thread. Webhooks are the answer.
How Speeko Webhooks Work
- You submit a job with a
webhook_url - Speeko returns a
job_idimmediately - When the job completes, Speeko POSTs to your URL
- Your endpoint verifies and processes the result
Endpoint Requirements
- Public HTTPS URL — No HTTP, no localhost (use ngrok for dev)
- Responds within 10 seconds — Or Speeko marks it failed and retries
- Returns 2xx status — Anything else triggers retries
- Idempotent handling — Same webhook may fire twice
Sample Webhook Handler (Node.js)
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/speeko', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-speeko-signature'];
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (signature !== expected) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
if (await alreadyProcessed(event.job_id)) {
return res.status(200).send('Already processed');
}
await processJob(event);
await markProcessed(event.job_id);
res.status(200).send('OK');
});Signature Verification
Every Speeko webhook includes an X-Speeko-Signature header with an HMAC-SHA256 of the body. Always verify before processing.
Retry Policy
If your endpoint fails, Speeko retries with exponential backoff:
- Retry 1: 1 minute later
- Retry 2: 5 minutes later
- Retry 3: 30 minutes later
- Retry 4: 2 hours later
- Retry 5: 8 hours later
After 5 failures, the webhook is abandoned. Use the /v1/jobs/:id endpoint to poll for status.
Idempotency
Webhooks can fire multiple times for the same event. Your handler must tolerate duplicates. Use job_id as an idempotency key.
Local Development
ngrok http 3000Use the ngrok URL as your webhook_url.
Debugging
Speeko's dashboard shows webhook delivery history with request/response details. Use it to debug failed deliveries.
Common Pitfalls
- Slow endpoint (>10s response) → treated as failure
- Forgot to verify signature → security hole
- No idempotency → double-charges, duplicate notifications
- Synchronous downstream calls → chain of failures