Avatar video webhook mode: what arrives and what to poll anyway

Use mode webhook for a Sume avatar video and Sume posts one terminal event: completed, failed or canceled. Payload, signature headers and the polling backup.

4 min readSume
All posts

Send mode: "webhook" with a public HTTPS webhook_url, and Sume posts exactly one event when your avatar video job finishes: job.completed, job.failed, or job.canceled. There are no progress events and no partial deliveries. Sume avatars are async jobs: you submit a request, get a job id back, and read the finished video later. There is no live video session. The webhook is how your server hears that the wait is over without holding a request open.

If you send a webhook_url and no mode, you get webhook mode anyway. If you omit both, you get async, and you poll.

What the delivery looks like

The body is JSON with event, request_id, job_id, status, and a payload. A completed job carries status: "OK" and a payload.artifacts array with Sume media URLs. Failed and canceled deliveries carry status: "ERROR" and an error object. Sume signs the raw body with HMAC SHA-256 over <timestamp>.<raw_body> and sends two headers.

Webhook headers and events for generation jobs (Sume docs, read 2026-10-07)
ItemValueNote
x-sume-webhook-timestampUnix secondsReject deliveries outside your replay window; five minutes is a reasonable default
x-sume-webhook-signaturesume-v1=<hex>During secret rotation there is one entry per live secret, newest first, comma-separated
x-sume-webhook-secret-fingerprintFingerprintCompare it with the fingerprint in the dashboard when a signature fails
Eventsjob.completed, job.failed, job.canceledTerminal only

Submit and receive

Webhook URLs must be public HTTPS. Sume rejects localhost, private-network, and non-HTTPS URLs when you submit. Read your signing secret on the Webhooks tab of the dashboard, or with GET /v1/webhooks/signing-secret using an API key that has account:read, and store it as SUME_COM_WEBHOOK_SIGNING_SECRET. Your verifier must refuse to run with an empty secret.

curl -X POST https://api.sume.com/v1/avatar-1.0/talking-video \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: webinar-reminder-001" \
  -d '{
    "avatar_handle": "product_host",
    "script": "Tomorrow at ten we walk through the new reports.",
    "quality": "plus",
    "mode": "webhook",
    "webhook_url": "https://hooks.example.com/sume"
  }'

Why you still poll

The docs call a webhook a delivery optimization, not your only recovery path. Keep status_url polling available for a missed or retried delivery. Store the job id from the first response before you return, so a later poll has something to read. When the webhook says completed, fetch the result and copy the media URL into your own records.

Rules for the receiving endpoint

  • Verify the signature on the raw body before you parse it.
  • Return a 2xx fast, then do the heavy work in a queue.
  • Treat the job id as the idempotency key for your own processing, because a delivery can arrive more than once.
  • On job.failed, read the public error from the job record before you decide whether to retry.
  • Never resubmit a paid avatar request just because a callback was late.

Webhook or poll: which for an avatar video

Polling is the simplest thing that works and needs no public endpoint. It suits a script, a back-office tool, or a first prototype: submit, store the job id, ask for status with backoff, fetch the result. Webhook mode suits a product where a user submits a request in one moment and your server must react in another, such as sending an email with the link when the clip is ready.

Because an avatar video can take longer than a request can stay open, the docs steer you away from sync and subscribe for this work. Those two modes are aliases that wait up to 30 seconds for a terminal state and then return the same job envelope, with sync.timed_out set when the wait ended first. They are useful for short image jobs, and they are the wrong tool for most video.

A good production shape is both at once: submit with mode: "webhook", and also schedule a poll a few minutes later that checks for jobs whose webhook never arrived. The second path costs almost nothing and removes the worst failure mode, a job that finished while your endpoint was down.

What to store

Keep a small record for each request: your own request id, the Sume job id, the Idempotency-Key, the avatar handle, the quality tier, the planned duration, and the status you last saw. With those six fields you can answer "where is this video?", "did we pay twice?" and "how much did this campaign cost?" without searching logs. The job envelope also carries status_url and result_url, so you never need to build those paths by hand.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume