Skip to main content

Introduction

Email verification is a mechanism for confirming that a user actually owns the email address they registered with. Laravel provides sending and verifying confirmation emails out of the box, so you can build a secure authentication flow with minimal implementation.
If you use a starter kit, the authentication screens and email verification flow are already built in. If you implement it manually, follow the steps on this page to define the models, routes, and views yourself.

Preparing the model and database

Implement MustVerifyEmail

Make sure App\Models\User implements Illuminate\Contracts\Auth\MustVerifyEmail.
Once you add this interface, a confirmation email is automatically sent to newly registered users. If you implement registration without a starter kit, fire the Registered event after successful registration.

Verify the email_verified_at column

You need an email_verified_at column on the users table. It is typically included in the default 0001_01_01_000000_create_users_table.php migration.

Routing (three routes)

Email verification defines three routes: verification.notice, verification.verify, and verification.send.
1

Define the verification notice route (verification.notice)

Returns a screen telling unverified users to “please check your email.”
2

Define the verification handler route (verification.verify)

When the user clicks the link in the email, this validates the signed URL and completes verification.
3

Define the resend route (verification.send)

Resends the confirmation email if the user loses it.

Protecting routes

To grant access only to verified users, use the verified middleware. It is typically combined with auth.
When an unverified user visits the route, Laravel automatically redirects them to verification.notice.

Customization

To customize the verification email body, set VerifyEmail::toMailUsing in the boot method of your AppServiceProvider.

Events

The Illuminate\Auth\Events\Verified event is fired when email verification occurs. Starter kits handle this automatically, but for manual implementations, add event handling as needed.
Last modified on July 13, 2026