Sume job webhooks vs run webhooks: one verifier, two event sets

Job webhooks send job.completed, failed, canceled. Run webhooks send action, format or agent run.terminal. Both share the sume-v1 signature and secret.

5 min readSume
All posts

Sume has two webhook surfaces with separate events and the same signature scheme. Generation jobs send job.completed, job.failed or job.canceled. Action, Format and Agent Completion runs send action.run.terminal, format.run.terminal or agent.run.terminal. One verifier and one signing secret cover both. Only the body handling differs.

Which events you get

The event sets do not overlap, and the payloads differ. A run webhook carries the full run receipt, not a job result.

You calledYou receive
POST /v1/videos, /v1/images, a model endpointjob.completed / job.failed / job.canceled
An Action run endpointaction.run.terminal
A Format run endpointformat.run.terminal
An Agent Completion run endpointagent.run.terminal

Shared signing

Both sign the raw body with HMAC-SHA256 over <timestamp>.<raw_body>, send x-sume-webhook-timestamp and x-sume-webhook-signature: sume-v1=..., and use the workspace secret you store as SUME_COM_WEBHOOK_SIGNING_SECRET. The same rotation window applies to both.

One endpoint, two shapes

If a single endpoint receives both, verify first and then branch on event. Job payloads put artifacts under payload.artifacts and carry a job_id. Dedupe on job_id for job events, and on the run's request_id for run events.

const event = JSON.parse(rawBody); // after verifying
if (event.event.startsWith('job.')) {
  await saveJob(event.job_id, event);
} else if (event.event.endsWith('.run.terminal')) {
  await saveRun(event.request_id, event);
}

Same fallback for both

For jobs, keep status_url polls as a backup. For runs, the SDK offers waitForRun, and subscribeFormatRun polls a Format run client-side. Either way, a delivery is a notification and not the only source of truth.

Related posts

More in Developers

All Developers posts

Written by Sume