Result 409 on Sume: job_not_completed vs run_not_completed

Both mean not ready: jobs answer 409 job_not_completed, runs 409 run_not_completed with details.status. Poll status_url, then read result_url once.

4 min readSume
All posts

Reading a result too early gives a 409 on both Sume surfaces, with a different code on each: 409 job_not_completed from GET /v1/jobs/:id/result and 409 run_not_completed from GET /v1/format-runs/{run_id}/result. Neither is a failure of the work. Poll the status endpoint until the item is terminal, then read the result once.

The API answers with a conflict on purpose, instead of returning an empty result that looks like success.

The two codes next to each other

The job rule is on the Sume jobs page and the run rule on the Format runs page (read 2026-10-03).

Early result reads on Sume jobs and Format runs (read 2026-10-03)
Generation jobFormat run
Result pathGET /v1/jobs/:id/resultGET /v1/format-runs/{run_id}/result
Early read409 job_not_completed409 run_not_completed, with details.status
Status pathGET /v1/jobs/:id/statusGET /v1/format-runs/{run_id}/status
Ready signalterminal and result_ready are truestatus is completed or failed
Failure is read fromThe job record: GET /v1/jobs/:idThe terminal receipt: error and output_error

What to poll on

For jobs, branch on the booleans terminal and result_ready, or on sume_status. The status endpoint also returns a queue-shaped status (IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED, CANCELED) that maps onto sume_status, but do not mix the two vocabularies in one condition.

A failed or canceled job has no result to read, so asking for it also returns the 409; read the failure off the job record instead. For runs, the lifecycle is queued, processing, then completed, failed, canceled or skipped, and next_action on the receipt says poll_status, retry_later or none.

Use the URLs on the envelope instead of building paths. A job envelope carries status_url, result_url, events_url and cancel_url, and next_poll_after_seconds while it is waiting; a run receipt carries the same four URLs.

JOB=job_123
until [ "$(curl -s https://api.sume.com/v1/jobs/$JOB/status \
  -H "Authorization: Bearer $SUME_API_KEY" | jq -r .terminal)" = "true" ]; do
  sleep 5
done
curl -s https://api.sume.com/v1/jobs/$JOB/result \
  -H "Authorization: Bearer $SUME_API_KEY"

Where the loop should stop

The loop above has no timeout, so wrap it with a deadline of your own, such as 20 minutes for video. A client deadline does not cancel the job; it only stops you watching. For the full backoff version, see poll on next_poll_after_seconds, and for a batch read where some ids are still running, partial success on batch results.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume