Sume /v1/usage limit: it caps rows, not the summary total
On GET /v1/usage, limit (1 to 100) only caps the rows listed. With thread_id, run_id or job_id the summary folds every row, up to 5,000.

On GET /v1/usage, limit is the number of newest rows returned, from 1 to 100, and nothing more. When you pass thread_id, run_id or job_id, the response also carries a summary that is folded over every ledger row of that scope, not only the rows listed. The one cap on the summary is 5,000 rows: past that, summary.truncated is true and the figures cover only the newest rows.
This comes from the Usage docs and the live OpenAPI schema for /v1/usage.
Does a small limit shrink the cost total?
No. The OpenAPI description for limit says that with a scope filter the summary always folds every row of the scope. So limit=1 is enough to read the cost of a whole run, and it keeps the response small.
Never add up the listed rows yourself: the docs warn that a refunded row keeps its hold amount in billable_amount_usd_micros.
import os
import requests
r = requests.get(
"https://api.sume.com/v1/usage",
params={"thread_id": os.environ["SUME_THREAD_ID"], "limit": 1},
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
s = r.json()["data"]["summary"]
if s["truncated"]:
raise SystemExit("summary covers only the newest 5000 rows")
print(s["debited_usd"], "final" if s["final"] else "still open")Which summary fields tell me whether the number is final?
A cost read taken while jobs are still running can move. These fields tell you whether it can, and whether it is complete.
| Field | What it means |
|---|---|
debited_usd_micros | Sum of captured rows: what the wallet deducted. The source-of-truth figure. |
held_usd_micros | Reserved rows, parked pending_* rows included. Not spend yet. |
refunded_usd_micros | Holds given back. Not spend. |
final | true once no hold is open, so debited will not move. |
truncated | true when the scope has more rows than the fold takes (5,000). |
When is summary missing?
The schema says summary is present only when thread_id, run_id or job_id was given, and null on the plain newest-rows list. The only documented query parameters are limit and those three ids; the docs I read show no cursor, so rows beyond the newest 100 are not reachable through limit.
What should I do with this?
Three habits make the summary safe to rely on.
- Read a run's cost with
run_idandlimit=1. - Check
finalbefore you bill someone fromdebited_usd. - Check
truncatedon very large threads, and do not trust the total when it istrue.
Sources
Related posts
More in Developers
- Sume webhook signature fails: compare the secret fingerprint
When a sume-v1 signature does not verify, one header tells you if the wrong secret signed it. A 24-line Node check reads the fingerprint and names the cause.
- Sume webhook never arrived: a sweeper that settles pending jobs
Run a small timer job that reads status for jobs still pending after ten minutes and settles them with the same guarded update your webhook route uses.
- Synthesia Voices page previews your script: test voices with Sume TTS
Synthesia's Voices page plays stock voices with your own script. In Sume, test a voice with the TTS endpoint at $0.0475 per 1,000 characters.
- Tavus stock voices in 16 languages vs Sume TTS language mismatch 409
Tavus auto-localized 16 new stock voices (Sep 9, 2026). In Sume, a voice and text language mismatch returns 409 unless you confirm. How to avoid wasted renders.
Written by Sume