Billing & Usage
Every account has two billing meters. Each run settles on exactly one:
The presence of user_id decides the meter, even for API calls. Plan allowances and prepaid funds are separate; neither pays for the other.
New API accounts require user_id by default. API signups get $1 promotional prepaid credit spendable on deepseek-v4-1-flash until you top up (full catalog) or connect a model subscription for BYO personal development. Web/platform signups start the wallet at $0.
Plan usage
usage = client.billing.usage() # client.auth.get_usage() still works
print(
usage.plan,
usage.runs_used,
usage.runs_limit,
usage.period_end,
usage.free_path_available,
)
print(usage.cost_used, usage.overage_enabled, usage.overage_used_cents)What counts as a billable run? One execution that completes with output: manual, scheduled, webhook, email, reply, or retry. On the plan meter, failed runs with no output do not count against included runs.
List plans with client.billing.plans(); add include_free=True for Hobby.
Use usage.free_path_available to decide whether to offer Hobby recovery. False or missing means offer a paid plan. Connecting a model subscription does not bypass Hobby's run allowance.
Usage overage
Opt in to keep running past your plan's included runs, billed per run up to a monthly cap you set:
client.billing.set_overage(enabled=True, monthly_cap_cents=5000) # $50 capDetails: how overage kicks in
- When the included allotment is exhausted, a run returns
402 RUN_LIMIT_REACHEDwithoverage_availableinerror.details(trueonly when overage can be enabled for your account). On an account already on Hobby,free_path_availableisfalse— connecting a model plan is not recovery past the allotment. - Enabling overage needs an active platform-inference subscription. It is unavailable on trial, Hobby (stable slug
free), and Individual because their inference is customer-supplied; the call returns402 OVERAGE_UNAVAILABLE. - See errors.
Prepaid balance
Each run with user_id debits a micro-USD balance at provider list prices. Plan run limits and overage do not apply to this meter. A failed or cancelled run that consumed tokens is still debited. A retry is a separate run and a separate debit. topup() starts Stripe Checkout and returns the checkout URL.
Credits expire on a rolling window: purchased credits 12 months after your most recent paid top-up (any paid top-up refreshes the whole balance); promotional credits expire 90 days after they are granted unless you make a paid top-up. You get an email before anything expires. Effective September 8, 2026, except where prohibited by applicable law. See the Terms.
url = client.billing.topup(amount_cents=2000) # $20, opens Stripe Checkout
bal = client.billing.balance()
print(bal.balance_usd, bal.balance_micros) # balance_usd is display-onlyWhen the balance is depleted, a run returns 402 TOKEN_BALANCE_DEPLETED. The SDK raises BillingError with .details carrying balance_micros and a topup_url. Recover by topping up, or connect a model subscription for personal development. See errors.
Details: top-up mechanics and signup notes
- Top-ups are $5 minimum per charge and available to every account, including plan accounts covering API usage.
- The balance is credited asynchronously once payment completes (after the
checkout.session.completedwebhook), sobalance()won't reflect it until then. - Any completed top-up Checkout saves your card, which enables auto reload.
balance()also returns the recent transaction ledger: top-ups, reloads, per-run debits, and adjustments withbalance_after_microsfor each.- Signup dedupes alias-collapsed emails: plus-tags (
you+anything@…) always map to the base mailbox, and Gmail dot variants collapse too. An address that aliases an existing account is rejected as already registered.
Develop on your model subscription
Connect Claude Pro/Max, OpenAI Codex, xAI, or Gemini in Account → Model connections. Finish the provider sign-in and wait for Connected. See the complete setup steps.
On eligible trial/inactive accounts, connecting activates Hobby. Personal runs use your connected provider and count against the platform plan's allowance. The prepaid balance is reserved for runs with user_id.
Use a matching model and disable strict mode for personal development:
# Personal development only: this disables strict user_id checks account-wide.
# This persists. For customer-facing apps, keep strict mode on and pass user_id.
client.settings.update(require_end_user_id=False)
run = client.runs.create_and_wait(message="say hi", model="grok-4.6") # no user_id
print(run.auth_method, run.auth_provider) # "oauth_subscription", e.g. "xai"Details: scope and caveats
- Best for personal development. Consumer subscriptions carry each provider's own usage windows, rate limits, and terms. Production and multi-tenant traffic should stay on the prepaid balance.
- The credential is account-level and is never attached to a run created with
user_id. Per-end-user provider credentials are not supported. - The model must match the connected provider: Claude for Anthropic, GPT/Codex for OpenAI, Grok for xAI, and Gemini for Google. Other models use the normal route or fall back according to the account's model settings.
run.auth_methodandrun.auth_provideridentify the inference route. Usesettled_meter="wallet"in usage reports to find prepaid debits.- If an own-subscription turn fails because of provider auth, quota, rate limit, or model availability, connect or select another provider and recover the run. Task retry and chat reply resolve the current connected/preferred provider instead of reusing the failed concrete-model pin; chat resends only its failed follow-up.
Auto reload
When the balance falls below your threshold, m8tes charges your saved card the reload amount and credits it automatically:
client.billing.set_auto_reload(
enabled=True,
threshold_cents=500, # reload when balance < $5
amount_cents=2000, # charge $20 per reload
)Details: card requirement and reload cadence
- Any completed top-up Checkout saves your card; enabling auto reload without one returns
402 NO_SAVED_PAYMENT_METHOD. An account that has never topped up returns403 NO_PREPAID_BALANCE. - Reload amounts run from $5 to $10,000 per charge (lower than the manual top-up ceiling; these charges happen off-session).
- At most one reload fires per 6-hour window, so a declined card is never retried on every run, and Stripe emails a receipt for each charge.
- Reloads appear in
balance()transactions and inreceipts()alongside manual top-ups.
Spend alerts
Three escalating alerts fire as the balance drains (low, critical, depleted). Each sends an email and a webhook event so your systems can react, for example by triggering your own top-up flow.
client.billing.set_alert_threshold(low_balance_threshold_cents=2000) # warn below $20Details: alert tiers
Each tier fires at most once per depletion cycle; all three re-arm on the next top-up.
Usage over time and receipts
series = client.billing.usage_timeseries(group_by="model")
for b in series.buckets:
for s in b.models:
print(b.date, s.model, s.cost_usd)
page = client.billing.receipts() # paid top-ups with Stripe-hosted receipt linksDetails: timeseries semantics and per-run metrics
usage_timeseries()returns daily token + USD buckets, zero-filled over the window (default: last 30 UTC days), reconciling withusage().cost_used.- Filter with
user_id(one end-user) oragent_id; passgroup_by="model"for per-model slices in each bucket. surface="api"/"platform"filters the creation stamp.settled_meter="wallet"filters runs that actually hit the prepaid ledger. The two differ when an api-stamped run settles on the plan.teammate_idis the wire name for the agent id: query params and JSON bodies keep it. The SDK acceptsagent_id(canonical) andteammate_idalike.- Every run response also carries per-run metrics:
run.usagehas the token lanes (input/output/cache) andcost_usd, the exact figure billing meters. It'sNoneuntil the run produces metrics.
Per-end-user caps and usage
Multi-tenant accounts can cap each end-user's runs, cost, and rate, and break the billing period down per end-user with client.users.usage(). See Users.