What did one script_run cost? Sume script_runs and its children
Sume /v1/usage lists script_runs with rows and money per call, and counts script_run_children in includes. Read the cost of one script_run to the cent.

To see what one script_run cost, call GET /v1/usage for the thread or run that contains it and read summary.script_runs: each entry gives a script_run_id, the number of rows, and its debited, held and refunded micros. The jobs that the script dispatched are counted in includes.script_run_children.
This matters most in a launch week, when a script fans out many cheap generations in one go and the wallet only shows one line per job.
What the summary gives you per call
The OpenAPI schema (read 2026-10-11) describes script_runs as the script_run calls inside the scope, by their stamp, newest money first, and empty when there are none. Each entry has five required fields.
The usage docs add that rows carry script_run_id and script_run_call_index when a script_run dispatched the job, so you can group or order the rows yourself when you need the per-job lines.
| Field | Meaning |
|---|---|
| script_run_id | The stamp that identifies the call |
| rows | Number of ledger rows the call caused |
| debited_usd_micros | Money the wallet deducted for the call |
| held_usd_micros | Holds still open for the call |
| refunded_usd_micros | Holds returned after a failure, cancellation or queue_full |
The children count and the other row kinds
The includes object counts rows by kind: LLM turns, sidecars, Browser sessions, generation jobs, other, refunded rows, and script_run_children. The last one is the number of jobs that a script_run call dispatched. It is a count of rows, not a money figure, so pair it with the script_runs entries for the money.
The refunded rows count and the refunded micros in the same summary tell you how much of the call came back, so read them together with the children count.
Why a script_run needs its own number
A script that loops over a list of prompts can submit many jobs under one call. Without the stamp you would have to guess which rows belong together. The stamp lets a finance report answer a plain question: what did that script cost, including everything it started?
It also keeps run caps honest. The cap object on a run scope shows the limit, the counted amount and the remaining amount. It counts reserved plus captured generation rows without LLM, so it is never a total cost. For total cost, use debited, and for the cap behaviour see the post on capping spend from an agent loop.
What a call looks like in a report
A useful report line has four values: the call stamp, the debited dollars, the held dollars and the refunded dollars. Convert micros to dollars by dividing by one million, and round once at the end. Add the number of children from the includes object so a reader can see the cost per dispatched job as a derived figure, clearly labelled.
Because the entries come newest money first, the first line is the most expensive call in the scope. That is the one to open when a bill looks high.
A reading routine
First, request the scope with the thread or run id and a small limit; the limit only caps listed rows, not the summary. Second, check final. Third, find the entry in script_runs for the call. Fourth, compare its debited and held with the per-job rows if you need detail.
Do not sum rows by hand to get the call's cost. The docs say never to, because a refunded row keeps its hold amount in billable_amount_usd_micros. Use the entry's own figures. If your scope is large, check the truncated flag, which the 5000-row note explains.
Sources
Related posts
More in Developers
- Sonic 3.6 vs Eleven v4 Turbo: one script, one Python A/B run on Sume
Send the same text to sonic-3.6 and eleven-v4-turbo through the TTS Router with one Python script, poll both jobs, and compare the files by ear.
- Sume 400 invalid_request: read details.errors[].path to find the field
A Sume 400 invalid_request lists each bad field in details.errors with path, loc, message and type. Read them in Python instead of guessing from the message.
- A Sume 400 that returns a job id: input rejected at provider submit
Most Sume 400s create nothing, but a provider input rejected at submit leaves a failed job, a request_id and a refund. How to read it and what key to use.
- Sume 404 resource_not_found: job_not_found and model_not_found overlap
Every Sume 404 reports public_reason resource_not_found, whatever the code. Branch on error.code to tell a missing job from a bad model id or a missing asset.
Written by Sume