The tables the plugin creates, every column, and how they are indexed.
Better Enrollment adds two tables, invite and inviteUse, and extends the organization plugin's organization table when org features are enabled. Run npx @better-auth/cli generate after installing to add them to your schema.
One row per invitation. Status is only ever pending, accepted, or cancelled; expired is derived from expiresAt at read time, so there is no cron and nothing to sweep.
Tableinvite
Field
Type
Key
Description
id
string
PK
Unique identifier for each invite
type
string
-
Delivery type: "private" (email-bound, single use) or "public" (shareable link)
kind
string
-
What redeeming grants: "app", "org-join", or "org-create". Defaults to "app"
email ?
string
-
Address a private invite is bound to; null for public invites. Indexed
name ?
string
-
Optional display name for the invitee
role
string
-
Role merged into the user on redemption
tokenHash
string
UQ
Hash of the invite token; the raw token is never stored
status
string
-
"pending", "accepted", or "cancelled". "expired" is derived from expiresAt and never stored. Indexed
mode
string
-
Mode the invite was created for: "invite-only" or "open"
organizationId ?
string
-
Organization an org-join invite adds the invitee to. Plain column, no FK: accepted invites survive org deletion as audit records. Indexed
organizationRole ?
string
-
Role granted inside the organization on join
teamId ?
string
-
Team the invitee is added to, when the org plugin uses teams
presetSeatLimit ?
number
-
Seat limit applied to the organization founded through an org-create invite
preCreatedUserId ?
string
-
Shell user pre-created for a private invite; claimed by the invitee on accept
createdByUserId ?
string
-
User who created the invite. Plain column, no FK: the record outlives the inviter. Indexed
inviterName
string
-
Denormalized inviter name, kept for display and audit
inviterEmail
string
-
Denormalized inviter email, kept for display and audit
expiresAt ?
date
-
Expiry timestamp; null means the invite never expires. Indexed
maxUses ?
number
-
Redemption cap for public invites; null means unlimited
The schema indexes email, organizationId, tokenHash (unique), status, expiresAt, and createdByUserId. If your invite table grows into the millions, consider adding composite indexes (email, status) and (organizationId, status) in your own migrations; Better Auth's schema DSL only expresses single-column indexes.