Sume jobs list: no next_cursor on the last page ends the loop

GET /v1/jobs returns up to 100 jobs newest first. Pass data.next_cursor back as starting_after, and stop when it is absent. Do not build a cursor yourself.

4 min readSume
All posts

GET /v1/jobs returns at most 100 jobs per page, newest first. When more remain, data.next_cursor is present, and you pass it back as starting_after. On the last page it is absent, and that absence is your loop terminator. Do not build a cursor from the last job id, because the cursor is opaque. An undecodable cursor is treated as the first page.

Paging rules in one table

GET /v1/jobs paging (read 2026-10-06)
RuleDetail
OrderNewest first
Page sizeUp to 100
Next pageSend data.next_cursor as starting_after
Last pagenext_cursor is absent
Undecodable cursorTreated as the first page, not an error
VisibilityAn API key lists its own member's jobs

A generator that follows the cursor

It stops when the field is missing, and it never inspects job ids.

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"))

Common mistakes

  • Looping until a page is empty: that costs one extra read, which counts against your read budget.
  • Assuming the order matches your submission order. Retries break that, so join on idempotency_key.
  • Passing a job id as the cursor: it will not decode, and you get the first page again, which can loop forever.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume