Sume webhooks plus a sweeper: recover jobs whose callback never came

Webhook delivery can fail after 10 attempts while the Sume job still finishes. Run a sweeper that polls jobs stuck non-terminal in your own table.

5 min readSume
All posts

A Sume job webhook can fail to reach you and the job will still finish. Delivery is retried up to 10 attempts total with a 10 second timeout each, and ten refused attempts leave a failed delivery but a job in its real terminal state. The docs say to keep status_url polling available for exactly this, and a sweeper is that polling, done once in a while rather than in a tight loop.

The pattern

Store every job id with a status column on submit. The webhook handler marks a row terminal. A scheduled sweeper selects rows still non-terminal after your usual job time, reads their status once, and marks them. Redeliver is a second option: POST /v1/jobs/{job_id}/webhook/redeliver re-sends the real terminal event with a fresh signature and does not use one of the automatic attempts.

import asyncio, os
import httpx

async def sweep(open_job_ids: list[str]) -> dict[str, str]:
    headers = {"x-api-key": os.environ["SUME_API_KEY"]}
    found: dict[str, str] = {}
    async with httpx.AsyncClient(base_url="https://api.sume.com", headers=headers) as c:
        for job_id in open_job_ids:
            r = await c.get(f"/v1/jobs/{job_id}/status")
            r.raise_for_status()
            body = r.json()
            if body.get("terminal"):
                found[job_id] = body.get("sume_status", "unknown")
    return found

async def main() -> None:
    print(await sweep(["job_123"]))

asyncio.run(main())

Make handling idempotent

Both paths can report the same job, so key your handler on job_id and ignore a second report. Use the same handler function for the webhook and the sweeper.

Webhook versus sweeper (read 2026-10-03)
PathLatencyCovers
WebhookSeconds after the terminal eventNormal case
SweeperYour scheduleDeliveries that exhausted retries
Redeliver callOn demandOne known job, after you fix the endpoint

What not to do

Do not resubmit the paid request because a callback is missing; that creates a second paid job. Read the status instead.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume