Sume job response: status_url, result_url, events_url, cancel_url

A Sume submit returns four URLs: status_url to poll, result_url once result_ready is true, events_url for the timeline, cancel_url while cancelable is true.

5 min readSume
All posts

A Sume submit response carries four URLs inside data: status_url to poll, result_url to fetch once result_ready is true, events_url for the job's lifecycle timeline, and cancel_url to cancel while cancelable is true. A 2xx on submit means the job exists and paid work is in flight; it does not mean the job finished, so keep the job id and these URLs.

This post reads the field list from the API reference (the SubmitJobResponse and JobStatusResponse schemas in the OpenAPI file) and the polling rules from Jobs and results, both read 2026-10-02.

What does each of the four URLs do?

The OpenAPI schema gives each URL one job. The same four also come back on every status read, so you can recover them after a restart from the job id alone.

URL fields on the submit and status responses, from the Sume OpenAPI schema and Jobs and results docs, read 2026-10-02.
FieldCall it whenWhat the schema says
status_urlThe job is queued or processingPoll this URL for current queue/job status.
result_urlresult_ready is trueFetch after result_ready is true; a non-completed job returns 409 job_not_completed.
events_urlThe job failed or was canceled, or you are debuggingSanitized lifecycle, generation, terminal, and webhook delivery events.
cancel_urlcancelable is truePOST to cancel; null after generation starts and after terminal states.

Which flag tells me what to call next?

Read next_action instead of inferring it from the status string. It is poll_status for queued or processing jobs, fetch_result once the job completed, and inspect_events for failed or canceled terminal jobs. Two booleans back it up: terminal is true when polling can stop, and result_ready is true only when /result can return 200 with a body.

The same submit also reports next_poll_after_seconds, idempotency_hit, and a usage estimate. This one-liner trims the envelope to the fields a poller needs:

curl -sX POST https://api.sume.com/v1/images \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-8823-hero-v1" \
  -d '{"model":"sume/auto","prompt":"matte black bottle on marble","mode":"async"}' \
  | jq '.data | {request_id, status_url, result_url, next_action, next_poll_after_seconds, idempotency_hit}'

Does a 2xx mean the result is ready?

No. Every communication mode returns the job id in its first response. With mode: "sync" the server waits at most 30 seconds, and if that budget runs out the response is still 2xx with a sync object whose timed_out or capacity_exhausted is true. The docs say to continue with GET status_url and not to submit a new paid job for the same intent.

Retrying the submit itself is fine when you reuse the same Idempotency-Key: the retry returns the original job instead of billing a second one, and idempotency_hit tells you which case you got.

What happens when cancel_url is null?

cancel_url is null once generation has started and once the job is terminal, and cancelable is false. Calling cancel at that point returns 409 job_generation_already_started with details.cancelable: false, and the job runs to completion. Cancelling a job that is already canceled is idempotent. Cancel queued jobs you no longer need before they start processing.

What should I store?

Three things make a restart safe.

  • The job id (request_id on the envelope, job.id inside it) next to your own business key, so a restart can pick the job back up.
  • The four URLs, when present. The generation admission page recommends storing them.
  • Use Sume media URLs from the result. Raw provider URLs are not public API outputs.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume