Cost per row of a Sume bulk run: add up debited_usd_micros
Read usage.debited_usd_micros on each child receipt, wait for final to be true, and treat null as unknown. Why billable_amount alone understates a bulk run.

To get the cost per row of a Sume bulk run, fetch each child's receipt and read usage.debited_usd_micros, divided by 1,000,000 for dollars. That field is what the wallet actually deducted for the run, including the agent's own language-model turn. The tempting field, usage.billable_amount_usd_micros, is only the generation spend counted against the run's cap and leaves that turn out, so adding it up understates the bill.
Two more rules keep the sheet honest: read a receipt's spend only once usage.final is true, and treat usage: null as unknown, never as zero.
Which usage field answers which question?
Agent tools are starting to bill in one pool. Comfy's Agent page says its charges come from the same Comfy Credits pool as generations, so a planning turn and a render land in one number. Sume separates them on the receipt, which lets you ask both questions.
| Field | Meaning | Use it for |
|---|---|---|
| billable_amount_usd_micros | Generation spend counted against the cap; excludes the agent's LLM turn | Checking how close a run came to its cap |
| generation_spend_cap_usd_micros | The cap that applied to this run | Spotting runs stopped by the cap |
| debited_usd_micros | What the wallet deducted for the run and its thread, LLM row included | The cost of the row |
| held_usd_micros | Holds still open; not spend yet | Detecting runs that are still settling |
| refunded_usd_micros | Holds given back; not spend | Reconciling against the ledger |
| final | True once no hold is open | Deciding whether the number can still change |
What does the script look like?
It walks the queue's items, skips the ones that never started, and totals only receipts whose spend is final.
import os, requests
B = "https://api.sume.com/v1"
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
def get(path):
r = requests.get(B + path, headers=H, timeout=30)
r.raise_for_status()
return r.json()["data"]
def queue_costs(queue_id):
rows, total, pending = [], 0, []
for item in get(f"/format-run-queues/{queue_id}")["items"]:
if not item["run_id"]:
rows.append((item["index"], "never started"))
continue
u = get(f"/format-runs/{item['run_id']}").get("usage")
if not u or not u.get("final"):
pending.append(item["index"])
continue
total += u["debited_usd_micros"]
rows.append((item["index"], u["debited_usd_micros"] / 1e6))
return rows, total / 1e6, pendingWhy wait for final?
While a run is in flight, billable_amount_usd_micros climbs, and holds are open that are not spend yet. A run can look expensive at the moment it terminates and cheaper once a hold is refunded. The script puts unsettled rows in pending and leaves them out of the total, so run it again later and the sum only ever contains settled numbers.
What belongs in the cost sheet?
The same fold sits behind GET /v1/usage?run_id=, so the receipt and the ledger agree.
- Failed rows. A run that wanted to spend past its cap lands as failed, and generation it completed before failing is still billed.
- Canceled rows. Cancel is idempotent and the receipt reports what was spent before it stopped.
- Continuations. A run with
previous_run_idhas its ownusage, butdebited_usd_microscovers the run and its thread, so do not add a continuation and its parent without checking for overlap against the ledger. - Rows with
usage: null. Spend could not be read, which is not the same as 0; mark them unknown and re-read.
How do I turn this into a price per video?
Divide the settled total by the number of rows that produced a deliverable, not by the number you submitted, and report the failed-row spend separately. Prices come from Sume's public API pricing page and your own receipts; this post gives no per-second rates on purpose, since they change by model. Set a per-item cap from the first pilot batch, then compare each later batch's per-row cost with it.
Sources
Related posts
More in Pricing
- Cost to remove backgrounds and upscale 500 product photos by API
Sume bills background removal at $0.0225 an image and upscale at $0.20, both flat. 500 photos through both steps cost $111.25; the table and a submit loop.
- Does AI video API billing round up? Sume's ceil rules per endpoint
A 5.2 s clip is billed as 6 s. Which Sume endpoints round seconds or minutes up, which prorate, and worked examples from the published rates.
- H3 Max Recast 768p or 1080p: draft cheap, publish in HD
Sume bills H3 Max Recast at $0.375 a second at 768p and $0.5625 at 1080p. Budget a 768p test pass and one 1080p final, and what each plan costs.
- H3 Max Recast 768p vs 1080p: price per second and per clip
fal lists H3 Max Recast at $0.30 a second for 768p and $0.45 for 1080p. On Sume the same two tiers cost $0.375 and $0.5625 a second; per-clip math for 5-30 s.
Written by Sume