Skip to main content
Evaly’s team invitation system allows organization owners and admins to invite collaborators via email. Invitations are token-based, secure, and have built-in expiration handling.

Sending Invitations

Owners and admins can invite new members to join their organization:
1

Create the Invitation

Specify the recipient’s email and the role they should have:
await createInvitation({
  organizationId: "org_123",
  email: "[email protected]",
  role: "admin" // or "owner"
});
2

Email Sent Automatically

An invitation email is automatically sent to the recipient with a unique invitation link.
3

Recipient Accepts

The recipient clicks the link and accepts the invitation to join your organization.

Invitation Validation

The system performs several checks before creating an invitation:

Email Format Validation

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
Emails must be valid and properly formatted.

Duplicate Prevention

The system checks:
  • Existing Members: User is not already a member of the organization
  • Pending Invitations: No pending invitation already exists for this email

Team Size Limits

Before sending an invitation, the system checks your organization’s member limit based on your subscription plan:

Free Plan

Up to 3 members

Pro Plan

Up to 10 members

Max Plan

Unlimited members
If your team has reached the member limit, you’ll receive an error with an option to upgrade your plan:
Your team has reached the maximum of 3 member(s) on your current plan.
Upgrade to add more team members.

Invitation Properties

Each invitation has the following properties:
  • Token: A unique 32-character random token for security
  • Email: The recipient’s email address (stored in lowercase)
  • Role: Either owner or admin
  • Status: pending, accepted, expired, or revoked
  • Expiration: Invitations expire after 7 days
  • Rate Limiting: Invitations can be resent once every 15 seconds

Managing Invitations

Viewing Pending Invitations

Owners and admins can view all pending invitations for their organization:
const invitations = await getPendingInvitations({
  organizationId: "org_123"
});

// Returns:
// [
//   {
//     email: "[email protected]",
//     role: "admin",
//     status: "pending",
//     inviter: { name: "John Doe", email: "[email protected]" },
//     isExpired: false,
//     createdAt: 1234567890,
//     expiresAt: 1235172690
//   }
// ]

Resending Invitations

If the recipient didn’t receive the email or the invitation expired:
await resendInvitation({ invitationId: "inv_123" });
Features:
  • Extends expiration by another 7 days from the current time
  • Sends a new email to the recipient
  • Rate limited to once per 15 seconds to prevent spam
If you try to resend too quickly, you’ll see:
Please wait X second(s) before resending the invitation

Revoking Invitations

Cancel a pending invitation before it’s accepted:
await revokeInvitation({ invitationId: "inv_123" });
Only pending invitations can be revoked. Once accepted or expired, invitations cannot be revoked.

Accepting Invitations

When a recipient receives an invitation email, they can accept it by:
1

Click the Invitation Link

The email contains a unique URL like:
https://evaly.app/invite/AbC123XyZ...
2

Log In or Sign Up

Recipients must be logged in with the email address that received the invitation.
3

Accept the Invitation

Click the accept button to join the organization.
4

Automatic Organization Switch

If you don’t have a selected organization yet, you’ll be automatically switched to the new organization.

Acceptance Validation

The system validates:
  • Token Validity: The invitation token must exist and be valid
  • Status Check: Only pending invitations can be accepted
  • Expiration: Invitation must not have expired (auto-marked as expired if time has passed)
  • Email Match: The logged-in user’s email must match the invitation email
  • Duplicate Membership: User is not already a member of the organization
Invitations must be accepted by the exact email address they were sent to. If you have multiple email addresses, make sure to log in with the correct one.

Invitation Notifications

When someone accepts an invitation and joins your organization:
  • Notification Sent: All existing organization members receive an in-app notification
  • Notification Type: MEMBER_JOINED
  • Includes: The new member’s name and email
// Automatically triggered on acceptance
await createNotification({
  organizationId,
  type: NOTIFICATION_TYPES.MEMBER_JOINED,
  metadata: {
    memberName: "Jane Smith",
    memberEmail: "[email protected]"
  }
});

Invitation Email Template

Invitation emails are sent via Plunk and include:
  • Organization name
  • Inviter’s name
  • Recipient email
  • Unique invitation link
  • Expiration notice
const inviteUrl = `${appUrl}/invite/${invitation.token}`;

const emailContent = getInvitationEmail({
  organizationName: "Acme University",
  inviterName: "John Doe",
  recipientEmail: "[email protected]",
  inviteUrl
});

Common Scenarios

Scenario 1: Inviting Multiple Team Members

const emails = [
  "[email protected]",
  "[email protected]",
  "[email protected]"
];

for (const email of emails) {
  await createInvitation({
    organizationId: "org_123",
    email,
    role: "admin"
  });
}

Scenario 2: Promoting an Admin to Owner

Invitations are only for new members. To change an existing member’s role, use:
await updateMemberRole({
  organizerId: "organizer_456",
  newRole: "owner"
});

Scenario 3: Re-inviting a Former Member

If someone left the organization, you can send them a new invitation. Their old organizer record is soft-deleted, and accepting creates a new one.

Best Practices

1

Double-Check Email Addresses

Verify email addresses before sending invitations to avoid sending to wrong recipients.
2

Set Appropriate Roles

Only grant owner role to members who truly need full administrative control.
3

Monitor Pending Invitations

Regularly review and revoke stale invitations that haven’t been accepted.
4

Communicate with Recipients

Let team members know they’ll receive an invitation email to avoid it being missed or marked as spam.
5

Plan Your Team Size

Be aware of your plan’s member limit and upgrade if needed before inviting.

Build docs developers (and LLMs) love