Hold AI Shorts for human approval: poll the run, then publish

A Python poll loop for a Sume Format run that stops at a human yes or no before any upload, so a reviewer can reject sameness first.

5 min readSume
All posts

If Shorts are generated by a pipeline, the last step before upload should be a person. YouTube's October 2, 2026 statement says its recommendations will favor original content (9to5Google, read 2026-10-05), and a reviewer is the cheapest filter for sameness and for realistic scenes that need a disclosure label. This post shows the gate. It does not upload anything.

What the run receipt gives you

Sume's run docs, read on October 5, 2026, describe the lifecycle: queued, processing, then completed, failed, canceled or skipped. A completed receipt holds primary_output_url and artifacts. The receipt is read at GET /v1/format-runs/{run_id}, and the response wraps it in data.

Poll with a back-off. The docs advise doubling the gap up to one minute, and note that a non-terminal receipt carries an expires_at, after which Sume force-finalizes the run as failed.

The gate

Set SUME_API_BASE to the API host from your dashboard docs and SUME_API_KEY to a key with formats:read. Run the script with a run id.

import os, sys, time
import requests

BASE = os.environ["SUME_API_BASE"].rstrip("/")
KEY = os.environ["SUME_API_KEY"]
HEAD = {"Authorization": "Bearer " + KEY}

def wait(run_id):
    gap = 5
    while True:
        r = requests.get(f"{BASE}/v1/format-runs/{run_id}", headers=HEAD, timeout=30)
        r.raise_for_status()
        run = r.json()["data"]
        if run["status"] not in ("queued", "processing"):
            return run
        time.sleep(gap)
        gap = min(gap * 2, 60)

run = wait(sys.argv[1])
if run["status"] != "completed":
    sys.exit("run " + run["status"] + ": " + str(run.get("error")))
print("Review this file:", run["primary_output_url"])
answer = input("Original, no sameness, labels checked? [y/N] ")
verdict = "APPROVED" if answer.strip().lower() == "y" else "REJECTED"
rid = run.get("id", sys.argv[1])
print(verdict, rid)
with open("review-log.txt", "a") as log:
    log.write(verdict + " " + rid + "\n")

What the reviewer checks

Give the reviewer a short list, not a feeling.

  • Does the opening differ from the last three approved Shorts?
  • Is there a claim or point the viewer can state in one sentence?
  • Does any realistic scene show something that did not happen? If so, the disclosure label applies.
  • Is the length and structure different from yesterday's?

The log file doubles as an audit trail. If a Short is ever questioned, you have the run id and a dated human decision beside it. For a queue of many items, read each child at its own run id after the queue finishes, since the bulk docs say completed means every item is terminal, not that every item succeeded.

Why a gate beats a rule

Rules about originality are vague, and YouTube has not published a threshold. A person looking at the finished file catches what a rule cannot: two Shorts that open on the same shot, a joke that repeats, a product that looks slightly wrong. The gate costs a minute per Short and removes the worst failures.

If you run a daily batch, ask the reviewer to approve in a fixed window, say 15 minutes after the batch lands, and let anything not approved slip to tomorrow. A slow day is cheaper than a repetitive week.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume