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.

5 min readSume
All posts

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.

Receipt usage fields, read 2026-10-03
FieldMeaningUse it for
billable_amount_usd_microsGeneration spend counted against the cap; excludes the agent's LLM turnChecking how close a run came to its cap
generation_spend_cap_usd_microsThe cap that applied to this runSpotting runs stopped by the cap
debited_usd_microsWhat the wallet deducted for the run and its thread, LLM row includedThe cost of the row
held_usd_microsHolds still open; not spend yetDetecting runs that are still settling
refunded_usd_microsHolds given back; not spendReconciling against the ledger
finalTrue once no hold is openDeciding 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, pending

Why 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_id has its own usage, but debited_usd_micros covers 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

All Pricing posts

Written by Sume