account · billing · subscription
Manage subscription
Change the plan, end it, and see who is on it — the three things a member cannot do inside Relay today.
Stub
Low-fidelity on purpose. This poses the manage half's three questions; it does not answer them. The purchase half is drawn properly at Checkout & billing profile, and the post-purchase Billing page at Billing. Do not cite this page as a design — cite the program map.
This subscription ends on 11 October 2026
Team stays fully active until then — nothing is deleted and nobody loses access before that date. On the 11th the workspace moves to the Free contract. You can turn the renewal back on any time before it.
event
billing.cancel.pending_viewed · resume → billing.cancel.resumed · audit billing.subscription.resumePlan
Team Active
$75.00
USD / month · $15 per seat
view
billing.subscription.viewed {tier, seats, status} · cancel opens a confirm step, never cancels on clickChange plan
What each plan enforces, next to what this workspace is using now.
Free
$0
USD / month
- 90 relays a month
- 1 connection
- 4,096-token context
- Kept for 30 days
Pro
$15
USD / month
- 500 relays a month
- 2 connections
- 8,192-token context
- Kept for 6 months
TeamCurrent
$15
USD / seat / month · 3-seat minimum
- 1,000 relays a month per seat
- 1 connection per seat
- 16,384-token context
- Kept for 6 months
select →
billing.plan_change.selected {from, to, blocked} · a blocked tier still emits, with the reason — a refusal nobody can see is a refusal nobody can fixSeats
| Member | Role | Seat |
|---|
What this stub is for. Three things a Relay member cannot do in the app today, each one already half-built underneath:
Record. Program map
- Cancel.
cancel_at_period_endis a realorg_billingcolumn, webhook-fed, and already returned by/billing/status— the app reads it only to tell a trial from a subscription. The ending state above is that column, drawn. Cancelling should set it, not delete anything; resuming clears it. - Change plan. Upgrade free→pro is live. Downgrade does not exist anywhere, and a downgrade that would land under current usage has no drawn behaviour — hence the guard, which states the excess rather than greying a button.
- Seats — the decision. Relay seats are derived:
sync_subscription_seatstrues the quantity to the org's member count, so a seat is a consequence of membership. The reference console assigns users to seats, which implies a member can exist without one. That is a quota-and-true-up change, not a UI preference. Switch the model above to see both.
integrations/ga4.py with ga4_event() — and zero callers; the app has no tracking
helper at all. The contract both ends must satisfy is relay-platform/docs/SPEC.billing-surface-requirements.md (audit logging,
the edge-case register, the UI event taxonomy).Record. Program map
relay-board/docs/product/subscription-management.md · purchase half
/concepts/checkout · post-purchase /concepts/app-v35/billing.html.
Deep links: ?seat=assigned · ?state=ending.