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
- Bash progress line for a Sume bulk queue from counts with jq
Poll a Sume bulk queue and print 'running: 60/100 done, 4 running, 2 failed' with curl and jq; back off, ride out 429 and 503, and exit 1 if any item failed.
- Bash: split a TSV into 100-row Sume bulk queues with jq and curl
A short shell script that cuts a product TSV into 100-row chunks, builds each bulk body with jq, and posts it under a chunk-named idempotency key.
- bash wait -n fails on macOS bash 3.2: cap curl jobs at four
On macOS /bin/bash 3.2 'wait -n' is an invalid option, so a throttled curl loop spins. A portable version that caps Sume video submits at four in flight.
- 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.
Written by Sume