Auto-load (Auto-recharge)
GET/PUT /io/wallet/autoload — configure automatic wallet top-ups when the balance runs low. 1 credit = $1.
Auto-load automatically tops up a user's wallet by charging their saved card off-session whenever the balance drops below a threshold — so metered features never stall on an empty wallet.
GET https://api.misar.io/io/wallet/autoload
PUT https://api.misar.io/io/wallet/autoloadHow it works
- Save a card. The first manual top-up runs Checkout with
setup_future_usage: off_session, so the buyer's card is attached to a Stripe Customer and saved. The webhook stores the customer + card on the wallet. - Enable auto-load.
PUT /io/wallet/autoloadwithenabled: true, athreshold(credits) and anamountDollars(dollars to charge). Enabling requires a saved card. - Trigger. When a deduct drops the balance below the threshold, the wallet atomically claims the charge (under the wallet row lock, with a 5-minute cooldown so concurrent deducts can't double-charge) and creates an off-session
PaymentIntenton the saved card. Credits are granted through the same idempotenttop_up_walletpath as a manual top-up (keyed on the PaymentIntent id). - Recover from failure. A declined charge is recorded; after 3 consecutive failures auto-load disables itself and the user is emailed to update their card.
Safety net
Besides the inline trigger, a scheduled scan (POST /io/wallet/autoload/run, Bearer CRON_SECRET) re-checks enabled wallets whose balance is below threshold and charges any that the inline path missed. The same atomic claim + cooldown guarantees no double-charge.
Authentication
SSO bearer (own config) or service key (+ user_id).
Authorization: Bearer <sso_access_token>
# — or —
x-wallet-service-key: <WALLET_SERVICE_KEY> # with ?user_id=<uuid> / body.user_idGET — read the configuration
curl "https://api.misar.io/io/wallet/autoload" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"enabled": true,
"threshold": 10,
"amountDollars": 50,
"hasPaymentMethod": true,
"cardBrand": "visa",
"cardLast4": "4242",
"failureCount": 0,
"lastError": null,
"lastSuccessAt": "2026-07-27T09:14:22.000Z"
}enabledbooleanthresholdnumber | nullamountDollarsnumber | nullhasPaymentMethodbooleantrue to enable.cardBrandstring | nullvisa (display only).cardLast4string | nullfailureCountnumberlastErrorstring | nulllastSuccessAtstring | nullPUT — update the configuration
enabledbooleanbodyrequiredTurn auto-load on or off.
thresholdnumberbodyBalance (credits) that triggers a recharge. Required when enabled: true. Range 0–1000000.
amountDollarsintegerbodyDollars to charge per recharge. Required when enabled: true. Integer in 10–100000.
curl -X PUT "https://api.misar.io/io/wallet/autoload" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "enabled": true, "threshold": 10, "amountDollars": 50 }'Returns the updated config (same shape as GET).
Enabling requires a saved card
PUT with enabled: true and no saved card returns 409 { "error": "...", "reason": "no_payment_method" }. Prompt the user to make one manual top-up first — that saves their card. Invalid threshold/amountDollars return 400.
Emails
Every auto-load money event emails the user (via the central api.misar.io/mail/v1/send from no-reply@trans.misar.io):
| Event | |
|---|---|
| Auto-load charged the card and credited the wallet | Auto-reload succeeded (amount, credits, new balance, receipt) |
| Off-session charge declined | Auto-reload failed — update your card (+ "disabled after 3 failures" note) |
| Balance low but auto-load off / no card | Low-balance warning |
| Saved card expiring / auto-updated | Card-expiring reminder (auto-updated cards are refreshed silently) |