Sweep for missed Sume webhooks: list queued and processing jobs

A webhook is an optimization. Run a periodic sweep over GET /v1/jobs with status=queued and processing, then compare against your own records and re-check each.

5 min readSume
All posts

Run a periodic sweep: list your non-terminal jobs with GET /v1/jobs?status=processing (and queued), compare them with the jobs your database thinks are finished, and read each stuck one from its status URL. The docs say a webhook is a delivery optimization and not your only recovery path, and a sweep is how you act on that.

Why a sweep and not just retries

Sume tries a webhook up to 10 times. After that you have a failed delivery and a job that still reached its real terminal state. Your receiver may also have stored nothing during an outage.

Recovery tools (read 2026-10-06)
ToolFindsNeeds
Webhook retriesTerminal events during a short outageNothing
Sweep over GET /v1/jobsJobs you lost track ofA scheduled task
GET /v1/jobs/:id/statusOne job's stateThe job id
Webhook redeliverRe-sends the real terminal eventjobs:write and a job with a webhook_url

A paged listing

An API key lists the jobs its own member created in the workspace. Results are newest first, up to 100 per page, and data.next_cursor is passed back as starting_after.

import os, requests

BASE = "https://api.sume.com/v1/jobs"
HEADERS = {"Authorization": f"Bearer {os.environ.get('SUME_API_KEY', '')}"}

def list_jobs(session, status):
    cursor = None
    while True:
        params = {"status": status, "limit": 100}
        if cursor:
            params["starting_after"] = cursor
        r = session.get(BASE, headers=HEADERS, params=params, timeout=30)
        r.raise_for_status()
        data = r.json()["data"]
        yield from data["jobs"]
        cursor = data.get("next_cursor")
        if not cursor:  # absent on the last page
            return

if __name__ == "__main__":
    with requests.Session() as s:
        for status in ("queued", "processing"):
            for job in list_jobs(s, status):
                print(job["id"], status, job.get("idempotency_key"))

What to do with each row

  • If a job is terminal in Sume and open in your records, read its result and close it.
  • If it is still processing, leave it alone and keep polling its status URL.
  • If you want the callback again, use Redeliver instead of resubmitting.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume