Log usage.cost for every Sume video job in Python and total a batch
A finished Sume video job returns usage.cost in USD. Log it with the job id and model, and sum it for a batch. Here is a short Python script that does it.

GET /v1/videos/{id} on a completed job returns usage.cost, where cost is the USD amount billed. Read it once the job is completed, write a line with the job id, model and cost, and add the costs to get a batch total.
The reserve at submit is not the final amount, so use usage.cost for your records and treat the reserve only as the amount that must be free in the wallet.
Where the number comes from
Sume bills provider list x 1.25, rounded up to the cent. The completed job reports the result in usage.cost. The response for a completed job also carries unsigned_urls for the file and the model that ran.
A failed or cancelled job has no file. Check status before you read the cost, and log failures with their error text so you can see why.
| Field | Where | Why log it |
|---|---|---|
| id | submit and poll | join your records to Sume's job history |
| model | poll | know which price table applied |
| status | poll | separate completed from failed |
| usage.cost | poll, completed only | the billed USD amount |
| error | poll, failed only | the public failure reason |
The script
It takes job ids on the command line, reads each job once and appends a CSV line. Run it after a batch finishes. For jobs still running, it prints their status and skips the cost.
import csv, json, os, sys, urllib.request
KEY = os.environ["SUME_API_KEY"]
def get(job_id):
req = urllib.request.Request(
"https://api.sume.com/v1/videos/" + job_id,
headers={"Authorization": "Bearer " + KEY})
with urllib.request.urlopen(req, timeout=30) as r:
return json.load(r)
total = 0.0
with open("video-costs.csv", "a", newline="") as f:
w = csv.writer(f)
for job_id in sys.argv[1:]:
j = get(job_id)
cost = (j.get("usage") or {}).get("cost")
if j["status"] == "completed" and cost is not None:
total += cost
w.writerow([j["id"], j.get("model"), j["status"], cost, j.get("error")])
print("batch total USD:", round(total, 2))Checking the total
Check one job by hand first. A 5-second Omni clip at 720p is 5 x $0.125 = $0.625, which rounds up to $0.63, so the log should show 0.63 for it. If your number differs, check the resolution and the duration the job actually ran.
Because each job is rounded up to the cent on its own, a batch total is the sum of rounded amounts, not a rounded sum. Ten jobs at $0.625 cost $6.30, not $6.25.
Habits that help
Keep the CSV, since it gives you a record that does not depend on a dashboard. Compare it to your balance change after a batch to catch a mismatch early.
- Write one line per job, even for failures.
- Never sum a job that is not
completed. - Store the
Idempotency-Keywith the job id. - Use a lower resolution for tests to keep the batch cheap.
Related posts
More in Developers
- Log usage.cost from the Sume images response to CSV in Python
POST /v1/images returns usage.cost as the billed USD amount. A Python logger that writes model, image count and cost per image to a CSV for budget reviews.
- Longest AI video Sume can render: 1800 s from 60 clips
One Timeline render caps at 1800 seconds. With 30-second clips that is 60 clips, with 200 slots allowed. The math and the render price follow.
- Lyria 3.5 prompts for video BGM: section tags and timestamps
Use [Verse]/[Chorus]/[Bridge] tags and [0:00-0:10] timestamps in a Lyria 3.5 prompt to pin an arc to a video. A worked prompt and a Sume call are below.
- macOS launchd: one AI video a day with a per-date Idempotency-Key
A launchd agent that wakes late can run twice. A per-date Idempotency-Key and an existing-file check keep a daily 3 s Gemini Omni clip ($0.1125) to one charge.
Written by Sume