These tables are created and managed by Better Auth. Do not modify their
structure directly.
| Table | Purpose |
|---|
user | Global identity: id, email, name, image |
session | Login sessions: token, userId, expiresAt |
account | Linked provider accounts: google, apple, credential |
verification | Email verification, magic link tokens |
jwks | RSA key pairs for JWT signing |
oauth_client | OAuth client registrations |
oauth_access_token | Issued access tokens |
oauth_refresh_token | Issued refresh tokens |
oauth_consent | User consent records |
organization | B2B organizations |
member | Organization members |
invitation | Organization invitations |
| Column | Type | Description |
|---|
| id | text PK | Application identifier (e.g. tobby) |
| name | text | Display name |
| oauth_client_id | text UNIQUE | FK to oauth_client.id |
| audience | text | JWT audience claim value |
| webhook_url | text? | Event webhook URL (Phase 3) |
| webhook_secret | text? | Webhook signing secret |
| status | text | active or suspended |
| auth_policy | jsonb | Per-application account policy |
| created_at | timestamptz | |
| updated_at | timestamptz | |
| Column | Type | Description |
|---|
| id | text PK | |
| app_id | text FK | References application.id |
| user_id | text FK | References user.id |
| status | text | active, suspended, disabled, pending_approval |
| role | text | member, admin, billing_admin |
| display_name | text? | Per-application display name |
| avatar_url | text? | |
| profile | jsonb | Per-application custom fields |
| invited_by | text? | Inviting user id |
| first_seen_at | timestamptz | |
| last_active_at | timestamptz? | |
Unique constraint: (app_id, user_id)
| Column | Type | Description |
|---|
| id | text PK | |
| app_id | text FK | |
| email | text | Invited email address |
| invited_by | text | |
| role | text? | Default: member |
| token | text UNIQUE | Invitation token |
| expires_at | timestamptz | |
| status | text | pending, accepted, expired, cancelled |
| message | text? | Optional invitation message |
| Column | Type | Description |
|---|
| id | text PK | |
| app_id | text FK | |
| name | text | Human-readable identifier |
| key_prefix | text | First 8 characters of the plaintext key |
| key_hash | text | SHA-256 hash of the key |
| scopes | text[] | Permission scopes |
| expires_at | timestamptz? | |
| last_used_at | timestamptz? | |
| created_at | timestamptz | |
| Column | Type | Description |
|---|
| id | text PK | Group identifier |
| name | text | Display name |
| created_at | timestamptz | |
| Column | Type | Description |
|---|
| group_id | text FK | References sso_group.id |
| app_id | text FK | References application.id |
Primary key: (group_id, app_id).
allowed_providers: string[]; // "email", "google", "apple"
| "auto_on_first_access";
require_uppercase: boolean;
expiry_days: number | null;
max_concurrent: number | null;
idle_timeout_minutes: number | null;
require_email_verification: boolean;
allowed_email_domains: string[];
blocked_email_domains: string[];
required_profile_fields: string[];