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.

5 min readSume
All posts

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.

What the reference says about fetchAll (read 2026-10-10)
TopicReference saysConsequence for polling
Return valueHTTPResponse[]Match responses to runs by index
ErrorsmuteHttpExceptions returns the response instead of throwingSet it so one 429 does not hide 19 results
URL length2,082 characters maximumStatus URLs are short; keep ids, not payloads, in them
Timeout360 seconds by defaultLonger than any status read needs
ParallelismNot statedDo 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

All Integrations posts

Written by Sume