Balance check before an ad variant burst: Sume API 402 guard
Read GET /v1/balance before sending a burst of video variants. Sume reserves 1.25 times list price on submit and returns 402 insufficient_credits below it.

Read GET /v1/balance before a burst of ad variants, and compare it with the reserve the burst will need. Sume reserves the list price times 1.25 when you submit a video, and returns 402 insufficient_credits if the workspace balance is below that reserve. If you submit fifty variants at once, the later ones can fail with 402 although the first ones worked, so a guard in your script saves a half-finished test.
The two reads and the one error
The API reference lists GET /v1/balance as the available balance in USD and GET /v1/usage as the ledger of reservations, captures, refunds and top-ups. The videos page lists the 402 and the 429 as separate errors, and the reserve rule is stated there. We did not verify the exact JSON field names of the balance response here, so the code below prints the raw body and you can read the field yourself.
| Item | Source | Meaning |
|---|---|---|
| GET /v1/balance | API reference | Available USD balance |
| GET /v1/usage | API reference | Reservations, captures, refunds, top-ups |
| Reserve on submit | Videos page | List price times 1.25 |
| 402 insufficient_credits | Videos page | Balance below the reserve |
| 429 rate_limited | Videos page | Back off and retry |
The guard arithmetic
Take a variant whose list price is $0.80. Its reserve is 0.80 times 1.25 = $1.00. Twenty such variants need $20.00 of balance if they are all in flight at once. If you submit them in waves of five, you need $5.00 at a time. We state the multiplier from the docs and the example prices are made up for the sum, so use the real list price from the catalog.
A small shell guard
The script reads the balance, prints it, and lets you stop before you submit anything. Keep it dull on purpose; the decision about the number belongs in your own code.
#!/bin/sh
set -eu
: "${SUME_API_KEY:?set SUME_API_KEY}"
curl -sS https://api.sume.com/v1/balance \
-H "Authorization: Bearer $SUME_API_KEY"
echo
curl -sS "https://api.sume.com/v1/usage" \
-H "Authorization: Bearer $SUME_API_KEY" | head -c 600
echoHandling a 402 mid-burst
Stop submitting on the first 402. Do not retry in a loop, because a top-up is the cure and a retry changes nothing. Record which variants were accepted, since each accepted submit returned a job id. Then top up and send only the remainder, with the same Idempotency-Key for each variant, so a variant that was in fact accepted replays instead of being billed twice. A different body under the same key gives a conflict, which is another reason to keep one body per key.
On a Format run the same ceiling idea comes from generation_spend_cap_usd, which limits one run's generation spend.
Limits
The guard checks the balance at one moment. Other jobs in the workspace can spend it between your check and your submit, so treat the check as a gate, not a lock.
Use the ledger, not a guess
After a burst, read GET /v1/usage. It lists the reservations, captures, refunds and top-ups, so you can see what the burst really cost against what you reserved. Compare the total with your plan, and keep the difference as a number for the next test. If you want a per-job figure, each video poll also carries a usage object with the cost, which is the better source for a per-variant table.
Do the same check before a repeat, because a winning variant often gets re-rendered at higher resolution, and the reserve for that run is larger than the first one.
Set a floor in your script: do not submit unless the balance covers the next wave's reserve plus a margin. Submit in waves, not all at once. After each wave, read the balance again. This costs one cheap call per wave and prevents a test from ending half done on a weekend.
Each video job's list price comes from the model catalog, and GET /v1/videos/models lists what is available. Multiply the list price of the model you pinned by 1.25 and by the number of jobs in flight, and you have the balance the wave needs.
Sources
Related posts
More in Developers
- How do I make a bilingual English and Spanish audio announcement?
Make one bilingual announcement file: two TTS jobs, one per language, joined by a $0.01 Timeline audio concat with no re-synthesis. About 10 cents in total.
- callback_url or webhook_url: which field each Sume video route takes
POST /v1/videos takes callback_url; motion control, lip-sync and image routes take mode plus webhook_url. The field names and what they share.
- 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.
- 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.
Written by Sume