Plans, keys, and budgets

How accounts map to plans, how keys are scoped, and how usage is metered.

Plans

Xcity ships three default plans plus a custom Enterprise tier:

PlanMonthlyIncludesCap
Free$0basic model access, dashboardhard cap, no overage
Pro$29full model catalog, priority routingsoft cap + overage
Team$99seats, shared budgets, audit logsoft cap + overage
EnterprisecustomSSO, custom SLA, regional pinning, DPAnegotiated

Stripe is the system of record for plan state. The xcity-home app reads it through src/lib/billing.ts and mirrors the active plan onto each user’s GoTrue app_metadata.plan field via the /api/billing/webhook handler.

Keys

A key (sk-…) is bound to:

  1. A Xcity account — invalidating the account invalidates all its keys.
  2. A plan whitelist — only models allowed by the account’s current plan can be invoked. Routes to disallowed models return 403.
  3. A budget envelope — per-request budget enforced at LiteLLM admission, plus cumulative monthly cap.

Keys are minted via the dashboard or — for B2B integrations — through the Keys API. They can be revoked at any time without affecting the user’s other keys.

Budgets

Two budget signals matter:

  • Per-request cost ceiling. LiteLLM rejects a request whose estimated cost exceeds the per-request ceiling for the plan. This prevents accidental large prompts from draining a month’s budget in one call.
  • Cumulative monthly cost. The usage ledger sums to a per-account total. Free plans hard-block at the cap; paid plans switch to overage at the published rate.

You can inspect both via GET /api/me/litellm-key (returns the active envelope) and GET /dashboard/usage (visualizes the spend).

Plan changes

Upgrade and downgrade flow through Stripe Customer Portal. We listen for customer.subscription.updated and reflect the new entitlements within seconds (typically <2s end-to-end). Downgrades take effect at the end of the current billing cycle to avoid mid-cycle lockouts.

See Operations: Stripe webhooks for failure modes.

Last updated: