Webhook Integration Guide for TTS and Video APIs

Posted on March 3, 2026
By Speeko Team
webhooksasyncintegrationbackend

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

  1. You submit a job with a webhook_url
  2. Speeko returns a job_id immediately
  3. When the job completes, Speeko POSTs to your URL
  4. 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 3000

Use 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

Set up your webhooks.