What one script_run call cost: the usage script_runs array

Sume's usage summary lists each script_run call with its rows, debited, held and refunded micros, so a fan-out of TTS or image jobs has one price.

5 min readSume
All posts

To price one script_run call, query GET /v1/usage with the job_id of the turn that ran it and read summary.script_runs: each entry has a script_run_id, its row count, and its debited_usd_micros, held_usd_micros and refunded_usd_micros. The jobs the script dispatched also show up as includes.script_run_children in the same summary.

script_run is the hosted MCP tool that runs a short program which calls other tools in a loop or in parallel, per MCP tools and gates (read 2026-10-11). Fan-out is its point, which is why a single call can create many paid jobs and why a single price for it is useful.

What does the summary add for scripts?

Every child job a script creates carries two stamps on its ledger row: the script_run_id of the call and a 1-based script_run_call_index, the position of the sume.call inside the script. Rows tell you where they came from, so you never match jobs to calls by timestamp.

The summary folds those stamps into one array. Rows created before the stamps existed count as plain generation jobs, so an old thread can show zero script children while still having generation rows. The OpenAPI description says the same.

Script-related fields in the usage schema and tests (read 2026-10-11)
FieldWhereMeaning
script_run_idEach usage rowThe script_run call that dispatched the row's job
script_run_call_indexEach usage row1-based index of the sume.call inside that script
includes.script_run_childrenSummaryCount of rows a script dispatched; they are generation jobs too
script_runs[]SummaryPer call: rows, debited, held and refunded micros

Worked example from the API's own test

The API's usage-scope test builds one agent turn with an LLM row of 30,000 micros and two text-to-speech children dispatched by one script, 4,000 micros each. Reading that turn's job_id returns a debited_usd_micros of 38,000 (that is $0.038), includes.llm_turns of 1, generation_jobs of 2 and script_run_children of 2.

The script_runs entry for that call shows 2 rows and 8,000 micros debited, which is the answer to the question this post asks: the script cost $0.008, and the turn's model cost the other $0.030. Those numbers are a test fixture, not a price list; use them to check your parser, not to budget.

Refunds inside a script

A script can dispatch children that fail. A failed or canceled child's hold is released, so it lands in refunded_usd_micros for that script entry, and does not count as spend. The Usage page's status table says the same about any refunded row: it was released after a failure or a cancellation before capture.

That matters for the question "did the script spend what it reserved". Compare held_usd_micros and debited_usd_micros only after final is true. While final is false, a child may still be running and its hold is not yet spend or refund. The script's own max_paid_calls limit caps how many paid calls it may make.

A script to print the per-call prices

Pass the turn's job_id. The response includes the turn's own row and every job the turn commissioned, so the total and the per-script split come from one request.

import os
import requests


def main():
    r = requests.get(
        "https://api.sume.com/v1/usage",
        params={"job_id": os.environ["TURN_JOB_ID"], "limit": 50},
        headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
        timeout=30,
    )
    r.raise_for_status()
    s = r.json()["data"]["summary"]
    print("turn total micros:", s["debited_usd_micros"], "final:", s["final"])
    for call in s["script_runs"]:
        print(call["script_run_id"], call["rows"], "rows",
              call["debited_usd_micros"], "micros debited",
              call["refunded_usd_micros"], "refunded")


main()

Never sum the usage rows yourself: the Usage page tells you to use the summary, and limit only caps the rows listed, not the summary. The background on that is in usage limit caps rows, not the summary. For the tool itself, see programmatic tool calling with script_run.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume