n8n Google Sheets AI avatar video: one Sume video per row

Read rows with n8n's Google Sheets node, submit one Sume talking-avatar job per row, poll in a capped loop, and write each video URL to the sheet.

5 min readSume
All posts

To make one AI avatar video per Google Sheets row in n8n, read the rows with the Google Sheets node and send each row's avatar_handle and script to POST /v1/avatar-1.0/talking-video from an HTTP Request node. Write the returned job id back to the row, poll GET /v1/jobs/{id}/status in a loop with a fixed cap, and write the finished video URL into the sheet.

Sume has no n8n node, so each row is a plain HTTPS job request; the request body itself is covered in Talking avatar video API. Sume facts come from Generate avatar video, Jobs and results, and Generation admission; n8n behavior comes from n8n's docs, read 2026-09-27.

How should I lay out the sheet?

One row per video, under a header row: n8n treats the first row as headings and skips it when reading all rows.

From Sume's Generate avatar video and Jobs and results and n8n's sheet operations docs, read 2026-09-27.
ColumnHoldsRule
row_idYour own stable idGoes into the Idempotency-Key.
avatar_handleA ready avatarA script request names it at the top level.
scriptWhat the avatar saysSume must estimate it at 4-60 seconds. Split longer scripts into more rows.
statusready, submitted, done, failed, or check_laterYour own marker. Get Row(s) filters on it.
job_idWritten after the submitLets a restarted workflow resume polling instead of resubmitting.
video_urlWritten at the endThe media.sume.com URL from the result.

How do I submit one job per row?

Use Get Row(s) with a filter on status equal to ready, and set When Filter Has Multiple Matches to Return All Matches; by default n8n returns only the first matching row. n8n nodes run once per item, so the next HTTP Request node sends one POST per row, authenticated with a Bearer auth credential. The request below is what it sends for one row.

  • Idempotency-Key from the sheet, the row id, and a version. A retry that reuses the key gets the original job back instead of billing a second one.
  • mode can be left out: it defaults to async, which returns at once with polling URLs.
  • Any media column, such as product_image, must hold a fetchable public HTTPS URL.
  • Next, Update Row writes job_id and submitted to the row. Sume says to store the job id, and never to resubmit a paid request because a local process timed out.
curl -X POST https://api.sume.com/v1/avatar-1.0/talking-video \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: promo-sheet-row-42-v1" \
  -d '{
    "avatar_handle": "acme_host",
    "script": "Meet the Acme travel mug. It fits every cup holder.",
    "aspect_ratio": "9:16"
  }'

How many rows can I send at once?

Sume admits paid jobs queue-first: your workspace runs a set number of jobs at once and holds more as queued, and a submit past both limits fails with 429 queue_full. Video job concurrency and queueing lists the plan defaults; your live values are on the dashboard's Concurrency tab and in generation_limits on each submit response.

  • Size a batch from Sume's budget for new in-flight work: concurrency_limit minus active and queued jobs, capped by queue_capacity_remaining.
  • Set that size in the HTTP Request node's Batching option: Items per Batch, plus a Batch Interval in milliseconds. The interval is a fixed wait between batches, not a wait for jobs to finish.
  • Turn on Never Error and Include Response Headers and Status, and let an If node pass only 2xx responses on to Update Row. A 429 row then stays ready instead of stopping the workflow; retry it later with the same Idempotency-Key.
  • Reads and writes have separate per-minute budgets, and reads get forty times the write number, so polling cannot 429 your submits.

How do I poll without an endless loop?

n8n makes a loop when you connect a node's output back to an earlier node, with an If node to stop it. After Update Row:

  • Wait, After Time Interval, for example 30 seconds. Honor next_poll_after_seconds from the last status response when it is present.
  • HTTP Request: GET https://api.sume.com/v1/jobs/{job_id}/status.
  • If terminal is true, leave the loop. Otherwise a second If node checks {{ $runIndex }}, n8n's zero-based count of the current node's runs, and loops back to Wait only while it is under your cap: 40 checks of 30 seconds is 20 minutes, which Sume calls a reasonable client-side deadline for video.
  • At the cap, write check_later. Your timeout does not cancel the job; it keeps running and still bills, and the stored job_id picks it back up.

What do I write back when a job ends?

When the status shows result_ready: true, GET /v1/jobs/{id}/result returns the result. Completed avatar-video results can include public media.sume.com video artifacts; write that URL to video_url and set done with Update Row, which only updates existing rows.

/result answers 409 job_not_completed for any job that did not complete, so for a failed or canceled job read the error from GET /v1/jobs/{id} and write it to the row as failed.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume