Apps Script fetchAll: check 20 Sume run statuses in one call
fetchAll takes an array of requests and returns an array of responses. Use it to poll many Sume run statuses in one trigger without a loop of fetches.

UrlFetchApp.fetchAll(requests) takes an array of request objects and returns an array of HTTPResponse objects in the same order, so one trigger can check twenty Sume runs with one call. Google's reference does not say the requests run in parallel, so treat it as a convenience that shortens your code, and measure it before you count on speed.
The Apps Script facts come from Class UrlFetchApp, read 2026-10-10. The Sume facts come from Runs and results and Bulk runs.
What does the reference promise?
The reference shows fetchAll returning HTTPResponse[]. It documents the muteHttpExceptions option, which returns error responses instead of throwing, a URL length limit of 2,082 characters, and a default timeout of 360 seconds. It does not state that requests run concurrently or give a per-call count cap, so those are not facts to build on.
| Topic | Reference says | Consequence for polling |
|---|---|---|
| Return value | HTTPResponse[] | Match responses to runs by index |
| Errors | muteHttpExceptions returns the response instead of throwing | Set it so one 429 does not hide 19 results |
| URL length | 2,082 characters maximum | Status URLs are short; keep ids, not payloads, in them |
| Timeout | 360 seconds by default | Longer than any status read needs |
| Parallelism | Not stated | Do not promise speed-ups to your team |
How do I poll with it?
The Sume Runs and results page names the small poll payload behind status_url: it holds status, next_action, cancelable, expires_at, queue and timestamps, and it never holds the output or artifacts. That makes it the right thing to fetch twenty times; the full receipt at GET /v1/format-runs/{run_id} is heavier and only needed once a run ends.
Keep a sheet column of run ids and states. Collect the rows still non-terminal, build one request per row using the status_url Sume returned at submit time, call fetchAll, then write states back by index. Do not poll terminal rows again.
Read the run status field rather than inferring it from the HTTP code. The runs page says result_url returns 409 run_not_completed until a run is terminal, which is why you poll the status first and fetch the result only when it says the run ended.
function pollRuns(ids) {
const key = PropertiesService.getScriptProperties().getProperty("SUME_API_KEY");
const reqs = ids.map(id => ({
url: "https://api.sume.com/v1/format-runs/" + id,
headers: { Authorization: "Bearer " + key },
muteHttpExceptions: true
}));
return UrlFetchApp.fetchAll(reqs).map((r, i) => ({
id: ids[i],
code: r.getResponseCode(),
body: r.getResponseCode() === 200 ? JSON.parse(r.getContentText()) : null
}));
}What about rate limits on the Sume side?
Twenty status reads in one call are twenty requests to Sume. Errors and rate limits separates 429 rate_limited from 429 queue_full; the first is about request volume, so if any response in the array is a 429, honor its retry-after header and leave that row for the next trigger. Do not loop immediately.
For bulk batches, one queue read replaces many run reads. Poll GET /v1/format-run-queues/{id} and check counts.failed when the queue shows completed; that is a single request per batch.
Treat the order of the returned array as the only link between a response and its run. If you filter rows before building the request list, keep the filtered ids in a parallel array, as the sample does, and never rely on the sheet row number staying the same while the script runs. Another execution may sort or insert rows.
When should I skip polling entirely?
Send communication.webhook_url on each run, or on each bulk item, and let Sume call a web app. Run webhooks fire once per run when it reaches a terminal state. That moves the work from a timer to an event, and the sheet stops spending quota on checks that return "still running".
The Run webhooks page documents the envelope and retry schedule. A web app deployed from Apps Script can receive it, but remember that doPost cannot read request headers, so the signature check needs a different receiver; the linked post on that limit explains the options.
Sources
Related posts
More in Integrations
- Apps Script LockService tryLock stops a double Sume run
Wrap the Sume submit in an Apps Script lock so two triggers or edits cannot start the same paid run, then add an idempotency key so a retry is safe.
- Azure Logic Apps HTTP action times out at 120 s: long Sume runs
Logic Apps HTTP actions time out at 120 s. Start a Sume Format run (202 receipt), pass a webhook URL, and set an idempotency key so retries stay safe.
- Bitbucket merged-PR webhook to a Sume Format run: verify first
Verify Bitbucket's X-Hub-Signature (sha256=) with its published test values, then start a Sume Format run on pullrequest merged with a key built from the PR.
- Buildkite webhook: X-Buildkite-Token or Signature before a Sume run
Buildkite pipeline webhooks offer a clear-text token or an HMAC-SHA256 signature. Use the signature on build.finished before you start a paid Sume Format run.
Written by Sume