Reconcile a mixed project with GET /v1/usage: debited, held, refunded

How to read what one job or run really cost: debited, held and refunded fields, with the arithmetic for a project where one of six shots fails and is refunded.

5 min readSume
All posts

To see what a mixed project cost, read GET /v1/usage with a job_id, run_id or thread_id, and quote summary.debited_usd. That field is what the wallet actually deducted. held_usd_micros is money still reserved and not yet spent, and refunded_usd_micros is money given back after a failure, a cancel or queue_full. Do not add up the ledger rows yourself; the docs say never to.

The three numbers

The usage summary folds over every ledger row the scope caused. Debited is the captured rows. Held covers reservations that are still open. Refunded is a reservation that Sume released. A refunded row keeps its hold amount in billable_amount_usd_micros, which is why summing raw rows overstates the cost. final: true means no hold is open, so the numbers will not move again.

A worked example

Take six 5-second wan-3.0 shots at 720p: $0.6250 each, $3.7500 reserved if all are accepted. Suppose shot 5 fails at the provider. The expected figures are below; they are arithmetic from list prices (catalog read 2026-10-08), not a recorded response.

Expected usage summary for the six-shot step, shot 5 failed, as of 2026-10-08
MomentHeldDebitedRefundedFinal
All six submitted$3.7500$0.0000$0.0000false
Shots 1-4 and 6 captured, shot 5 failed$0.0000$3.1250$0.6250true
Shot 5 resubmitted and captured$0.0000$3.7500$0.6250true

Where to read it

Each shot is a job, so read the usage of the whole project by thread_id or run_id when one exists. For direct API calls, query each job_id and add the debited_usd values on your side. In the example the video step costs $3.1250 after the failure, and $3.7500 after the retry, while the $0.6250 refund is never spend.

For a project built from several runs, keep one table: step, job id, estimate, debited. After the last step, the sum of debited should match the drop in GET /v1/balance over the same window, apart from other work on the workspace. If the two differ, look for open holds (held_usd_micros) before you suspect a billing error.

A cap compares against reserved plus captured generation rows, which is a different total from debited. In a run receipt, usage.cap splits that into limit, counted and remaining. Use debited for cost reports and the cap fields for headroom.

Common reading mistakes

Three mistakes recur. First, quoting a receipt's billable amount as the cost: for a run it counts reserved and captured generation, and it excludes the agent's own LLM turn, so it is a cap measure and not an invoice. Second, summing raw rows, which counts a refunded hold as spend. Third, reading while a hold is open: if final is false, wait and read again.

The balance and the ledger are the billing records. Keep job ids for each step of the project so a single job_id read can answer the question 'what did shot 5 cost' without scanning the ledger.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume