Public Beta — reserve early accessJoin Waitlist
ThumbAPI logoThumbAPI

Webhooks

Webhooks let you generate thumbnails asynchronously. Instead of waiting for the response, ThumbAPI sends the result to your callback URL when the thumbnail is ready.

Available on Pro and Business plans.

How It Works

  1. You send a generate request with a webhookUrl field
  2. The API returns 202 Accepted immediately with a jobId
  3. When the thumbnail is ready, ThumbAPI POSTs the result to your webhookUrl

Sending a Webhook Request

Add webhookUrl to your normal generate request:

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "Authorization: Bearer tb_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "How to Build a SaaS",
    "format": "youtube",
    "imageStyle": "faceless",
    "webhookUrl": "https://your-app.com/api/webhooks/thumbapi"
  }'

Immediate Response (202)

{
  "jobId": "job_a1b2c3d4e5",
  "status": "processing",
  "webhookUrl": "https://your-app.com/api/webhooks/thumbapi"
}

Webhook Payload

When the thumbnail is ready, ThumbAPI sends a POST to your URL:

{
  "event": "generation.completed",
  "jobId": "job_a1b2c3d4e5",
  "data": {
    "image": "data:image/webp;base64,UklGRp4HAA...",
    "format": "youtube",
    "dimensions": { "width": 1280, "height": 720 }
  },
  "timestamp": "2026-04-27T14:30:00Z"
}

Failed Generation

{
  "event": "generation.failed",
  "jobId": "job_a1b2c3d4e5",
  "error": "Image generation timed out",
  "timestamp": "2026-04-27T14:30:45Z"
}

Handling Webhooks

Your endpoint must return 200 within 10 seconds. If it doesn't, ThumbAPI retries up to 3 times with exponential backoff.

Node.js / Express Example

app.post("/api/webhooks/thumbapi", (req, res) => {
  const { event, jobId, data, error } = req.body;

  if (event === "generation.completed") {
    // Save the thumbnail
    saveImage(jobId, data.image);
  } else if (event === "generation.failed") {
    console.error(`Job ${jobId} failed: ${error}`);
  }

  res.sendStatus(200); // Always acknowledge
});

Security

Verify webhook authenticity by checking the X-ThumbAPI-Signature header. This is an HMAC-SHA256 signature of the request body using your API key as the secret.

import crypto from "crypto";

function verifyWebhook(body, signature, apiKey) {
  const expected = crypto
    .createHmac("sha256", apiKey)
    .update(JSON.stringify(body))
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Next Steps

  • Rate limits — webhook requests count toward your quota
  • Error codes — handling failed generations
  • SDKs — webhook support is built into the official SDKs