jobs_result batch: read a wave when some jobs are still running
Sume's batch jobs_result returns one entry per id in request order. Read ok per entry, treat job_not_completed as running, and re-read only failed_job_ids.

Pass the ids to one jobs_result call as job_ids and read the ok field of each entry, not the call as a whole. Sume's batch form takes 1 to 20 ids, the same ceiling as jobs_wait, and returns a job_result_batch: results[] in request order, one entry per id, each with ok plus either value or a typed error. Partial success is normal and deliberate, so a single running job does not hide the finished ones.
Everything here is from Jobs and results and the MCP tools and gates page.
What does one entry look like?
The documented request is a list: { "job_ids": ["<first id>", "<second id>", "<third id>"] }. Each entry in the response is independent. A finished job returns ok: true with its value; an id that is still running comes back as job_not_completed, while every finished id still returns its result. A failure on one id says nothing about the others.
The response also carries partial_failure.failed_job_ids, which the docs say names exactly the ids worth re-reading. That is the list to feed back in, instead of re-reading the whole wave.
| Field | Meaning | What to do |
|---|---|---|
object: "job_result_batch" | The batch response | Read results[] |
results[] | One entry per id, in request order | Match by position or id |
ok: true with value | The job's result | Use it |
ok: false with job_not_completed | Job still running | Wait again, then read |
partial_failure.failed_job_ids | Ids worth re-reading | Re-read only these |
How does this pair with jobs_wait?
Wait first, then read. jobs_wait accepts job_ids with wait_for set to all (the default) or any, holds at most 55 seconds per call (default 50), and answers with a job_wait_batch that has a status snapshot for every id. With wait_for: "any" it still reports every id, and the remaining jobs continue and still bill.
If the slice ends first, the response is wait_slice_expired: call jobs_wait again with the same ids. Never resubmit the create, because that would pay twice for the same render. When the wait reports the wave done, one batch jobs_result collects it.
When should I use include_results instead?
Use include_results: true on the wait when you expect small results: every id that completed comes back in results[] with the same entries a batch jobs_result returns, so no separate read is needed. Ids whose results do not fit in one answer are named in results_omitted.job_ids, and the docs say to read those with one batch jobs_result.
Unknown or foreign-workspace ids fail a whole jobs_wait call, so keep the id list to jobs your session created. If a wait answers operator_stopped, those jobs are terminal with no output, and re-issuing the wait on them cannot change the answer.
What mistakes does this prevent?
Three. Reading only the top level and calling the wave failed because one id was still running. Retrying the create instead of the read when a single entry errors. And re-reading all 20 ids when failed_job_ids names two. Each costs time or money; the batch shape exists so none of them is necessary.
Remember that credentials decide what you can read: OAuth sessions see read-only tools, which the tools page lists as jobs_list, jobs_get, jobs_status, jobs_result, jobs_events and jobs_wait, while submits need write at consent or an API key and an idempotency_key.
{
"job_ids": ["<first id>", "<second id>", "<third id>"]
}How big should a wave be?
The ceiling is 20 ids per call, for both waiting and reading. A smaller wave of five to eight is easier to reason about, easier to fit in the client's output limit, and cheaper to re-read when one id fails. Use the full 20 only when you fan out a single batch and want one answer.
Whatever size you pick, keep the id list in your own notes or script rather than asking the model to recall it. The ids are the only handle on work that is still billing.
Sources
Related posts
More in Developers
- A kill switch for paid Sume submits: stop new jobs, cancel queued
Add an off switch to code that spends on the Sume API: check a flag before each submit, then cancel queued jobs; a 409 job_generation_already_started will bill.
- kling-3 on Sume: generate_audio true or false, and what changes
kling-3 has an audio toggle; MiniMax H3 and Omni audio is always on. The catalog lists separate audio-on and audio-off list rates.
- Kling 3 input_references 400 unsupported_capability: fix
Sending input_references to kling-3 on Sume returns 400 unsupported_capability. Move the image to frame_images or pick a model that takes references.
- Kling 3.0 Motion Control on Sume: four routes, one stored model id
POST /v1/kling/3.0/motion-control and three aliases all store kling/3.0/motion-control. How to pick a route, what the body needs, and what the job reserves.
Written by Sume