Sume webhook delivery statuses: pending to exhausted, and your move
A Sume job webhook has six delivery states, from pending to exhausted. What each means for your receiver, where to read it, and when to redeliver or poll.

A Sume job webhook has a delivery status separate from the job status: pending, delivering, delivered, retrying, failed, or exhausted. The job can be completed while the delivery is exhausted, because the two are tracked on different objects. The practical rule is simple: a job result never depends on the delivery arriving, so a missing callback is a reason to poll, not a reason to resubmit.
The vocabulary comes from the Errors and rate limits page. The Webhooks page says the delivery status and attempt count show on the job object and in the job events when they are available.
The six values
The table lists the values exactly as the docs write them and adds what a receiver should do. The last two columns are my reading of the Webhooks page, not extra Sume fields.
| Delivery status | Your reading | Your move |
|---|---|---|
pending | A delivery is queued for the job's terminal event | Nothing yet; the job may still be running |
delivering | An attempt is in flight | Be ready to answer within 10 seconds |
delivered | Your endpoint returned a 2xx | Store the event by job_id once |
retrying | An attempt failed; another is scheduled | Fix the receiver; Sume retries on its own |
failed | The delivery did not succeed | Poll status_url; redeliver after the fix |
exhausted | All automatic attempts are used (up to 10) | Poll, or call redeliver for the job |
Where to read it
The job object carries a webhook_delivery block, and the job events include webhook.delivery entries. The block holds the callback url, a last_error, and signing_secret_fingerprint. When a Studio Agent turn reads a job that another member created, url and last_error come back null, so the turn sees the state but not the owner's endpoint.
Reading the state is cheap, and reads have their own, larger rate-limit budget than writes. A reconciler that lists terminal jobs and checks their delivery state once a few minutes after completion is a reasonable pattern.
Redeliver after you fix the receiver
POST /v1/jobs/{job_id}/webhook/redeliver needs the jobs:write scope. Sume re-POSTs the real terminal event for that job with a fresh timestamp and signature, and the call still works after the automatic attempts are used up. It does not spend one of the ten automatic attempts, and it never changes the destination URL; a new URL means a new job.
Because the same job_id arrives again, the receiver must treat job_id as the idempotency key. The snippet calls the endpoint and prints the response.
const jobId = process.argv[2];
const res = await fetch(
`https://api.sume.com/v1/jobs/${jobId}/webhook/redeliver`,
{
method: "POST",
headers: { Authorization: `Bearer ${process.env.SUME_API_KEY}` },
},
);
console.log(res.status, await res.text());Do not confuse it with Send test
Send test (POST /v1/webhooks/test-deliveries, needs account:write) posts a dummy signed webhook.test body to a URL you type. It never replays a real job and has no job_id. Use it to prove the URL and the signature check work; use redeliver to replay a real event.
Sources
Related posts
More in Developers
- A Sume webhook receiver in a Cloudflare Worker with verifyWebhook
verifyWebhook uses WebCrypto, not node:crypto, so it can run in a Worker. A fetch handler that refuses an empty secret, checks the signature, returns 204.
- Sume webhook retries: 10 attempts, 270 seconds of gaps, then poll
How long does Sume keep retrying a job webhook? Ten attempts, a 30 second default gap and a 10 second timeout, worked out in seconds, plus a Python dedupe.
- Route Sume job webhooks: handle job.canceled, answer 204 to the rest
Sume sends job.completed, job.failed and job.canceled; run webhooks use another name. A TypeScript router that handles each and returns 204 for the rest.
- Sume webhook signature fails: compare the secret fingerprint first
Webhook signature mismatch? Compare x-sume-webhook-secret-fingerprint with the dashboard before touching code. It is the one value safe to paste in a ticket.
Written by Sume