GuidesRecipes
Poll Credit Balance
Read the tenant's prepaid credit balance, gate expensive operations, and handle OSS mode gracefully.
vendo.billing.balance() returns the tenant's current prepaid credit balance. Use it to gate expensive operations, render a balance display, or trigger a low-balance warning.
Vendo mode only. Raises VendoOnlyFeature in OSS mode — there is no billing backend when running outside Vendo.
Balances are reported in micros (1 USD = 1,000,000 micros). Divide by 1_000_000 to render dollars.
Read the balance
from vendo import Vendo
from vendo.errors import VendoOnlyFeature
client = Vendo()
def get_balance():
try:
balance = client.billing.balance()
return {
"credits_remaining_usd": balance.credits_remaining_micros / 1_000_000,
"currency": balance.currency,
"top_up_url": balance.top_up_url,
}
except VendoOnlyFeature:
return {"credits_remaining_usd": None, "message": "billing not available in OSS mode"}
vendo.billingis also exposed as a lazy module-level singleton —vendo.billing.balance()works onceVENDO_API_KEYis set — but the explicitVendo()client makes the dependency obvious and is what every other recipe on this page uses.
import { Vendo, VendoOnlyFeature } from "@vendodev/sdk";
const vendo = new Vendo();
async function getBalance() {
try {
const balance = await vendo.billing.balance();
return {
creditsRemainingUsd: balance.creditsRemainingMicros / 1_000_000,
currency: balance.currency,
topUpUrl: balance.topUpUrl,
};
} catch (e) {
if (e instanceof VendoOnlyFeature) {
return { creditsRemainingUsd: null, message: "billing not available in OSS mode" };
}
throw e;
}
}Gate a feature on available balance
MIN_BALANCE_MICROS = 500_000 # $0.50
def run_expensive_action(client: Vendo):
try:
balance = client.billing.balance()
except VendoOnlyFeature:
balance = None
if balance is not None and balance.credits_remaining_micros < MIN_BALANCE_MICROS:
return {"error": "insufficient_balance", "credits_remaining_micros": balance.credits_remaining_micros}
return client.data.execute("SOME_EXPENSIVE_ACTION", {})const MIN_BALANCE_MICROS = 500_000; // $0.50
async function runExpensiveAction() {
let balance: Awaited<ReturnType<typeof vendo.billing.balance>> | null = null;
try {
balance = await vendo.billing.balance();
} catch (e) {
if (!(e instanceof VendoOnlyFeature)) throw e;
}
if (balance !== null && balance.creditsRemainingMicros < MIN_BALANCE_MICROS) {
return {
error: "insufficient_balance",
creditsRemainingMicros: balance.creditsRemainingMicros,
};
}
return vendo.data.execute("SOME_EXPENSIVE_ACTION", {});
}Notes
balance()is a live read — it reflects credits after pending charges are applied. Cache it for no longer than 30 seconds if you are polling it in a dashboard.BalanceExhaustedis raised automatically by the proxy when a metered operation would push the balance below zero. You do not need to check the balance before everydata.executecall — the proxy enforces it.SpendCapscan also block operations before the balance hits zero. Read spend caps withvendo.billing.spend_caps().- The billing period is calendar-month UTC.
billing.usage(period="month")returns the breakdown for the current month.