Custom Domain
Billing

Plans & quotas

The plan catalog, metered domain usage, and Stripe checkout.

Plans

The public catalog is returned by GET /v1/plans (along with a billing: { configured, mode } block). Entitlements gate which products a tenant may use.

PlanPriceDomains / yearEntitlementsMotion
free$010Connectself-serve
startup$249/mo600Connectself-serve
growth$749/mo600 + metered overage (1,000-unit increments)Connect · Power · Secure/SSLself-serve
premiumdemo-gated12,000+ Monitorcontact sales
enterprisecustom12,000++ SCIM · SSO · white-labelcontact sales

Self-serve plans (free, startup, growth) are bought through Stripe Checkout. premium and enterprise route to a "book a demo" CTA and have no public price.

Status: the plan catalog is always public, but Checkout and the billing portal are live only where STRIPE_SECRET_KEY and the STRIPE_PRICE_* ids are configured. Until then those routes return 503 service_unavailable (billing.configured is false) — the case on the hosted service today. See Checkout & portal.

Metered usage

GET /v1/billing/usage reports the caller tenant's metered domain connections for the period against the plan's included quota. The tenant is derived from the authenticated credential — never a query parameter — and ?period= defaults to the current UTC calendar month.

{ "period": "2026-07", "plan": "growth", "used": 412, "limit": 600 }

growth is metered: usage beyond the included quota is billed in 1,000-unit overage increments rather than hard-blocked. The other plans are not metered.

Checkout & portal

# Start a Stripe Checkout session for a self-serve plan
curl -X POST http://localhost:8080/v1/billing/checkout \
  -H "Authorization: Bearer <KEY>" -H "Content-Type: application/json" \
  -d '{"plan":"growth","success_url":"https://app.acme.example/ok","cancel_url":"https://app.acme.example/cancel"}'
# → { "url": "https://checkout.stripe.com/..." }

# Open the Stripe Billing Portal (requires a prior checkout)
curl -X POST http://localhost:8080/v1/billing/portal \
  -H "Authorization: Bearer <KEY>" -H "Content-Type: application/json" \
  -d '{"return_url":"https://app.acme.example/billing"}'

Checkout and the portal require STRIPE_SECRET_KEY (and the STRIPE_PRICE_* ids) to be configured; without them these routes return 503 service_unavailable while the plan catalog stays public. Enforcement is on the control-plane write path only — never on the edge ask hot path, so serving traffic never blocks on billing.

On this page