Worker crashed mid-poll: list Sume jobs and join on idempotency_key

After a restart, GET /v1/jobs?status=processing lists your in-flight video jobs. Each row carries the idempotency_key you sent, so match your records on it.

5 min readSume
All posts

If a worker died after submitting Sume video jobs but before saving their ids, list the jobs with GET /v1/jobs?status=queued and status=processing and match each row to your own record by its idempotency_key. The list is newest first, capped at 100 per page, and an ordinary API key sees the jobs its owner created.

Do not match by position. The OpenAPI text says newest-first is not your submission order once a wave retries, and that the idempotency_key on each row is the column to join on.

The query parameters

These are the ones that matter for recovery. An unknown query parameter is a 400 unknown_parameter, not a silently unfiltered page.

GET /v1/jobs parameters, OpenAPI read 2026-10-08
ParameterValuesUse
statusqueued, processing, completed, failed, canceledone status per call
limit1 to 100page size
starting_afterthe next_cursor from the last pagenext page; absent cursor means done
scopethread or workspacean ordinary key defaults to its owner's jobs
typeany non-empty stringnarrow by job type

Walk the pages

Do not invent a cursor from the last job id. When data.next_cursor is missing you are on the last page. Run this with SUME_API_KEY set; it prints the id, status and key of every unfinished job.

import json, os, urllib.request

def page(status, cursor):
    url = "https://api.sume.com/v1/jobs?limit=100&status=" + status
    if cursor:
        url += "&starting_after=" + cursor
    req = urllib.request.Request(
        url, headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]})
    return json.load(urllib.request.urlopen(req))["data"]

def main():
    for status in ("queued", "processing"):
        cursor = None
        while True:
            data = page(status, cursor)
            for job in data["jobs"]:
                print(job["id"], job["status"], job["idempotency_key"], job["created_at"])
            cursor = data.get("next_cursor")
            if not cursor:
                break

main()

Why this replaces OpenAI's list call

OpenAI's video guide, read 2026-10-08, includes list and delete operations on videos, and the Videos API itself is removed on September 24, 2026. Sume's list is a read-only view over jobs of all kinds, not only video, so keep your own table as the source of truth and use the list for recovery.

Choose your Idempotency-Key from your record id at submit time, which makes this join possible; a random key per attempt leaves you with rows you cannot match. The storage post covers the columns to keep, and the list and delete post covers the removed routes.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume