Does a failed Sume video job send a webhook to callback_url?
Yes. A job that ends in failure sends job.failed with a public error to the HTTPS callback_url you set on POST /v1/videos, signed like every Sume webhook.

Yes. Pass an HTTPS callback_url on POST /v1/videos and Sume POSTs to it when the job reaches a terminal state. If the job fails, the event is job.failed, sent with a public error; success is job.completed and cancel is job.canceled.
Details are from the Webhooks guide and video docs, read 2026-09-30. Whether a failed job is billed is a separate question, answered in do failed AI video jobs cost money.
Which events can the callback receive?
Sume sends terminal events only. There are no progress or partial deliveries.
| Event | When it is sent | Status in payload |
|---|---|---|
job.completed | A public result is available | OK |
job.failed | The job failed with a public error | ERROR plus an error object |
job.canceled | The job reached canceled state | ERROR plus an error object |
How do I verify and branch on the event?
Sume signs the raw JSON body. Headers are x-sume-webhook-timestamp and x-sume-webhook-signature (sume-v1=<hex>), computed with HMAC SHA 256 over <timestamp>.<raw_body>. Read the raw body before parsing, refuse an empty secret, and reject old timestamps.
import crypto from "node:crypto";
export function handle(raw: string, ts: string, sig: string, secret: string) {
if (!secret) throw new Error("missing webhook secret");
const age = Math.abs(Date.now() / 1000 - Number(ts));
if (!Number.isFinite(age) || age > 300) return "stale";
const hex = crypto
.createHmac("sha256", secret)
.update(ts + "." + raw)
.digest("hex");
const want = "sume-v1=" + hex;
const ok = sig.split(",").some((s) => {
const a = Buffer.from(s.trim());
const b = Buffer.from(want);
return a.length === b.length && crypto.timingSafeEqual(a, b);
});
if (!ok) return "bad signature";
const body = JSON.parse(raw);
return body.event === "job.failed" ? "failed" : body.event;
}What should the handler do on job.failed?
Record job_id and the error object, mark the item failed in your system, and decide whether to resubmit. Keep polling as a fallback: the docs recommend a polling path alongside webhooks, since a delivery can be missed.
Does the URL have to be public?
It must be HTTPS. For the model endpoints, webhook URLs must be public; localhost, private-network, and non-HTTPS URLs are rejected. See webhook URL rejected.
Sources
Related posts
- Do failed AI video generations cost credits? Reserve, capture, refund
- Wan 3.0 webhook: get notified when a 30-second clip finishes
- Webhook security best practices: a receiver checklist
- Sume webhook not received? How to debug delivery and signatures
- Signed webhooks for Sume video runs: events, retries, verification
More in Developers
- Get the rendered MP4 back from a video editing API job
Descript's API lists no rendered file download without publishing. In Sume, a finished timeline_render job result carries video_url; here is the poll flow.
- Durable Object waitUntil keep-alive and a Sume job poll
Pending I/O now keeps a Durable Object alive without a client, but a Sume video job is better tracked by job id, status_url polling or a webhook.
- Edit a transcript with an AI instruction: Sume's STT flow
ElevenLabs STT accepts an edit instruction and returns edited_transcript. Sume's STT has no such field: it returns text and word timings to edit yourself.
- ElevenLabs per-key concurrency caps vs Sume's plan limit
ElevenLabs lets enterprise service account keys carry TTS, music and dubbing concurrency limits. Sume has one plan-based limit and no per-key setting.
Written by Sume