Balance & spend API
Check your wallet balance and what you have spent, from code, with your API key.
Four read-only endpoints answer "how much do I have left?" and "how much have I spent?" without opening the console. They authenticate with the same API key you use for model calls, are not billed, and are answered by RouteMux itself.
| You want to know | Call |
|---|---|
| How much can this key still spend? | GET /v1/user/balance |
| How much has my account spent today and this month? | GET /v1/account/info |
| How much has this one key spent, and how much of its limits are left? | GET /v1/key/info |
| My tool expects OpenAI's billing endpoints | GET /v1/dashboard/billing/subscription |
Send the key the same way as for model calls — see Authentication. All amounts are in USD.
Account balance and spend
curl https://api.routemux.com/v1/account/info \
-H "Authorization: Bearer $ROUTEMUX_API_KEY"{
"data": {
"wallet": {
"available_credit_usd": "42.180000",
"total_credit_usd": "42.180000",
"negative_credit_limit_usd": "0.000000",
"month_spend_usd": "57.820000",
"day_spend_usd": "3.410000"
},
"burn_rate": {
"avg_daily_usd": "1.927333",
"days_remaining": 21
},
"alerts": { "balance_low_threshold_usd": "5.000000" },
"auto_topup": null,
"campaign_credits": []
},
"requestId": "…"
}| Field | Meaning |
|---|---|
wallet.available_credit_usd | What you can spend right now: your balance minus amounts reserved by requests still in flight. |
wallet.total_credit_usd | Your balance including those reservations. |
wallet.negative_credit_limit_usd | The lowest your balance may go before new requests are rejected — 0 or a small negative number. See Negative balance. |
wallet.day_spend_usd | Charged today, since 00:00 UTC. |
wallet.month_spend_usd | Charged this calendar month, since the 1st at 00:00 UTC. |
burn_rate.avg_daily_usd | Your total spend over the last 30 days divided by 30. |
burn_rate.days_remaining | Whole days your available balance lasts at that rate. null if you spent nothing in the last 30 days. |
alerts.balance_low_threshold_usd | Your low-balance alert threshold from the console, or null if none is set. |
auto_topup | Reserved. Always null today. |
campaign_credits | Model-scoped campaign credits on your account. Each item includes campaignName, models, grantedUsd, remainingUsd, callsThisPeriod, nextRefreshAt and periodEndsAt. |
Spend covers every key on the account. It counts what you were actually
charged, including charges paid from bonus credit; failed requests count as 0.
A request shows up in spend once it settles — while it is still running, it only
lowers available_credit_usd through its reservation.
Per-key spend and limits
curl https://api.routemux.com/v1/key/info \
-H "Authorization: Bearer $ROUTEMUX_API_KEY"{
"data": {
"key": {
"id": "…",
"name": "prod-backend",
"tags": [],
"status": "active",
"expires_at": null
},
"wallet": {
"available_credit_usd": "42.180000",
"today_spend_usd": "3.410000",
"month_spend_usd": "57.820000"
},
"limits": {
"monthly_credit_limit_usd": "50.000000",
"monthly_used_usd": "12.500000",
"monthly_remaining_usd": "37.500000",
"daily_credit_limit_usd": null,
"daily_used_usd": "0.830000",
"daily_remaining_usd": null,
"allowed_models": [],
"rate_windows": []
}
},
"requestId": "…"
}This key's spend is under limits, not wallet
wallet.* here is the same account-wide data as /v1/account/info. What this
particular key spent is limits.monthly_used_usd and limits.daily_used_usd.
| Field | Meaning |
|---|---|
key.expires_at | When the key expires, or null if it never does. |
limits.monthly_used_usd | Charged to this key since the 1st of the month at 00:00 UTC, or since you last reset the key's usage, whichever is later. |
limits.daily_used_usd | Charged to this key since 00:00 in the key's quota timezone (set on the key in the console; defaults to your account timezone), or since the last reset. |
limits.monthly_credit_limit_usd, limits.daily_credit_limit_usd | The spending caps set on this key. null means no cap. |
limits.monthly_remaining_usd, limits.daily_remaining_usd | Cap minus used, never below 0. null when there is no cap. |
limits.allowed_models | Models this key is restricted to. Empty means every model you can access. |
limits.rate_windows | Reserved. Always empty today. |
Simple balance
For scripts and tools that just want one number:
curl https://api.routemux.com/v1/user/balance \
-H "Authorization: Bearer $ROUTEMUX_API_KEY"{ "balance": 37.5, "is_active": true, "currency": "USD" }balance is what this key can still spend: the smallest of your available
wallet balance, the key's remaining monthly cap and its remaining daily cap. A key
with a small cap therefore shows less than your wallet holds.
Unlike the other endpoints, this one returns a bare object (no data wrapper) and
balance is a number, not a string. It is also served at /user/balance for tools
whose base URL is the host root.
OpenAI-style billing endpoints
Some tools read a provider's balance from OpenAI's billing endpoints. Both are
supported, with or without the /v1 prefix:
curl https://api.routemux.com/v1/dashboard/billing/subscription \
-H "Authorization: Bearer $ROUTEMUX_API_KEY"{
"object": "billing_subscription",
"has_payment_method": true,
"soft_limit_usd": 37.5,
"hard_limit_usd": 37.5,
"system_hard_limit_usd": 37.5,
"access_until": 0
}hard_limit_usd carries the same number as balance above.
GET /v1/dashboard/billing/usage always returns total_usage: 0, so a tool that
computes "limit minus usage" lands on your real balance. It does not report
what you spent — use /v1/account/info for that.
The cost of a single request
These endpoints return totals, not per-request charges. Each request's exact charge is listed in Logs in the console — see Observability & usage.
When the key itself can't be used
These endpoints run the same key checks as model calls. A key that could not make a model call right now gets an error here too, instead of a balance:
| Situation | HTTP | Code |
|---|---|---|
| No key sent | 401 | AUTH_API_KEY_REQUIRED |
| Unknown or revoked key | 401 | AUTH_INVALID_API_KEY |
| Key disabled in the console | 403 | AUTH_API_KEY_INACTIVE |
| Key expired | 403 | AUTH_API_KEY_EXPIRED |
| Key's 30-day cap used up | 429 | LIMIT_API_KEY_QUOTA_EXHAUSTED |
| Key's daily cap used up | 429 | LIMIT_API_KEY_DAILY_QUOTA_EXHAUSTED |
| Account suspended | 403 | AUTH_ACCOUNT_SUSPENDED |
So a successful response always describes a usable key — is_active is true and
key.status is active. If you want to watch account-wide balance even while one
key is capped, query it with a key that has no cap.
Rate limits
Each key can call these endpoints up to 60 times per minute, and each IP
address up to 300 times per minute. Beyond that you get HTTP 429
LIMIT_RATE_EXCEEDED with a Retry-After header.
Polling once a minute is plenty.
Errors use the same envelope as model calls — see Errors.