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.

5 min readSume
All posts

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.

Spend guards by surface (read 2026-10-07)
GuardWhereWhat it doesDefault
dry_runHosted MCP paid toolsPreviews the cost without submittingOff
max_spend_usdHosted MCP paid toolsCaps one callNot enforced unless sent
generation_admission_previewHosted MCPShows estimate, balance and queue behaviorOptional
generation_spend_cap_usdFormat run createCaps generation spend for one run, up to 500The Format's default, $400
GET /v1/balanceRESTReads the USD balance before you startYour 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

All Developers posts

Written by Sume