DhokoAuthaz
DocumentationAPI Reference
  • Get Started

    • Authaz
    • Core Concepts
    • Set up your app
    • Quickstart — cURL
  • Authentication

    • Authentication Settings
    • Signup
    • Invitations
    • Password Authentication
    • Multi-Factor Auth
    • Magic Link
    • OAuth / Social Login
    • Passkey (WebAuthn)
    • SAML SSO
    • Machine-to-Machine (M2M)
    • API Keys
  • Authorization

    • Authorization
    • Resources
    • Policies
    • Roles
    • Access Explorer
  • Tenancy

    • Multi-tenancy
    • Tenancy Customization
  • Brand & Host

    • Branding
    • Custom Domains
    • Communications & Email Templates
  • Operate

    • Users
    • Analytics
    • Audit Logs
    • Application Settings
  • SDK Quickstarts

    • Quickstart — Next.js
    • Quickstart — React SPA
    • Quickstart — Hono
    • Quickstart — .NET (Authaz.Sdk)
  • Recipes

    • Recipes & Cookbook
    • Next.js — first integration
    • Next.js — B2B SaaS (multi-tenant)
    • Hono — first integration
    • Hono — B2B SaaS (multi-tenant)
    • React SPA — first integration
    • React SPA — B2B SaaS (multi-tenant)
    • .NET — first integration
    • .NET — B2B SaaS (multi-tenant)
  • Reference

    • Tokens
    • API Reference
    • Errors & Troubleshooting
  • Documentation

    • How Authaz is Built
  1. Authaz
  2. Docs
  3. Authentication
  4. Invitations

Authentication

Invitations

3 min read·Updated May 7, 2026

The Invitations card under Application → Authentication lets you (or your customers' admins) onboard users by email. The user clicks the link, sets up their account, and lands inside the application with whatever roles you pre-assigned.

curl -X POST https://your-app.authaz.io/api/v1/invitations \
  -H "X-API-Key: $AUTHAZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newhire@yourcompany.com",
    "roleIds": ["role_member"],
    "metadata": { "department": "Engineering" }
  }'
{
  "id": "inv_01h...",
  "email": "newhire@yourcompany.com",
  "status": "pending",
  "expiresAt": "2026-05-13T15:30:00Z",
  "invitedBy": "user_01h..."
}
Previous
Signup
Next
Password Authentication

Where it lives#

Dashboard → Application → Users → Invite Users (or Pending Invitations to see what's outstanding). The Authentication tab also surfaces an Invitations card so you can configure the email template and expiry policy.

Sending invitations#

From the dashboard#

Users → Invite Users opens a form: email address(es), roles, optional metadata. Multiple addresses are allowed — Authaz sends one email per address.

From the API#

# Single invitation
curl -X POST https://your-app.authaz.io/api/v1/invitations \
  -H "X-API-Key: $AUTHAZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newhire@yourcompany.com",
    "roleIds": ["role_member"],
    "expiresInDays": 7
  }'

Tenant-scoped invitations#

In multi-tenant apps, invitations belong to a tenant. Use the tenant-scoped path:

curl -X POST https://your-app.authaz.io/api/v1/applications/{appId}/tenants/{tenantId}/invitations \
  -H "X-API-Key: $AUTHAZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newhire@yourcompany.com",
    "roleIds": ["role_member"]
  }'

The user is added to that tenant only, with the listed roles scoped to it.

Configuration#

SettingWhat it controls
EnabledMaster switch. Disable to prevent any new invitations from being sent (existing pending ones still work).
Default expirationHow long an invitation link remains usable. Default 7 days.
Allow re-invitationIf true, you can invite the same email again before the previous one expires (creates a fresh code).
Email templateThe Authaz Sign-In template used. Customize copy, branding, CTA text. See Communications.

Listing invitations#

# List all
curl https://your-app.authaz.io/api/v1/invitations \
  -H "X-API-Key: $AUTHAZ_API_KEY"
 
# Filter by status
curl 'https://your-app.authaz.io/api/v1/invitations?status=pending' \
  -H "X-API-Key: $AUTHAZ_API_KEY"
 
# Pending count for the dashboard badge
curl https://your-app.authaz.io/api/v1/invitations/pending-count \
  -H "X-API-Key: $AUTHAZ_API_KEY"

Statuses you'll see:

StatusMeaning
pendingEmail sent, waiting for the user to click the link.
acceptedUser completed signup. The user record now exists.
expiredThe link expired before the user used it.
revokedAn admin canceled the invitation before it was used.

Resending and revoking#

# Resend (regenerates the code, restarts the expiration clock)
curl -X POST https://your-app.authaz.io/api/v1/invitations/{invitationId}/resend \
  -H "X-API-Key: $AUTHAZ_API_KEY"
 
# Revoke
curl -X DELETE https://your-app.authaz.io/api/v1/invitations/{invitationId} \
  -H "X-API-Key: $AUTHAZ_API_KEY"

Resend is the same UX as "they didn't get the email" — and it's a fresh signed code, so the old link from the original email becomes invalid the moment you resend.

What happens when the user clicks#

  1. The link opens Authaz Sign-In at /auth/invitation?code=….
  2. Authaz looks up the invitation; if it's pending and unexpired, it shows the signup form pre-populated with the email (and locked).
  3. The user picks a password (or a passkey / OAuth provider — whatever's enabled for the application).
  4. Authaz creates the user, assigns the roles from the invitation, marks the invitation accepted, and signs them in.
  5. They land on the application's afterLogin URL.

Invited users skip the email-verification step — being on the receiving end of the invitation email already proves they control the address.

Customizing the email#

The invitation template lives in Communications → Email Templates → Invitation. Available variables:

  • {{appName}} — your application's display name
  • {{inviterName}} / {{inviterEmail}} — who sent the invitation
  • {{inviteLink}} — the one-time URL
  • {{expiresInDays}} — invitation lifetime
  • {{customMessage}} — optional message passed in the API call (useful for onboarding context)

See Communications for the full template editor.

Bulk invitations#

For onboarding many users at once:

const invitations = [
  { email: "alice@acme.com", roleIds: ["role_admin"] },
  { email: "bob@acme.com",   roleIds: ["role_member"] },
  { email: "carol@acme.com", roleIds: ["role_member"] },
];
 
await Promise.all(invitations.map((inv) =>
  fetch("https://your-app.authaz.io/api/v1/invitations", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.AUTHAZ_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(inv),
  })
));

Authaz rate-limits invitation sends per application — the dashboard surfaces "Pending invitations" and "Sent today" counts so you can see what's piling up.

Next steps#

  • Signup — for the open self-serve path.
  • Communications — branding the invitation email.
  • Users — what happens after they accept.