Inviting users — a typical B2B pain point
In closed B2B products, access control is critical: a new user must land in their own organization with the correct role from the start. We have implemented dozens of such flows — from simple links to complex workflows with confirmations. The key is proper edge case handling: duplicates, expired links, email changes. We often encounter a situation where an invitation is sent to a corporate email, but the user is already registered with a personal one — requiring account merging. Or when an admin wants to revoke an invitation after sending. Our experience (over 10 years and 40+ projects implementing authentication) shows that a standard implementation without considering these nuances leads to bugs and client complaints.
How to implement a secure email invitation?
The main approach is generating a unique token stored in the database with an expiration time. In our stack, we use Prisma ORM for the data schema and Next.js Server Actions for server logic. The basic invitation model includes email, role, token, status, and expiration date. Statuses — PENDING, ACCEPTED, EXPIRED, REVOKED — are changed automatically or manually by the admin.
| Status | Description |
|---|---|
| PENDING | Invitation sent, awaiting acceptance |
| ACCEPTED | User accepted and added to the organization |
| EXPIRED | Validity period expired (default 7 days) |
| REVOKED | Revoked by admin before acceptance |
The token is generated as a random string using crypto.randomUUID() and hashed before storage. Upon acceptance, we check not only its existence but also the 'PENDING' status and expiration date. If the token has expired, the invitation is automatically marked 'EXPIRED'. To prevent reuse after acceptance, the token is deleted or set to 'ACCEPTED'.
Typical problems when implementing invitations
- Duplicates: if a user sends multiple invitations to the same email, the system should either ignore or update the previous one. We use a unique constraint on email within the organization.
- Email change: a user may accept an invitation with a different email — verification is needed. In our flow, we require confirming the new email before acceptance.
- Link expiration: lifetime defaults to 7 days, but can be configured per client requirements. After expiration, we show a page offering to request a new invitation.
- Role model: at invitation creation, a role is specified (OWNER, ADMIN, MEMBER, VIEWER). After acceptance, the user is added to the organization with that role. The admin can change the role afterwards.
Why invitations beat open registration?
Open registration in B2B creates chaos: anyone can sign up, requiring manual organization assignment. Link-based invitations provide security and automation: the user gets a role immediately, the organization is fixed, and the admin has a history. This approach reduces support workload by 2–3 times.
Comparison of registration methods
The choice between open registration and invitation depends on requirements. Open registration is easier for the user but requires administrative work for organization and role assignment. Email invitation with confirmation is reliable but multi-step. Link-based invitation is the sweet spot: secure, automated, convenient for admin and user. In our experience, companies that switch from open registration to invitations reduce employee onboarding time by 70%.
What’s included in the work
- Analysis of the role model and data schema.
- Design and implementation of the Invitation model in Prisma.
- Development of Server Actions for sending and accepting invitations.
- Creation of email templates in React Email with branding support.
- Integration with an email service (Resend/SendGrid) and webhook setup.
- Acceptance page with edge case handling (expired token, reuse).
- Unit tests (status checks, validation) and integration tests for the full flow.
- API documentation and admin instructions.
- Support for 30 days after deployment.
Work process: from task to deployment
- Analytics — define roles, data schema, security requirements. Collect use cases and edge cases.
- Design — Invitation model in Prisma, stack selection (Next.js, React Email, Resend). Design API endpoints via Server Actions.
- Implementation — write Server Actions for sending and accepting invitations, create email templates in React Email, develop the token-based acceptance page.
- Testing — unit tests for validation (e.g., status checks, expiration), integration tests for the full flow (send to accept).
- Deployment — environment variables (Resend/SendGrid keys, database), monitoring delivery via webhooks.
Our experience and guarantees
We have implemented similar systems for 15+ B2B products on Next.js and Laravel. We guarantee stable operation, compliance with Core Web Vitals, and flow documentation. Our experience with email services ensures delivery without spam filters. We also provide a 30-day warranty on the implemented code after deployment.
Timelines and cost
Implementation of a typical invitation flow with email and edge case handling takes 3 to 5 business days. Cost is calculated individually — depends on the complexity of the role model, need for external service integration, and additional requirements.
How to start?
Contact us — we will evaluate your project and suggest the optimal solution. Order a turnkey invitation system implementation. Get a ready system with tests and documentation.







