Billing & Usage

Every account has two billing meters. Each run settles on exactly one:

MeterCoversBilled as
Prepaid balanceRuns with user_id (work for one of your end users)Per token, prepaid wallet, provider list prices (no markup)
Platform planYour own runs: web app, and API/SDK calls with no user_idIncluded runs per month by plan, plus optional per-run overage

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.

usage.planPlanModel funding
inactiveSetup incompleteConnect a model provider or choose a paid plan
trialTime-limited trialCheck account eligibility
freeHobbyYour connected model provider
individualIndividualYour connected model provider
pro, max_5x, max_20xTeams: 100, 500, or 1,000 tasksPlatform inference included

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:

Python
client.billing.set_overage(enabled=True, monthly_cap_cents=5000)  # $50 cap
Details: how overage kicks in
  • When the included allotment is exhausted, a run returns 402 RUN_LIMIT_REACHED with overage_available in error.details (true only when overage can be enabled for your account). On an account already on Hobby, free_path_available is false — 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 returns 402 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-only

When 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.completed webhook), so balance() 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 with balance_after_micros for 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:

Python
# 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_method and run.auth_provider identify the inference route. Use settled_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:

Python
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 returns 403 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 in receipts() 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.

Python
client.billing.set_alert_threshold(low_balance_threshold_cents=2000)  # warn below $20
Details: alert tiers
TierFires whenWebhook event
Lowbalance ≤ your threshold (default $5)balance.low
Criticalbalance ≤ 20% of the thresholdbalance.critical
Depletedbalance ≤ $0, runs fail until you top upbalance.depleted

Each tier fires at most once per depletion cycle; all three re-arm on the next top-up.

Usage over time and receipts

Python
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 links
Details: timeseries semantics and per-run metrics
  • usage_timeseries() returns daily token + USD buckets, zero-filled over the window (default: last 30 UTC days), reconciling with usage().cost_used.
  • Filter with user_id (one end-user) or agent_id; pass group_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_id is the wire name for the agent id: query params and JSON bodies keep it. The SDK accepts agent_id (canonical) and teammate_id alike.
  • Every run response also carries per-run metrics: run.usage has the token lanes (input/output/cache) and cost_usd, the exact figure billing meters. It's None until 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.

Next: Users · Limits · Errors

Was this page helpful?