Upgrade and billing portal
Stripe Checkout for plan changes and Customer Portal for payment management.
Upgrade your tenant through Stripe Checkout or manage an existing subscription in the Stripe Customer Portal. Both flows require dashboard JWT authentication (JwtAuthGuard + tenant context).
Subscription flow
List available plans
GET /billing/plans Authorization: Bearer <jwt>Returns active plans with monthly email limits, AI token grants, and Stripe price IDs.
Start checkout
POST /billing/checkout Authorization: Bearer <jwt> X-Tenant-Id: clxxxxxxxx Content-Type: application/json{ "planSlug": "pro", "successUrl": "https://your-app.com/billing/success", "cancelUrl": "https://your-app.com/billing/cancel" }Response:
{ "url": "https://checkout.stripe.com/..." }— redirect the admin browser to that URL.Stripe completes payment
Stripe sends
checkout.session.completedtoPOST /billing/webhook. MailingCore activates the subscription and grants the plan's monthly AI tokens.Verify subscription
GET /billing/subscription Authorization: Bearer <jwt> X-Tenant-Id: clxxxxxxxxConfirm plan slug, status, and current period dates before resuming high-volume sends.
Customer Portal
For payment method updates, invoices, cancellation, or reactivation:
POST /billing/portal
Authorization: Bearer <jwt>
X-Tenant-Id: clxxxxxxxx
Response: { "url": "https://billing.stripe.com/..." }. The portal return URL defaults to your dashboard.
When to upgrade
| Situation | Action |
|---|---|
X-Quota-Warning: true on sends | Consider upgrading before hitting the 110% grace ceiling — see Quota enforcement |
| HTTP 429 monthly quota exceeded | POST /billing/checkout with a higher planSlug, or wait for the next billing cycle reset |
| Need more domains, members, or templates | Compare tiers in Plans and pricing |
Dashboard shortcut
The Billing route in the dashboard mirrors these endpoints: view current usage, launch checkout, or open the Customer Portal without curl.