Promise.allSettled for many Sume job statuses: isolate one failure
Check many Sume job statuses at once with Promise.allSettled so one 429 or network error is reported on its own row and does not hide the other results.

Use Promise.allSettled instead of Promise.all when you check many Sume jobs together. Promise.all rejects on the first failure and discards the rest, while `allSettled` waits for every promise and gives you a status for each one. A single 429 or dropped connection then shows up on its own row, and the finished jobs still report.
Each call goes to GET /v1/jobs/{id}/status, described in the jobs and results docs. The sample prints one line per job id: terminal, the seconds to wait before the next check, or the failure reason. We ran it on Node 22.14 against a local stand-in, with one unreachable base URL to see the failure row.
Reading rate-limit hints
The authentication docs say to read ratelimit-remaining rather than count requests yourself, and to wait for retry-after (seconds, sent on a 429). The sample copies retry-after onto the error so a failed row says how long to wait. A burst of status checks counts against the same requests-per-minute budget as other calls, so cap the fan-out for large lists.
| Outcome | How to detect | What to print |
|---|---|---|
| Terminal | fulfilled, data.terminal true | terminal |
| Still running | fulfilled, terminal false | next_poll_after_seconds |
| Rate limited | rejected, HTTP 429 | retry-after seconds |
| Network error or timeout | rejected, no HTTP status | error message |
Steps
- Wrap one status call in an async function that throws on a non-2xx answer and attaches
retry-after. - Give each request its own
AbortSignal.timeout. - Map the ids to promises and await
Promise.allSettled. - Print or store one row per id by index.
- Re-check only the rows that were not terminal, after the longest wait.
Sample
Pass job ids as arguments: node check.mjs id1 id2. The key comes from SUME_API_KEY.
const key = process.env.SUME_API_KEY ?? "";
const base = process.env.SUME_BASE ?? "https://api.sume.com";
if (!key) throw new Error("SUME_API_KEY is empty");
async function status(id) {
const r = await fetch(`${base}/v1/jobs/${id}/status`, {
headers: { authorization: `Bearer ${key}` },
signal: AbortSignal.timeout(10_000),
});
if (!r.ok) throw Object.assign(new Error(`HTTP ${r.status}`), { retryAfter: r.headers.get("retry-after") });
return (await r.json()).data;
}
const ids = process.argv.slice(2);
const results = await Promise.allSettled(ids.map(status));
results.forEach((res, i) => {
if (res.status === "fulfilled") {
const d = res.value;
console.log(ids[i], d.terminal ? "terminal" : `again in ${d.next_poll_after_seconds}s`);
} else {
const wait = res.reason.retryAfter ? `, retry-after ${res.reason.retryAfter}s` : "";
console.log(ids[i], "failed:", res.reason.message + wait);
}
});Limits of the pattern
Fan-out is simple, but it is not free. Fifty simultaneous status checks hit your requests-per-minute budget in one burst, and a 429 on several rows at once means the whole group should back off together. For large lists, process ids in slices of a size you choose, wait for each slice, and then sleep for the longest next_poll_after_seconds you saw.
Also keep results by index. allSettled returns an array in the same order as the input, which is why the sample can print the id next to each outcome without extra bookkeeping. That makes the output easy to diff between two runs, and easy to feed into a dashboard or a retry list for the ids that failed.
Log the failures with the id, the HTTP status when there is one, and the wait hint, so the next person can tell a rate limit from an outage at a glance.
What Sume does not do
Sume has no documented batch status route in the pages we read, so this makes one request per job. It does not queue your status checks, and a failed row is not a failed job: the job keeps running and can be checked again.
Sources
Related posts
More in Developers
- Prompting Omni Flash with sound: write the audio as its own line
Gemini Omni Flash 1.1 always generates audio. A prompt layout that separates picture from sound, three example prompts, and the request on Sume.
- Python 3.15 rc3 in CI: test your Sume job poll logic before Oct 9
Python 3.15.0rc3 is out and the final is planned for Oct 9. Add a CI job that runs a stdlib unittest on your Sume status-poll decision function.
- Python argparse CLI that checks seconds per Sume model first
A 25-line argparse CLI: choices reject unknown models, a duration check uses the documented limits, and --dry-run prints the body. Runs offline.
- Python asyncio price check: one Omni Flash clip at four resolutions
A runnable Python script submits a 3-second Omni Flash clip at 360p, 720p, 1080p and 4K together and prints usage.cost. Expect $2.20 in total.
Written by Sume