Sume submit response: the sync object is null on async and webhook

In a Sume job envelope, data.sync is null for async and webhook modes. Check it for null before you read timed_out or capacity_exhausted.

4 min readSume
All posts

In a Sume submit response, data.sync is null when the mode is async or webhook. It is filled in only for sync and subscribe, which wait up to 30 seconds. Code that reads data.sync.timed_out without a null check will crash on an async submit, so check for null first and poll status_url in every case where the job is not terminal.

What the fields mean

After a bounded wait, the envelope says whether the wait ended before a terminal state or was skipped.

data.sync fields (read 2026-10-06)
FieldMeaning
wait_timeout_secondsWait budget you asked for, clamped to 0 to 30
timed_outTrue when the response returned before a terminal state
capacity_exhaustedTrue when the API skipped the wait because the waiter budget was full
result_readyTrue when result_url can return a result

A null-safe branch

Either case is still a 2xx with a job id. Do not resubmit; poll.

def next_step(body: dict) -> str:
    data = body["data"]
    sync = data.get("sync")  # None on async and webhook submits
    if sync is None:
        return "poll status_url"
    if sync["timed_out"] or sync["capacity_exhausted"]:
        return "poll status_url"
    return "read data.job"

print(next_step({"data": {"sync": None}}))
print(next_step({"data": {"sync": {"timed_out": False, "capacity_exhausted": False}}}))

Why 30 seconds is not a job duration

The wait budget bounds how long the HTTP request blocks. Video and avatar-video jobs usually outlast it, so a migrated code path that was a single blocking call needs a poll loop or a webhook behind it.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume