Which fields to keep from a Sume submit response
Keep the job id, status_url, result_url, events_url, cancel_url, the sync flags and next_poll_after_seconds. Use generation_limits for pacing only.

Keep the job id (request_id), the four links status_url, result_url, events_url and cancel_url, the sync object when it is not null, and next_poll_after_seconds. Read generation_limits for pacing, and do not store it as a fact. A submit that you saved in full is a submit that you can resume, debug and reconcile without a second paid call.
Persisting the response is cheap, and it removes a whole class of questions later. A support case that starts with a job id and no record of what the submit answered is much slower than one that starts with the stored envelope.
A record like this also protects you from a double charge. When the process restarts, the stored job id and links let it carry on with polling, and it has no reason to submit again.
What the response is for
A submit response answers a question that every caller has: what do I do next. The links say where to look, the poll hint says when to look, and the sync flags say whether the wait you asked for finished. The response is still a 2xx when the wait budget ends, because running out of wait time is not an admission failure.
Do not rebuild the URLs from the id, even though they look predictable. The response gives you status_url, result_url, events_url and cancel_url, and following them keeps your code correct if a route moves. Treat them as opaque links that Sume hands to you.
If you use the SDK, the helpers read these fields for you. waitForJob follows the poll hint and next_poll_after_seconds when it is longer than the floor of two seconds, so you may only need to store the id.
Keep, use, or ignore
Use the table to decide what goes into your own record.
A short habit pays off. Log the whole envelope once, at debug level, for every submit during the first weeks of an integration. You will learn which fields appear for your routes, and you will have exact evidence when something looks wrong.
| Field | Do this |
|---|---|
| request_id (the job id) | Store it, it is the key for polling |
| status_url, result_url, events_url, cancel_url | Store them, and follow them instead of building URLs |
| next_poll_after_seconds | Obey it for the first poll, then follow each status response |
| sync.timed_out, sync.capacity_exhausted | Continue with a poll when either is true |
| generation_limits | Use it to size the next wave, do not store it |
Save the durable part
The function below copies the durable part of a response and drops the rest. It runs as is, and the demo shows the sync flags being kept only when present.
The sync object is null on async and webhook responses, so a null check is the right first step. When it is present, timed_out and capacity_exhausted are the two flags that matter, and both lead to the same action. Continue with a poll of the status URL, and never submit a new paid job for the same intent.
The poll hint deserves one more word. next_poll_after_seconds is a hint from the server about when the status is likely to change, and the docs say to obey it when it is present. If it is missing, use your own backoff. Do not poll in a tight loop in either case.
def keep(resp: dict) -> dict:
out = {
"job_id": resp["request_id"],
"status_url": resp.get("status_url"),
"result_url": resp.get("result_url"),
"events_url": resp.get("events_url"),
"cancel_url": resp.get("cancel_url"),
"poll_after": resp.get("next_poll_after_seconds"),
}
sync = resp.get("sync")
if sync:
out["sync_timed_out"] = bool(sync.get("timed_out"))
out["sync_capacity_exhausted"] = bool(sync.get("capacity_exhausted"))
return out
demo = {"request_id": "job_demo", "status_url": "/v1/jobs/job_demo/status",
"next_poll_after_seconds": 2, "sync": {"timed_out": True, "capacity_exhausted": False},
"generation_limits": {"active_generation_jobs": 1}}
print(keep(demo))
Keep the key beside the response
Keep the idempotency key in the same record. If a submit times out before you get the response at all, you have none of these fields, and the key is what lets you ask again safely. Retry the submit with the same key, and Sume returns the original job instead of billing a second one.
The generation limits snapshot is not durable data. It can change right after the response, because workers claim jobs and other clients submit work. Use it to pace the next few submits, and do not store it as a fact about your account.
Sources
Related posts
More in Developers
- Which login is my agent using? mcp_health auth_source on Sume MCP
Call mcp_health on the hosted Sume server to see the auth source of your session, then tools_list and account_me. Read-only OAuth and API-key sessions differ.
- Which Omni input continues a scene: end frame, reference clip or edit?
Sume has no extend button. Continue an Omni scene with a last-frame image, a 3 s reference clip, or a video edit; this table says which, with costs per 10 s.
- What ends a Sume STT sentence segment: . ! ? and the Japanese marks
Sume ends a segment on . ! ? 。 ! ? … plus optional trailing quotes or closing parentheses; the corner bracket 」 and a fullwidth ) are not on that list.
- Which API key scope does each Sume webhook endpoint need?
The signing secret needs account:read, rotate and test deliveries need account:write, redeliver needs jobs:write or formats:write. Map each call to a key.
Written by Sume