Billing

Billing in Xagent is subscription-based and powered by Stripe. Each team is on a plan that sets monthly quota limits. Usage is metered against those limits.

How Billing Works

  • A team subscribes to a plan — Free, Starter, or Business.
  • Paid plans are billed through Stripe Checkout; manage payment methods and invoices in the Stripe customer portal.
  • Each plan caps agents, monthly executions, and API calls. See Usage & Quotas.

Subscribing & Upgrading

These endpoints authenticate with a JWT access token; the POST actions require the caller to be a team admin (otherwise 403 "Team admin privileges required").

Start a checkout session to subscribe to a paid plan. Returns a Stripe Checkout URL to redirect the user to:

POST /api/billing/create-checkout-session
{ "plan": "starter", "interval": "monthly" }
{ "url": "https://checkout.stripe.com/c/pay/cs_test_..." }

plan is starter or business; interval is monthly (default) or yearly. Errors: 400 "Invalid plan", 409 "Team already has an active subscription. Use the Customer Portal to manage it."

Open the customer portal to manage an existing subscription (no request body):

POST /api/billing/portal-session
{ "url": "https://billing.stripe.com/p/session/..." }

Errors: 400 "No Stripe customer found".

Upgrade or change plan on an active paid subscription:

POST /api/billing/upgrade-plan
{ "plan": "business" }
{ "message": "Upgraded from starter to business" }

Errors: 400 "No active paid subscription. Use checkout to subscribe first.", 400 "Already on this plan".

Read the current subscription (any team member):

GET /api/billing/subscription
{
  "plan": "starter",
  "status": "active",
  "current_period_end": "2026-08-10T09:15:00Z",
  "cancel_at_period_end": false
}

A team with no paid subscription returns { "plan": "free", "status": "active", "current_period_end": null, "cancel_at_period_end": false }.

Webhooks

Stripe notifies Xagent of subscription events (payments, cancellations, plan changes) via a signed webhook so the team's plan stays in sync:

POST /api/webhooks/stripe    # Stripe webhook receiver

See Webhooks for the handled events, signature verification, and payload examples.

Self-hosting billing

Billing requires Stripe credentials. Set STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, and the plan price ids — see Environment Variables.

Next Steps