Skip to main content

Configure wallet auto-top-up

Auto-top-up keeps the wallet funded without an operator watching the balance. You set a threshold (the balance that triggers a refill) and a refill amount, and a scheduler that runs every 15 minutes charges the saved default payment method the moment your balance dips below that line. Use it for the accounts that cannot afford a human on watch: an overnight campaign, an unattended dialer, a customer-facing voice flow that must not stop at 03:00. Prefer auto-top-up over a manual top-up whenever the account is consumed by API traffic rather than interactive dashboard use. If a human authorizes every refill through Billing & payments, a missed refill becomes an outage; the scheduler removes the human from the critical path. Manual top-up remains the right tool for the very first payment (see prerequisites below) and for recovering a failed attempt.

Prerequisites — a reusable payment method

Auto-top-up charges the organization’s default payment method off-session. That requires two things saved before the first scheduler tick:
  • A Stripe customer exists for the organization. The platform creates it on the first interactive checkout, so the prerequisite is completing one manual top-up at least once.
  • A saved default payment method is on file — a card saved during checkout, or a bank debit (ACH) that has been approved. Check it with:
An empty data object here means the scheduler will skip every attempt with a no_default_payment_method error until a method is saved.

Threshold and refill — set the pair

Configure the rule with PUT /api/v1/billing/auto-topup. All amounts are minor currency units (cents when the currency is USD):
In that example the scheduler refills 1,000wheneverthebalancedropsbelow1,000 whenever the balance drops below 50, constrained to at most $3,000 of auto-charges per calendar month and at most 2 refills per UTC day. Validation rules, enforced with a 422 on save:
  • threshold_minor must be at least 100 ($1.00).
  • recharge_amount_minor must be at least 100 (1.00)andatmost1.00) and at most 10,000 per single refill.
  • recharge_amount_minor must be greater than threshold_minor — otherwise the balance would sit at the trigger line after every refill and fire another charge on the next spend. Pick a refill comfortably larger than the threshold.
  • max_monthly_minor, when set, must be at least one full refill (>= recharge_amount_minor), otherwise the very first charge would breach the cap.
  • max_topups_per_day is clamped to the range 1–100; leave it unset to use the platform default of 5 per day.
  • currency must be a 3-letter code; today the wallet ledger credits USD only, so save USD. A non-USD value is accepted at save time but the scheduler will pause the rule with a currency_not_supported error.
The safety layer on top of your settings: a 5-minute cooldown between refills plus a hard limit of one refill per rolling hour, even when the balance keeps dipping under the threshold. Combined with the daily cap, a misconfigured rule can burn at most a bounded amount instead of charging in a loop. Clear the monthly cap deliberately. Because the monthly cap is a safety control, setting max_monthly_minor: null alone does not clear it — the saved cap survives a blank-form submit. To remove the cap, pass clear_cap: true with the request:
To disable the rule entirely, either PUT with "enabled": false (the threshold/refill draft survives for later re-enable), or DELETE /api/v1/billing/auto-topup, which also clears the runtime counters. Response fields such as last_charge_at, month_charged_minor, day_topups_count, and last_error are runtime telemetry written by the scheduler — reads expose them, writes ignore them, so a save can never forge a “this month charged: $0” reset.

Notifications — success and failure

Every attempt, every outcome, is recorded in two places:
  • Audit log (signed audit log): billing.auto_topup_triggered on a refill attempt, billing.auto_topup_failed on a refusal, and billing.auto_topup_skipped when the rule self-pauses because your currency is not supported. A successful refill then credits the wallet via the payment webhook, which appears in the normal wallet ledger alongside manual top-ups.
  • The config itself: the scheduler stamps last_error and last_error_at onto the rule after every failed attempt, and GET /api/v1/billing/auto-topup exposes both so a monitoring loop can alert on them. Success resets last_error to null.
Tip on a failure: rather than poll the GET in a cron of your own, combine the audit-log surface with Usage-anomaly alerts and route the billing.auto_topup_failed entries to your operations channel.

Interactions with the other limits

Auto-top-up is one of four wallet-side controls, and it composes with each of the other three differently:
  • Low-balance renewal warnings. The dashboard’s low-balance alert is independent of auto-top-up; set your threshold above what your hourly burn consumes between warning intrusions, and the rule absorbs the warning entirely.
  • Org spend caps. The ceilings in Spend caps, budget alerts, and auto-cutoff measure what the wallet spends, which is the opposite side of the ledger from what auto-top-up refills. Set them together: the spend cap bounds burn, the auto-top-up rule replenishes underneath it.
  • Per-API-key budgets. Apply Per-API-key spend budgets to any high-volume key to cap what a single integration can consume in a month, independent of how the wallet refills. The dashboard badge described in Usage budgets and threshold alerts is a browser-side tripwire for the request-volume side of usage; auto-top-up governs the money side.

Recover a failed attempt

When last_error is non-null the rule stays armed — it retry-schedules the next tick and simply skips until the cause is resolved. The four canonical causes:
  1. no_default_payment_method — no saved card or approved ACH. Complete one interactive top-up from Billing & payments to create the Stripe customer and save the method, then re-check GET /billing/payment-method.
  2. payment_intent_requires_payment_method — the saved card was declined. Update the payment method to a working card.
  3. payment_intent_requires_action — the charge needs customer authentication (SCA/3-D Secure). Top up interactively once to satisfy the bank’s challenge; subsequent off-session refills resume automatically.
  4. currency_not_supported — the saved currency is outside the supported set (today: USD). Update the rule to USD, or top up interactively and disable auto-top-up.
A fifth class — a raw Devotel or Stripe error code — is rare; it appears unchanged in last_error, so resolve the underlying issue (for example a declined refund or a wallet cap interrupt) and the next tick resumes.

End-to-end walkthrough

A complete setup in four calls:
  1. Verify prerequisitesGET /api/v1/billing/payment-method returns your saved method’s brand, last four, and expiry.
  2. Enable the rulePUT /api/v1/billing/auto-topup with the threshold, refill, optional monthly cap, optional daily count, and currency: "USD" as above.
  3. Simulate the threshold — the decision is what fires the refill, not a simulated spend; the 15-minute tick decides when the live balance minus threshold_minor reads below zero. To test the pipeline safely, set a deliberately high threshold above the current balance so the next tick immediately refills, then lower the threshold back to the production value.
  4. Inspect the outcome — re-read GET /api/v1/billing/auto-topup and confirm last_charge_at advanced and last_error is null; then open Billing & payments and confirm the matching credit in the wallet ledger, or the audit-log surface for the billing.auto_topup_triggered entry.
Between those steps the never-write rule applies: the scheduler stamps last_charge_at, month_charged_minor, and day_topups_count itself. A save payload that carries them is ignored by validation.