Admin / Access codes admin only

Access codes

One feature across two surfaces: mint a code in the room (App), manage and audit every code in the Console. Both call the same role-gated endpoint — the logic lives once on the backend, never in either frontend.

Always lands them in their own workspace — never yours. Entitlements apply to their org. This is not the org invite.
App · in the room
The lean surface, open with the prospect: configure & mint, hand the code over. Nothing else — no list, no audit.
Console · management
The full surface: every issued code, who minted what, revoke, ceilings & policy. The oversight, out of the room.
App · in the room Mint and hand over — the act, in the moment.
Configure the codein-room
Skip the access gate
Registers without the waitlist — instant beta access, their own org.
Enroll in Loop
Adds a Loop membership (joined via demo). Early-access program perks.
Extended Pro trial
Time-boxed Pro on their personal org.
30 days
Rides the code → seeds their onboarding. Their words, carried forward.
Configure a code and issue it — the code to hand over, and exactly what it grants, appears here.
POST /api/admin/v1/access-codes · the one function both surfaces call
Console · management Same endpoint, fuller view — list, audit, revoke, policy.
Trial ceiling90 days max · server-enforced
Who can mintplatform_admin (audited)
Defaultsingle-use · 14-day expiry
Issued codes audit · who minted what
CodeGrantsUse caseMinted byState
ACS-K7M2 gatepro 30d Shopify ops — 3 agents, context dies erik@relayctx.com redeemed
ACS-T2HF gatelooppro 14d Dev infra eval — PR review handoffs erik@relayctx.com issued
Concept — settled design, not yet built. App & Console share one backend. The App already calls /api/admin/v1 in prod (the Applicants screen), so the in-room "Issue code" is the same role-gated endpoint the Console mint form uses — auth is the session JWT (Bearer or relay_jwt cookie), gated by role, not by which frontend called it. The mint/list/revoke logic lives once in a service; both surfaces are thin clients. An access code is a beta_codes row, extended with grant_loop, trial_days, use_case, source='demo', minted_by; activation (beta_service) reads the code instead of hardcoding beta — sets tier, optionally create_loop_membership(joined_via='demo') + set_user_trial — and logs the redemption (pre-cleared + audited). Safety invariant: every grant lands on the prospect's own org; never the rep's (the line vs the removed org-invite embed, #298). Now integrated: the App’s in-room mint and the Console management surface. This page stays as the one-screen explainer of the split. Entitlement policy governed by SPEC.org-plan-model.md in relay-board.