Cap Sume spend from an agent loop: dry_run, max_spend_usd and run caps
Four optional guards cap what an automated Sume caller can spend: dry_run, max_spend_usd, generation_spend_cap_usd on Formats, and a balance check.

There are four guards, and each belongs to a different surface: dry_run and max_spend_usd on hosted MCP tools, generation_spend_cap_usd on Format runs, and GET /v1/balance before a REST batch. Sume enforces max_spend_usd only when you send it, so an agent loop that you want capped has to pass it on every paid call.
The guards side by side
None of these is automatic on every call. The wallet balance is the only hard limit that is always on, because a submit fails with 402 insufficient_credits when the wallet cannot fund it. Everything else is a limit you choose to set.
| Guard | Where | What it does | Default |
|---|---|---|---|
dry_run | Hosted MCP paid tools | Previews the cost without submitting | Off |
max_spend_usd | Hosted MCP paid tools | Caps one call | Not enforced unless sent |
generation_admission_preview | Hosted MCP | Shows estimate, balance and queue behavior | Optional |
generation_spend_cap_usd | Format run create | Caps generation spend for one run, up to 500 | The Format's default, $400 |
GET /v1/balance | REST | Reads the USD balance before you start | Your call |
Format run caps
On a Format run, generation_spend_cap_usd limits how much the run can spend on generation. The value must be above 0 and at most 500: 0 or a number above 500 returns 400 invalid_request. A Format has its own default of $400, and a null cap on the request means the $500 ceiling, so passing null raises the limit instead of removing it.
Choose the cap from the job. A run that makes one image does not need a $400 ceiling, and a small cap turns a runaway agent step into a failed run with a clear receipt, which is cheaper than a surprise bill. The cap is per run, so a bulk run of many items needs a number that makes sense for each item, and the Format's own default is the ceiling you fall back to when you send nothing.
Remember that the cap and the balance are separate checks. A run can be well under its cap and still fail with 402 insufficient_credits, because the wallet is what pays. Read the balance first for any large batch, and treat the cap as a limit on how wrong a single run can go.
An MCP call with the guards on
Every write and paid MCP tool requires an idempotency_key, and the three optional arguments sit beside it. A first call with dry_run: true returns the estimate. If the estimate is acceptable, the same call without dry_run and with the same key submits for real, and max_spend_usd keeps it under the number you chose.
{
"idempotency_key": "order-4821-hero-image-v1",
"dry_run": true,
"max_spend_usd": 2
}Where agent loops overspend
The expensive pattern is a loop that retries a paid create with a fresh key, because each fresh key is a new job. Generate the key once per intended render and store it. The second is a fan-out that sizes itself from nothing: read the generation_limits object on a submit response, whose wave_size_hint is a hint for the next wave, not a guarantee, and stop when 402 arrives.
A third is polling a job that was already canceled. Cancel works only before generation starts. After that the API returns 409 job_generation_already_started, and the job runs to the end and bills, so a cancel in a loop is a way to find out the money is already spent.
A short checklist
Before an agent gets a paid tool, give it a key with only the scopes it needs, set max_spend_usd in the tool arguments it generates, make it call dry_run first on anything new, and put a total budget in your own code that you decrement from each completed job. Sume's guards cap one call or one run, and only your code can cap a whole session.
Keep that session budget visible. Start with the balance you read from GET /v1/balance, subtract the estimate of each accepted job, and stop the loop when the remainder drops under the price of the next step. A loop that can see its own budget stops politely, while a loop that learns about the budget from a 402 stops in the middle of a batch.
Sources
Related posts
More in Developers
- Captions out of sync with the audio: check STT word times and offsets
Captions running early or late usually trace to an unapplied offset. How Sume STT word times work, which offset to add, and a Python merge that applies it.
- Connect a new MCP client to Sume: five calls that prove it works
After you add https://mcp.sume.com/mcp to a new client, run mcp_health, tools_list, tools_schema, account_me and catalog_list. What each result should show.
- Convert an SRT file to Sume caption cues in Python
Sume captions take no SRT upload, but cues carry the same start, end and text. A 26-line Python script turns an SRT into cues and posts them for $0.20.
- Cost per ad variant: build a ledger from usage.cost on Sume
Every completed /v1/videos poll carries usage.cost. Sum it by hook and ending to get the cost per ad variant before media spend. Node script and the caveats.
Written by Sume