Wan 3.0 webhook: get notified when a 30-second clip finishes

Long Wan 3.0 clips take minutes. Pass callback_url on POST /v1/videos and Sume posts a signed webhook when the job ends, so you don't have to poll wan-3.0.

4 min readSume
All posts

To skip polling on a Wan 3.0 job, add callback_url to the POST /v1/videos body. It must be an HTTPS URL; when the job reaches a terminal state Sume POSTs to it with a signed JSON body, and you then fetch the clip from the job.

Wan 3.0 clips run up to 30 seconds, and the docs say video generation can take from 30 seconds to several minutes, so a callback fits. The fields come from the Video generation and Webhooks docs, read 2026-09-29.

How do I set the callback?

curl -X POST https://api.sume.com/v1/videos \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: wan-callback-001" \
  -d '{
    "model": "wan-3.0",
    "prompt": "A time-lapse of clouds crossing a mountain lake",
    "duration": 20,
    "resolution": "720p",
    "callback_url": "https://example.com/hooks/sume-video"
  }'

What does Sume send to my endpoint?

Sume's standard job webhook envelope, not OpenRouter's video.generation.* events. It signs the raw JSON body and adds two headers.

From Video generation and Webhooks, read 2026-09-29.
HeaderUse
x-sume-webhook-timestampSigned timestamp; reject stale ones
x-sume-webhook-signaturesume-v1= signature over <timestamp>.<raw_body>
x-sume-webhook-secret-fingerprintWhich signing secret was used

How do I verify it?

Compute an HMAC SHA 256 of <timestamp>.<raw_body> with your signing secret and compare it with the sume-v1= entry, using the raw bytes, not a re-serialized body. Refuse to verify at all when the secret is empty. The Webhooks docs have a full verifier; read them before you ship one.

What if the callback never arrives?

Keep the job id and poll GET /v1/videos/{jobId} as a backstop, and send an Idempotency-Key on submit so a retry returns the original job rather than a second billed clip. A failed job carries an error field to read.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume