> ## Documentation Index
> Fetch the complete documentation index at: https://docs.auction-rise.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Invitations

> Token-based team invitations with email delivery, auto-verification, and accept/decline flows.

# Invitations

Workspace owners and admins can invite users by email. Invitations are token-based, delivered via Resend, and support both new and existing accounts.

## Sending an Invitation

Only **owners** and **admins** can invite members. From the workspace Members settings page, click **Invite Member**, enter an email address, choose a role, and submit.

The `InviteMemberModal` component calls the `createInvitation` server action which:

1. Generates a secure token and stores the invitation in the `invitations` table.
2. Sends an invitation email via Resend with an acceptance link.

## Accepting an Invitation

The acceptance page lives at `/invitations/accept?token=...`.

The flow detects whether the invitee has an existing account:

* **Existing account** — shown a "Sign in to accept" CTA. After login, the invitation is auto-accepted and they are added to the workspace.
* **New account** — shown a "Create account to accept" CTA. The registration form pre-populates their email. After registration, their email is **auto-verified** (no second verification email) and they are signed in and added to the workspace immediately.

<Note>
  Auto-verification uses `auth.admin.updateUserById()` via the admin Supabase client, called in `autoVerifyInvitedUser()` in `lib/invitations/server-utils.ts`.
</Note>

## Invitation Status Lifecycle

| Status     | Meaning                            |
| ---------- | ---------------------------------- |
| `pending`  | Sent, not yet acted on             |
| `accepted` | User accepted and joined workspace |
| `declined` | User declined the invitation       |
| `expired`  | Token passed its expiry window     |

## Global Invitation Banner

The `GlobalInvitationBanner` component renders in the authenticated layout for all pages. It self-fetches on mount by calling `getMyInvitations()` and renders `PendingInvitationBanner` if any pending invitations exist, allowing users to accept or decline without navigating away.

## Server Actions

```typescript theme={null}
import {
  createInvitation,
  getMyInvitations,
  acceptInvitation,
  declineInvitation,
  cancelInvitation,
} from "@/lib/invitations/actions";
```

## Email Delivery

Invitation emails are sent via the Resend SDK (direct send, not via SMTP relay). Requires `RESEND_API_KEY` and `RESEND_FROM_EMAIL` to be set.

## Environment Variables

| Variable              | Required | Description                       |
| --------------------- | -------- | --------------------------------- |
| `RESEND_API_KEY`      | Yes      | Resend API key for sending emails |
| `RESEND_FROM_EMAIL`   | Yes      | Verified sender address           |
| `NEXT_PUBLIC_APP_URL` | Yes      | Base URL used in invitation links |
