Ten sub-cent usage rows: why cents fields never match debited_usd
Sume prints three roundings for the same money: credit_amount rounds up, billable_amount_usd_cents rounds half-up, debited_usd rounds once. Sum micros instead.

Ten usage rows of $0.004 each give three different answers in cents, because Sume rounds the same money three ways: each row's credit_amount rounds up (1 cent per row, 10 in total), each row's billable_amount_usd_cents rounds half-up (0 cents per row, 0 in total), and the summary's debited_usd sums micros and rounds once (4 cents). Only the last is right; the exact figure is the sum of billable_amount_usd_micros, 40,000 micros.
The three rules are in the API's usage code, and the Usage page (read 2026-10-11) says compatibility fields can show rounded cent values as credits. The $0.004 rows are a hypothetical used to make the rounding visible, not a quoted price.
The three roundings side by side
Every ledger row stores an integer number of USD micros, where one cent is 10,000 micros and one dollar is 1,000,000. Cents exist only at the edge, and the edge has three different conventions that grew at different times.
For ten hypothetical rows of 4,000 micros each, the arithmetic is below. Per row, 4,000 / 10,000 is 0.4 cents. Ceiling turns 0.4 into 1; half-up turns it into 0; summing first gives 40,000 micros, which is 4.0 cents.
| Field | Rule | Per row | Sum of 10 rows |
|---|---|---|---|
| credit_amount | Legacy per-row ceiling | 1 cent | 10 cents |
| billable_amount_usd_cents | Per-row half-up | 0 cents | 0 cents |
| billable_amount_usd_micros | Exact integer | 4,000 | 40,000 micros |
| summary.debited_usd | Sum micros, round half-up once | n/a | $0.04 |
Which one should a budget use?
Use micros. The summary's debited_usd_micros is documented as the amount the wallet deducted, and debited_usd is that figure turned into dollars with the only rounding in the response. If you need a row-level number, use billable_amount_usd_micros and divide by 1,000,000 yourself, at the end.
Do not add up credit_amount over many small rows. It is kept for compatibility and the API schema labels it a legacy rounded cent amount, so sub-cent rows are overstated (2.5 times in the 4,000-micro example above). The reverse trap exists too: summing billable_amount_usd_cents over sub-cent rows can read as zero. The related post on the credits field being rounded cents covers the balance side.
Where cents mismatches usually come from
A cost chart in your own app that sums credit_amount will drift above the Billing page whenever your volume is made of cheap rows: speech clips, short captions, thumbnails. A chart that sums billable_amount_usd_cents will drift below. Both are rounding, not a billing error, and neither means a job was charged twice.
When you reconcile, pick a window, sum billable_amount_usd_micros over captured rows only, and compare after one rounding. Reserved rows are holds and refunded rows are given back, so counting them double-counts. If your list is long, remember that limit caps only the rows listed, per usage limit caps rows, not the summary.
A reconciliation that cannot drift
This sums micros over the captured rows returned and prints dollars with one rounding. Scope it with a thread_id, run_id or job_id when you can, because then the summary does the same fold for you.
import os
import requests
def main():
r = requests.get(
"https://api.sume.com/v1/usage",
params={"limit": 100},
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
rows = r.json()["data"]["usage"]
micros = sum(x["billable_amount_usd_micros"] for x in rows
if x["status"] == "captured")
cents = (micros + 5_000) // 10_000
print(f"{len(rows)} rows, captured {micros} micros = ${cents / 100:.2f}")
main()
Sources
Related posts
More in Pricing
- How Sume pricing works: plans, one wallet, published model rates
Sume plans set access and concurrency. Usage draws from one prepaid wallet at each model's published USD rate, for generation, the Agent, Formats, and the API.
- AI avatar video API pricing: cost per second and per minute
Sume bills AI avatar video per second by quality tier, with separate rates when you send a product image. Per-minute costs for standard, plus, and max.
- AI video generation cost per video: what one Sume API run cost
To see what one Sume run or video job cost, call GET /v1/usage with run_id or job_id and read debited_usd: the wallet deduction, agent turns included.
- Do failed AI video generations cost credits? Reserve, capture, refund
No. Sume reserves a job's estimated USD cost at submit, captures usage only on completion, and releases or refunds the hold if the job fails or is canceled.
Written by Sume