next_poll_after_seconds vs recommended_poll_interval_seconds

Which delay a Sume poller should sleep: next_poll_after_seconds, recommended_poll_interval_seconds, or retry-after. Null rules, a fallback, and read budgets.

5 min readSume
All posts

Sleep for next_poll_after_seconds when a Sume status response carries it: the OpenAPI schema calls it the suggested minimum delay before the next status poll, and null for terminal jobs. recommended_poll_interval_seconds is the default SDK and CLI cadence for non-terminal jobs, and the HTTP retry-after header is the wait Sume sends on a 429. When none is present, use exponential backoff.

Descriptions below are from the JobStatusResponse schema in the API reference and the polling rule on Jobs and results. The header semantics come from MDN's Retry-After page. All read 2026-10-02.

What does each delay field mean?

Three body fields and one header sound alike. They answer different questions, and none of them is a promise about how long the job will take.

Delay fields on Sume job responses, from the OpenAPI schema and Errors and rate limits docs, read 2026-10-02.
FieldWhereMeaningNull when
next_poll_after_secondsstatus and submit bodySuggested minimum delay before the next status pollThe job is terminal
recommended_poll_interval_secondsstatus and submit bodyDefault SDK/CLI polling cadence for non-terminal jobsThe job is terminal
retry_after_secondsstatus and submit bodyBackoff hint when Sume has delayed the next worker attemptNo special backoff applies
retry-after429 response headerSeconds to wait before retryingOnly sent on a 429

Which one should my loop sleep on?

The docs say to honor next_poll_after_seconds when it is present and back off otherwise. Using recommended_poll_interval_seconds as the second choice is a reasonable reading of its description, but it is my suggestion, not a documented rule. A small helper keeps that order in one place:

def next_delay(st: dict, current: float) -> float:
    return (st.get("next_poll_after_seconds")
            or st.get("recommended_poll_interval_seconds")
            or min(current * 2, 30))

print(next_delay({"next_poll_after_seconds": 3}, 2))  # 3
print(next_delay({}, 2))                              # 4

What about a 429 on the status call itself?

Status reads have their own budget. Sume splits request budgets into reads (any GET or HEAD) and writes, so a tight status loop cannot 429 your own submits. On the Free plan the read budget is 4800 per minute and the write budget is 120; Pro is 12000 and 300. A 429 names the budget in error.details.scope as read or write.

If a poll gets a 429, wait for the retry-after seconds, then continue. Read ratelimit-remaining rather than counting requests yourself. Per the authentication page, the headers describe whichever budget the current request spent from.

When does polling stop?

Poll until terminal is true, or until your own deadline. Both delay fields are null on a terminal job, which is a second signal to stop. The deadline is client-side: the docs suggest 20 minutes for video as a reasonable client deadline, and say a timeout does not cancel the job, so you have only stopped watching.

For many jobs, prefer a webhook with polling kept as a backup, rather than shortening the interval.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume