How many days of Sume balance are left? A daily snapshot forecast
Forecast how long a Sume wallet lasts: snapshot GET /v1/balance daily, sum the drops, divide. Why /v1/usage's 100-row page is the wrong input. Python included.

To forecast how many days of Sume balance you have left, read GET /v1/balance once a day, add up every day-over-day drop, divide by the days elapsed to get a burn rate, and divide today's balance by it. Sume's Usage docs say the balance is USD-denominated, so a daily snapshot gives you a series you control.
This post is about runway, not about what one job cost. For one job, thread or run, use the scoped /v1/usage reads covered in Cost of one Sume agent thread or turn.
Why not forecast from /v1/usage?
The unscoped GET /v1/usage returns the newest rows only. In the Sume API source the limit query is an integer from 1 to 100, and there is no date filter in that schema. A busy workspace can burn through 100 rows in an afternoon, so a window you cannot widen is a poor basis for a weekly or monthly rate.
The ledger is also not one row per dollar spent. Rows move through reserved, captured and refunded, and the docs say a refunded row keeps its hold amount in billable_amount_usd_micros. Adding rows by hand double counts. See Why Sume usage rows add up to more than you spent for the three amounts.
What does the balance response give you?
The balance endpoint wraps its fields in data.balance. The fields this forecast needs are below, from the Sume API source and the Usage page.
| Field | Meaning | Use in the forecast |
|---|---|---|
| available_amount_usd_micros | Spendable USD balance in millionths of a dollar | The snapshot you store |
| available_amount_usd_cents | The same amount in cents | Display only |
| state | funded or empty | Alert when it flips to empty |
| expiration.expiring_soon_amount_usd_micros | Amount in credit lots expiring within expiring_soon_days | Subtract from runway if you cannot spend it in time |
| expiration.expiring_soon_days | The look-ahead window, 30 by default in the source | Context for the line above |
What does the script do?
Run it once a day from cron or CI at the same hour. It appends a timestamp and the balance to a CSV, adds every drop between consecutive snapshots as spend, and prints days left. A rise between snapshots is a top-up, a grant or a refund, so it is ignored rather than subtracted.
import csv, os, time
import requests
KEY = os.environ["SUME_API_KEY"]
LOG = "balance_log.csv"
def balance_micros() -> int:
r = requests.get("https://api.sume.com/v1/balance",
headers={"Authorization": f"Bearer {KEY}"}, timeout=30)
r.raise_for_status()
return r.json()["data"]["balance"]["available_amount_usd_micros"]
def main() -> None:
with open(LOG, "a", newline="") as f:
csv.writer(f).writerow([int(time.time()), balance_micros()])
rows = [(int(t), int(b)) for t, b in csv.reader(open(LOG))]
spent = sum(b0 - b1 for (_, b0), (_, b1) in zip(rows, rows[1:]) if b1 < b0)
days = (rows[-1][0] - rows[0][0]) / 86400
if days < 3:
print("Need at least 3 days of snapshots.")
return
burn = spent / days / 1_000_000
left = rows[-1][1] / 1_000_000
print(f"burn ${burn:.2f}/day, balance ${left:.2f}, about {left / burn:.0f} days left")
main()Where is the forecast wrong?
Three places, and you should know them before you trust the number.
- Holds. A job reserves its estimate at submit and refunds the difference after it finishes, so a snapshot taken while a large batch is in flight can read low. Snapshot at a quiet hour, and use at least a week of data.
- Top-ups hidden inside a drop. If you top up and spend more than the top-up between two snapshots, the net change understates spend. Daily snapshots make this rare.
- Step changes. A new campaign or a plan change breaks the average. Recompute from the last 7 days instead of the whole file once your workload changes.
What should you do with the number?
Pair days left with the largest hold your next batch will place. The admission docs say a submit fails with 402 insufficient_credits when Sume cannot reserve the estimated cost, so runway is only useful if the balance also covers the biggest single reservation. The sizing table in largest hold one Sume call can place gives that figure per endpoint.
Top-ups are a dashboard action: the Billing and credits page says the public API exposes balance and usage reads, not a top-up endpoint. So the forecast should send a message to a person, not try to fix the wallet.
Sources
Related posts
More in Pricing
- GPT Image 2.5 portrait 1024x1536 costs less than square
On fal, GPT Image 2.5 high is $0.04116 at 1024x1536 and $0.05268 at 1024x1024, though portrait has more pixels. Sume at x 1.25: about $0.051 vs $0.066.
- GPT Image 2.5 price on Sume: 1K, 1080p, 2K and 4K at low, medium, high
GPT Image 2.5 on Sume at high quality: about $0.066 at 1024x1024, $0.050 at 1920x1080, $0.069 at 2560x1440, $0.125 at 4K. Low is under a cent to 1.4 cents.
- H3 Max Recast 768p or 1080p: draft cheap, publish in HD
Sume bills H3 Max Recast at $0.375 a second at 768p and $0.5625 at 1080p. Budget a 768p test pass and one 1080p final, and what each plan costs.
- H3 Max Recast 768p vs 1080p: price per second and per clip
fal lists H3 Max Recast at $0.30 a second for 768p and $0.45 for 1080p. On Sume the same two tiers cost $0.375 and $0.5625 a second; per-clip math for 5-30 s.
Written by Sume