Runway polling: 5 seconds, jitter, backoff vs Sume next_poll_after
Runway recommends polling tasks every 5 seconds or more with jitter and exponential backoff. Sume returns next_poll_after_seconds. A Python poller for both.

Runway recommends polling a task no faster than every 5 seconds, adding jitter, and backing off exponentially on non-200 responses, and it warns against a fixed setInterval because API latency can bunch requests. Sume goes one step further: the job status response can include next_poll_after_seconds, and clients should honor it when present and back off otherwise.
The two sets of rules
The Runway rules in order: a 5-second floor, jitter, exponential backoff on errors and no fixed-interval timers. The reason given is that latency makes a fixed timer too frequent on some ticks.
| Item | Runway | Sume `/v1/jobs` |
|---|---|---|
| Interval | 5 seconds or more | next_poll_after_seconds when present |
| Jitter | Recommended | Not stated on the pages read; add it anyway |
| Errors | Exponential backoff on non-200 | Back off when the hint is absent |
| Fixed timers | Avoid | Avoid |
| Push alternative | Not covered here | Signed webhooks; keep polling as fallback |
A poller that follows both
This poller waits for a Sume job, honors the hint and uses jitter. Set SUME_API_KEY and pass a job id.
import os, random, sys, time
import requests
BASE = "https://api.sume.com"
TERMINAL = {"completed", "failed", "canceled"}
def wait(job_id, timeout=600):
headers = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
deadline = time.time() + timeout
delay = 5.0
while time.time() < deadline:
r = requests.get(f"{BASE}/v1/jobs/{job_id}/status", headers=headers, timeout=30)
if r.ok:
body = r.json()
if body.get("status") in TERMINAL:
return body
hint = body.get("next_poll_after_seconds")
delay = float(hint) if hint else 5.0
else:
delay = min(delay * 2, 60)
time.sleep(max(5.0, delay) + random.uniform(0, 1.5))
raise TimeoutError("still running; cancel the job if you no longer need it")
if __name__ == "__main__":
print(wait(sys.argv[1]))Prefer a push
Polling is the fallback, not the plan. For many jobs, use a signed webhook and sweep with polling only for the ones that never call back.
Sources
Related posts
More in Developers
- Runway THROTTLED task status vs Sume queued jobs
Runway tasks over your concurrency limit show THROTTLED and are enqueued roughly in submit order. Sume accepts them as queued. How to handle each in a client.
- Feed scraped product copy to a Format run: input, not instruction
Putting a supplier's text into a Format's instruction lets it steer the run. Sume's input field is treated as data, with a 64-key and 2 MiB limit.
- script_run budgets: call, paid-call and timeout limits on MCP
script_run caps a Sume MCP program by timeout (5-55 s), max_calls and max_paid_calls, and stops with a named error code. Defaults, ceilings and what to do next.
- Seedance 2.5 60 FPS on Dreamina: is there a frame-rate field?
Dreamina's plan page lists frame-rate improvements up to 60 FPS and resolution upgrades. Sume's video request has no fps field; here is what it takes instead.
Written by Sume