Webhook receiver was down: replay missed Sume job webhooks

After a receiver outage, list completed jobs and POST /v1/jobs/{job_id}/webhook/redeliver one by one. Sume has no bulk cancel-before-cutoff call.

4 min readSume
All posts

List the jobs that finished while your receiver was down, then call POST /v1/jobs/{job_id}/webhook/redeliver for each. Redeliver is per call and works after the automatic attempts are exhausted. Sume has no single call that cancels or replays everything before a cutoff time.

Sume behavior is from Webhooks and the OpenAPI spec, read 2026-09-30. The Svix September 2026 changelog is the reason people ask: it describes cancelling pending deliveries created before a cutoff.

What happens to deliveries while the receiver is down?

Network errors and non-2xx responses are retried until attempts are exhausted: up to 10 attempts total, with a fixed delay (30s by default) and a 10s timeout per attempt. Ten refused attempts leave a failed delivery and a job that still reached its real terminal state. "Delivery is an optimization, never the only recovery path."

How do I find what I missed?

GET /v1/jobs accepts status (queued, processing, completed, failed, canceled), results are newest-first and capped at 100 per page, and data.next_cursor goes back as starting_after. Absence of next_cursor ends the loop. Compare job ids against what your receiver stored; job_id is the idempotency key.

How do I redeliver them?

Each call re-POSTs the job's real terminal event (job.completed, job.failed or job.canceled) with a fresh timestamp and signature. It needs jobs:write, and returns 409 if the job is still running or was created without a webhook_url. Redeliver does not change the destination URL.

const base = "https://api.sume.com/v1/jobs";
const headers = { Authorization: "Bearer " + process.env.SUME_API_KEY };
let cursor: string | null = null;
do {
  const qs = new URLSearchParams({ status: "completed", limit: "100" });
  if (cursor) qs.set("starting_after", cursor);
  const res = await fetch(base + "?" + qs.toString(), { headers });
  const page = await res.json();
  for (const job of page.data.jobs) {
    if (await alreadyStored(job.id)) continue; // your dedupe on job_id
    const r = await fetch(base + "/" + job.id + "/webhook/redeliver", {
      method: "POST",
      headers,
    });
    if (r.status === 409) continue; // no webhook_url, or still running
  }
  cursor = page.data.next_cursor ?? null;
} while (cursor);

What has no Sume equivalent?

Backlog recovery operations, Sume docs read 2026-09-30: https://docs.sume.com/workflows/webhooks
NeedSume
Replay one job's terminal eventPOST /v1/jobs/{job_id}/webhook/redeliver
Replay everything before a timeLoop the list and redeliver per job
Cancel pending deliveries before a cutoffNot documented
Recover without webhooksPoll status_url per job

Should I redeliver or just poll?

If your pipeline already polls, read the results directly and skip redelivery. If downstream steps are driven by webhook handlers, redeliver so they run once, and rely on job_id dedupe so a replay of something you did receive is harmless. Mixing up redeliver with "Send test" is common; see send test vs redeliver.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume