Better Enrollment

The invite page

One page and one redeem call handle every invite kind.

Every invitation link points at the same page, carrying only ?token=. The invitee never needs to know what kind of invite they hold.

const { data: invite } = await authClient.invite.get({ token });

Rendering by nextAction

invite.nextActionMeaningWhat to render
SIGN_UPInvite-only, no sessionThe fields listed in requiredFields
SIGN_INOpen mode, no sessionYour sign-in form; keep the token in the URL
CONFIRMOpen mode, session presentA single confirm button
nullExpired, revoked, or consumedA clear terminal message

requiredFields lists exactly what to collect: always password for sign-up, plus email for public invites, plus organizationName and organizationSlug for org-create.

What your page will see

Invitees have no account, so live invites always return nextAction: "SIGN_UP": your page is a sign-up form driven by requiredFields. You only ever handle two states, SIGN_UP and null.

Redeeming

Submit everything to one endpoint:

await authClient.invite.redeem({
  token,
  password,
  name,
  email,
  organizationName,
  organizationSlug
});
// -> { status: "ACCEPTED", user, organization? }

redeem routes to the right semantics for the mode and kind, so your page never branches. The response says what happened, so you can render "You joined Acme" or "Your organization is ready".

A deliberately thin payload

invite.get returns only kind, role, derived status, expiry, uses remaining, and a masked email such as a***@example.com. Never the inviter's identity or internal ids.

Last updated on

On this page