Skip to main content

Overview

The invite plugin supports two types of invitations:
  • Private invites: Sent to a specific email address with email notification
  • Public invites: Generic invitation tokens/links that anyone can use

Private invites

Private invites are sent to a specific email address. The plugin automatically determines if the user needs to create a new account or upgrade their existing role.

Basic example

const result = await authClient.invite.create({
  email: "[email protected]",
  role: "member",
});

// Result: { status: true, message: "The invitation was sent" }
You must configure sendUserInvitation in your server setup to send private invites. See Email integration.

Server-side creation

const result = await auth.api.createInvite({
  body: {
    email: "[email protected]",
    role: "admin",
  },
  headers: request.headers, // Include session cookies
});

Public invites

Public invites create a shareable token or URL that anyone can use. Useful for referral programs, open sign-ups, or sharing via social media.

Create a public invite

const result = await authClient.invite.create({
  role: "member",
  // No email = public invite
});

// Result: { status: true, message: "<token or url>" }
The message field contains either the token or complete URL, depending on your senderResponse configuration.

Get URL instead of token

const result = await authClient.invite.create({
  role: "member",
  senderResponse: "url",
});

// Result: { status: true, message: "http://localhost:3000/invite/abc123?callbackURL=..." }

Configuration options

All options from createInviteBodySchema are available:
role
string
required
The role to assign to the invited user.
role: "admin"
email
string
Email address for private invites. Omit for public invites.
tokenType
'token' | 'code' | 'custom'
Type of token to generate. Defaults to server configuration.
tokenType: "code" // Generates 6-digit code like "A1B2C3"
maxUses
number
Maximum number of times this invite can be used. Defaults to 1 for private invites, unlimited for public invites.
maxUses: 10 // Allow 10 people to use this invite
expiresIn
number
Token expiration time in seconds.
expiresIn: 7 * 24 * 60 * 60 // 7 days
redirectToSignUp
string
Where to redirect new users to create their account.
redirectToSignUp: "/auth/signup"
redirectToSignIn
string
Where to redirect existing users to sign in.
redirectToSignIn: "/auth/login"
redirectToAfterUpgrade
string
Where to redirect users after accepting the invite (when already logged in). Use {token} placeholder.
redirectToAfterUpgrade: "/dashboard?invite={token}"
shareInviterName
boolean
Whether to share the inviter’s name with the invitee.
shareInviterName: true
senderResponse
'token' | 'url'
How to return the invite to the sender (public invites only).
senderResponse: "url" // Return complete URL instead of token
senderResponseRedirect
'signUp' | 'signIn'
Default redirect type for public invites.
senderResponseRedirect: "signIn"
customInviteUrl
string
Custom invite URL template. Use {token} and {callbackUrl} placeholders.
customInviteUrl: "https://myapp.com/join?token={token}&next={callbackUrl}"

Use cases

1
Invite new team member (private)
2
await authClient.invite.create({
  email: "[email protected]",
  role: "member",
  expiresIn: 7 * 24 * 60 * 60, // 7 days
});
3
Upgrade existing user role (private)
4
await authClient.invite.create({
  email: "[email protected]",
  role: "admin",
});
6
const result = await authClient.invite.create({
  role: "member",
  senderResponse: "url",
  maxUses: 100,
  expiresIn: 30 * 24 * 60 * 60, // 30 days
});

const shareUrl = result.message;
// Share this URL on social media, email, etc.
7
Time-limited signup code (public)
8
const result = await authClient.invite.create({
  role: "member",
  tokenType: "code",
  maxUses: 1,
  expiresIn: 15 * 60, // 15 minutes
});

const code = result.message; // e.g., "A1B2C3"
// Display this code to the user

Example UI component

import { useState } from "react";
import { authClient } from "./client";

function InviteForm() {
  const [email, setEmail] = useState("");
  const [role, setRole] = useState("member");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setLoading(true);
    setError("");

    try {
      await authClient.invite.create({
        email,
        role,
      });
      alert("Invitation sent!");
      setEmail("");
    } catch (err) {
      setError(err.message || "Failed to send invitation");
    } finally {
      setLoading(false);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email address"
        required
      />
      <select value={role} onChange={(e) => setRole(e.target.value)}>
        <option value="member">Member</option>
        <option value="admin">Admin</option>
      </select>
      <button type="submit" disabled={loading}>
        {loading ? "Sending..." : "Send Invite"}
      </button>
      {error && <p className="error">{error}</p>}
    </form>
  );
}

Permission checks

The plugin respects your canCreateInvite configuration:
// Server configuration
invite({
  canCreateInvite: async ({ invitedUser, inviterUser, ctx }) => {
    // Only admins can invite admins
    if (invitedUser.role === 'admin' && inviterUser.role !== 'admin') {
      return false;
    }
    return true;
  },
})
If permission is denied, the create endpoint throws an error:
try {
  await authClient.invite.create({ email: "[email protected]", role: "admin" });
} catch (error) {
  if (error.errorCode === "INSUFFICIENT_PERMISSIONS") {
    alert("You don't have permission to create this invite");
  }
}
Private invites require sendUserInvitation to be configured on the server. Attempts to create private invites without email configuration will fail with an INTERNAL_SERVER_ERROR.

Next steps

Activating invites

Handle invitation activation flow

Email integration

Configure email sending for invitations

Build docs developers (and LLMs) love