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.
- Test a Sume webhook receiver with node:test and signed fixtures
Three node:test cases that sign their own Sume webhook bodies: fresh, rotation header, and the three rejections. Runs with node --test.
- TikTok Content Posting API rate limits: 20, 6 and 30 per minute
TikTok limits creator info to 20 requests per minute, post init to 6, and status checks to 30, each per access token. Design your queue around the tightest one.
Written by Sume