Architecture Overview
How identity, billing, and inference flow through the Xcity stack.
Xcity’s stack has three planes — identity, billing, and inference — that any product on the platform composes against.
┌────────────────────────────────────────────┐
Browser → │ xcity-home (Astro, *.xcity.one) │
│ ├── /api/auth/* identity BFF │
│ ├── /api/billing/* Stripe BFF │
│ └── /api/me/* plan / key resolver │
└──────┬───────────┬────────────────┬────────┘
│ │ │
▼ ▼ ▼
GoTrue Stripe LiteLLM
(auth.xcity) (billing) (tokenhub.xcity)
│
▼
Solar Compute (AR)
Identity plane
Authentication is centralized on auth.xcity.one (a self-hosted GoTrue instance with Supabase as a dev fallback). The xcity-home Astro app issues a host-only, SameSite=Lax session cookie scoped to *.xcity.one. Every browser sub-product on a .xcity.one subdomain inherits that session by hitting xcity-home BFF endpoints with credentials: 'include'.
See Sub-product Integration for the integration recipe.
Billing plane
Stripe is the source of truth for plans, subscriptions, and invoices. The xcity-home server holds the only set of Stripe credentials; sub-products never call Stripe directly. Plan and entitlement state is mirrored onto each user’s GoTrue app_metadata via Stripe webhooks landing at /api/billing/webhook.
See Billing model and the Stripe webhook reference.
Inference plane
tokenhub.xcity.one runs LiteLLM in front of one or more upstream model providers and our own self-hosted models. Every API key is bound to a Xcity account, a plan whitelist, and a budget cap. Requests are logged for the usage ledger that drives /dashboard/usage and overage billing.
Sub-products
Anything that lives on a *.xcity.one subdomain (xct-chat, xct-flow, xct-agent-marketplace, future ones) integrates via three BFF endpoints and never holds its own Stripe or auth credentials:
| Endpoint | Returns |
|---|---|
GET /api/auth/me | Current user |
GET /api/me/litellm-key | Bearer + plan + allowed models |
GET /api/billing/plan | Plan id, entitlements, renewal |
CORS is enforced via a regex allowlist over *.xcity.one plus localhost for development; see src/lib/cors.ts.
Where data lives
| Domain | Store | Region |
|---|---|---|
| User identity | GoTrue Postgres | San Juan, AR (primary) |
| Subscriptions | Stripe | Global (US) |
| API usage | LiteLLM Postgres | San Juan, AR |
| Audit logs | Object storage | San Juan + DR |
Enterprise contracts can pin a region or require an on-prem-style deployment — see Enterprise: Data Residency.
Last updated: