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.

4 min readSume
All posts

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.

Fields to log per job, read 2026-10-05
FieldWhereWhy log it
idsubmit and polljoin your records to Sume's job history
modelpollknow which price table applied
statuspollseparate completed from failed
usage.costpoll, completed onlythe billed USD amount
errorpoll, failed onlythe 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-Key with the job id.
  • Use a lower resolution for tests to keep the batch cheap.

Related posts

More in Developers

All Developers posts

Written by Sume