An AI series render ledger: job id, key, plan minutes, warnings
TikTok is testing spam detection on AI-content accounts. Keep a CSV of every Sume render: job id, idempotency key, plan minutes, status, file and warnings.

Why a ledger, and what it is not
The October platform roundup reports that TikTok is testing improved detection for accounts dedicated to AI-generated spam, with attention on political, financial and medical content. If you run a branded series that is made with AI, you want to be able to say, for any episode, what was generated, when, and from which request. A ledger of your own render jobs answers that. It is a record you keep, not a credential TikTok accepts or a defense against any review, and we do not claim it changes how a platform treats an account.
What Sume gives you for this is thin and useful: every job has an id, every write can carry an Idempotency-Key you choose, the plan returns billable_minutes before you pay, and a finished job returns a result with its warnings. The ledger stitches those together in a CSV you control.
What to record and where each field comes from
Each column maps to a documented field. Nothing in it is invented by the script.
| Column | Source | Why you want it |
|---|---|---|
| episode | Your own numbering | Join key for publishing |
| idempotency key | The header you sent | Replays the same job, never a duplicate |
| job id | request_id in the submit response | Look the job up again at any time |
| billable minutes | timeline plan response | The cost you expected before rendering |
| status | sume_status on GET /v1/jobs/:id/status | completed, failed or canceled |
| video url | video_url in the job result | The finished file on media.sume.com |
| warnings | warnings[] in the job result | Padded, looped, resampled or clamped |
The script
submit plans first, then renders with a stable key built from season, episode and a version suffix, and returns the first four columns. settle reads the status and, when a result is ready, the file and warnings. write dumps rows to a CSV. Call submit per episode and settle later, since a render is a job and not a response.
import csv, json, os, urllib.request
def api(method, path, body=None, key=None):
h = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json", "User-Agent": "sume-example/1.0"}
if key:
h["Idempotency-Key"] = key
data = json.dumps(body).encode() if body else None
with urllib.request.urlopen(urllib.request.Request(
"https://api.sume.com" + path, data, h, method=method)) as r:
return json.load(r)
def submit(ep, body):
key = f"s1-ep{ep:02d}-v1"
plan = api("POST", "/v1/timeline-1.0/plan", body)
job = api("POST", "/v1/timeline-1.0/render", body, key)
return [ep, key, job["request_id"], plan["billable_minutes"]]
def settle(row):
st = api("GET", f"/v1/jobs/{row[2]}/status")
out = {}
if st.get("result_ready"):
res = api("GET", f"/v1/jobs/{row[2]}/result")
out = res.get("result", res)
return row + [st.get("sume_status"), out.get("video_url", ""),
json.dumps(out.get("warnings", []))]
def write(rows, path="ledger.csv"):
with open(path, "w", newline="") as f:
csv.writer(f).writerows(rows)Keys and versions
Build keys from facts you control: season, episode, and a version you bump when you change the body on purpose. The point of the key is that a retry after a timeout reuses the same request instead of starting a second one; check the idempotency docs for the exact replay and conflict behavior before you rely on it. When you intentionally re-render episode 7 with a new mix, bump the version to v2 and the ledger keeps both rows, with the old file untouched.
Do not put secrets or personal data in keys or in the ledger. Keep it to ids, numbers, URLs and codes.
What the ledger does not do: it does not prove how a clip was made beyond the Sume request, it does not replace the disclosure or labeling controls a platform gives you in its own upload flow, and it does not decide whether a series is spam. The platforms decide that on their own signals. Treat the ledger as an internal control with two jobs: reconcile cost against your invoice, and let a person answer 'which request produced this file' in under a minute.
A practical extra column is the publish URL on each platform, filled in after upload. With that one column you can walk from a live Short back to the exact job id, key and body version, and from there to the plan you approved. Keep the Timeline body itself in version control next to the CSV, named by the same key, so the record is complete: the inputs, the request and the result.
If you run more than one series, give each its own key prefix and its own CSV. Mixing them makes reconciliation harder, and a prefix is free.
Using it
Run settle on every row before you publish an episode and refuse to publish rows whose status is not completed. Read the warnings column too, because a padded or looped short source is not a failure and will not stop the job; it will only show up here. If a platform later asks how an episode was made, you have a dated record of the request and the file. If it asks nothing, you have a cost log that matches your invoice line for line. Confirm live rates in GET /v1/catalog, and keep the documented price per whole output minute in mind when you add a cost column.
This is a small habit, and the whole script is under 30 lines. It is the cheapest piece of governance a generated series can have.
Sources
Related posts
More in Use cases
- Baby shower invitation art with an API: watercolor, details in code
Make a soft watercolor invitation border on Sume with an empty center, then add the date, place and host in code so every detail is exact and easy to update.
- Black Friday reminder series on Sume: three clips for $8.73
Three 15 second avatar reminders for Nov 20, Thanksgiving eve and Black Friday cost $8.73 at standard with a product image. Script plan, tiers and the math.
- Coffee shop loyalty card art with an API: stamps drawn in code
Generate 3:2 loyalty card art on Sume with empty stamp spaces, then draw each customer's stamps in code so the count is always right and the art is reused.
- Criteo Retail Media onsite video: 720p, 15 s, a Sume avatar clip
Criteo onsite video asks for MP4 at 720p, 15 s recommended and 30 s max, in 16:9, 1:1 or 9:16. Sume avatar output is 720p, so script to 15 seconds.
Written by Sume