Sume 403 stripe_topup_team_only: top-ups buy team credits

POST /api/billing/top-ups returns 403 stripe_topup_team_only. On-demand credits are bought into a team wallet, by an Admin, for $10 to $1000.

5 min readSume
All posts

stripe_topup_team_only means you called the personal top-up route. Since credits were unified, on-demand usage is bought into a **team wallet**: an Admin of an organization workspace posts to /api/billing/org/top-ups with an amount from $10 to $1000. Personal wallets keep and spend what they already hold, and a plan gives included usage.

The exact error

The body is code: stripe_topup_team_only with the message "On-demand usage is purchased from a team wallet. Create or join an organization to buy additional credits, or upgrade your plan for more included usage." It is defined in apps/web/lib/billing/topup-errors.ts.

What the team route does

  • Limits are $10 to $1000 per checkout. Presets are $50, $100, $500 and $1000, and custom amounts inside the range work. One credit is $1.
  • Only a role with billing.manage can start it, which means Admin or owner.
  • The route writes a pending top-up row at the team's wallet, then opens a Stripe Checkout Session in payment mode.
  • Credit lands only when the verified Stripe webhook reports the session paid. The success redirect is informational and never issues credit.
  • One purchase mints exactly one credit lot in the team's single pool, and any kind of usage can spend it.

Receipts belong to the company

The first checkout creates a Stripe customer for the organization and stores it on the workspace row. Receipts and invoices therefore go to the company rather than to whichever admin paid. Delayed methods such as bank transfer finish as unpaid and settle later; the same idempotent credit runs when Stripe reports the async payment succeeded.

Who can see the balance

Any member can read the team balance at GET /api/billing/org/balance; a can_manage_billing flag decides whether the top-up button shows. A wallet that was never funded answers provisioned: false, and a generation against it fails with 402 organization_wallet_not_provisioned rather than falling back to someone's personal wallet.

What to do

If you only have a solo account, upgrade the plan or create an organization first. If you are an Admin, fund the team wallet and ask producers to run under the team workspace so usage draws from the pool. Refunds are handled in Stripe, with a negative operator grant for any part already spent; there is no in-app refund flow.

Auto top-up is a separate switch

Auto top-up uses a saved Stripe payment method in setup mode; it is a wallet feature rather than a subscription. If the environment has the charging worker off, the web routes answer auto_topup_unavailable instead of saving a card behind an Enabled badge that would never charge. The team docs also list no organization auto top-up yet, so for a team the overage path is a one-time top-up by an Admin. Plan this before a big batch: check the balance endpoint, top up once, and let the batch draw from the pool.

Related posts

More in Pricing

All Pricing posts

Written by Sume