Billing
June 9, 2026 · View on GitHub
Full Stripe go-live: STRIPE-SETUP.md · npm run wizard:stripe
Without Stripe (current)
Stripe not required. Do not set STRIPE_* secrets — billing stays disabled.
Option A — single hosted key (simplest):
npm run issue:key
npx wrangler secret put API_KEY # or API_KEYS
Legacy plan: 120 req/min, up to 500 active inboxes.
Option B — key in Neon (free, for pilots with team_id):
npm run issue:key:db -- pilot-name
Free plan: 60 req/min, 10 inboxes. Pro manually:
npm run team:plan -- TEAM_ID pro
team_id visible in GET /v1/me or issue:key:db output.
Dashboard and API work without Upgrade button.
Stripe Pro (when available)
Plans
| Plan | Rate limit | Active inboxes |
|---|---|---|
| free | 60/min | 10 |
| pro | 300/min | 100 |
| legacy | 120/min | 500 (wrangler API_KEY only) |
New key in DB
npm run issue:key:db -- acme-corp
Key stored in teams + api_keys. Do not duplicate in API_KEYS.
Stripe (hosted)
- Stripe Dashboard → Product → Price (subscription) → copy
price_… - Webhook:
https://api.webmailagent.com/webhooks/stripe
Events:checkout.session.completed,customer.subscription.updated,customer.subscription.deleted - Secrets:
npm run wizard:stripe→npm run setup:stripe-prod - Verify:
npm run doctor:billing·npm run test:contract:qa:billing - UI: dashboard.html · billing.html