A dry-run flag for Sume API calls: print the request, skip the spend

Add DRY_RUN to code that calls the Sume API: build the body, key and spend cap, print them, and send nothing. Review a batch before it costs money.

5 min readSume
All posts

A dry-run flag is the cheapest cost control you can write for a Sume integration: build every request exactly as you would send it, print the body, idempotency key and spend cap, and stop before the network call. A reviewer can then read a whole batch before anything is charged.

Why print the cap

The Sume best-practices page says to cap spend on every run with generation_spend_cap_usd and to treat a missing cap as a bug in the client. A dry run that prints the cap makes a missing one visible in review, not on the invoice.

import asyncio, json, os

DRY_RUN = os.environ.get("DRY_RUN", "1") != "0"

async def submit(client, path: str, body: dict, key: str) -> None:
    if "generation_spend_cap_usd" not in body:
        raise ValueError("every run needs generation_spend_cap_usd")
    if DRY_RUN:
        print(json.dumps({"path": path, "key": key, "body": body}, indent=2))
        return
    r = await client.post(path, json=body, headers={"Idempotency-Key": key})
    r.raise_for_status()

async def main() -> None:
    body = {"input": {"product_url": "https://shop.example.com/p/1"},
            "generation_spend_cap_usd": 3}
    await submit(None, "/v1/formats/acme/product-promo/runs", body, "order-1-v1")

asyncio.run(main())

Default to dry

Default the flag to on, and require an explicit DRY_RUN=0 for a real run, so a copied script never spends by accident. This is a guard in your code; it does not call Sume, so it cannot tell you a price.

What it does not replace

The cap bounds one run, and the balance gate returns 402 insufficient_credits before provider work starts. Dry runs complement them by catching mistakes earlier, such as a loop that submits the same item twice.

Cost controls by layer (read 2026-10-03)
LayerControlCatches
Before the callDry run and reviewWrong batch size, missing cap
On the rungeneration_spend_cap_usdRunaway single run
On the accountBalance and 402Spending beyond funds

Sources

Related posts

More in Developers

All Developers posts

Written by Sume