SweetRouterAPI

Images and video

Webhooks

Get an HTTPS callback when an image or video job completes or fails, instead of polling.

Set up

Add endpoints on the Webhooks page, or pass webhook_url on a single request. Every enabled endpoint receives job.completed and job.failed.

Payload

http
POST https://your-app.com/webhooks/sweetrouter
SweetRouter-Event: job.completed
SweetRouter-Delivery: cmg9a1...
SweetRouter-Signature: t=1791105133,v1=5f1c...

{
  "id": "cmg9a1...",
  "type": "job.completed",
  "created_at": "2026-10-04T09:12:13.500Z",
  "data": { "id": "cmg8x2k0d0001", "object": "job", "status": "completed", "outputs": [ ... ] }
}

Verify the signature

Each request carries SweetRouter-Signature: t=timestamp,v1=hmac. Compute HMAC-SHA256 of timestamp.rawBody with your signing secret and compare. Reject anything older than 5 minutes.

node.js
import crypto from "node:crypto"

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((part) => part.split("=")))
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex")
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300
  return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))
}

Retries

Respond with any 2xx within 10 seconds. Otherwise we retry after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, then stop. A delivery can arrive more than once, so dedupe on the delivery id.