Use the idempotency_key on Sume job objects as your join label

Every Sume job object returns the idempotency_key it was created with, and list order is newest first. Join your own labels on that key, not on array position.

5 min readSume
All posts

Every Sume job object includes the idempotency_key it was created with, and GET /v1/jobs lists newest first, which is not your submission order once retries happen. Join your own records to jobs on idempotency_key, and never on array position. The key is returned on job objects but is never echoed inside an error body.

What the API says

The list endpoint's description says newest-first is not your submission order once a wave retries, so identity must not be read off array position, and that each row carries the key it was created with. The submit schema says the key doubles as the label you join on when rebuilding which job was which.

Join choices (read 2026-10-06)
Join onSafe?Why
Array position in the listNoNewest first, and retries reorder
Prompt textNoTwo jobs can share a prompt
idempotency_keyYesYou chose it, and every job echoes it
Job id you stored at submitYesFine when the submit response was saved

Rebuild a map after a crash

If your process died before it stored job ids, list the jobs and index them by the key you derived from your own record.

def by_label(jobs: list[dict]) -> dict[str, dict]:
    # idempotency_key is on every job object; array position is not identity
    return {j["idempotency_key"]: j for j in jobs if j.get("idempotency_key")}

jobs = [{"id": "job_b", "idempotency_key": "ad-2"}, {"id": "job_a", "idempotency_key": "ad-1"}]
print(by_label(jobs)["ad-1"]["id"])

Design the key for this use

  • Make it deterministic from your record, such as ad-<order id>-v2, so a rebuild can compute it again.
  • Keep it under 255 printable characters: longer keys or control characters get a 400.
  • Remember that keys are scoped to the member who owns the API key.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume