Looking to hire Laravel developers? Try LaraJobs

laravel-email-verification maintained by misaf

Description
Provider-neutral email domain and deliverability validation for Laravel applications.
Last update
2026/09/01 11:54 (2.x-dev)
License
Downloads
28

Comments
comments powered by Disqus

Laravel Email Verification

Provider-neutral email domain and deliverability validation for Laravel applications.

Features

  • A ValidationRule that enforces an optional domain allow-list plus pluggable deliverability verification
  • Driver-based deliverability via a Laravel Manager
  • Configurable allowed domains (empty by default — no restriction)
  • Localized failure messages (en, de, fa)
  • Explicit deliverable, risky, undeliverable, and unverifiable outcomes

The core package is provider-neutral: it ships only the null driver, which performs no external check. Real deliverability verification comes from driver packages that register themselves via the manager's extend. Install the driver(s) you want — one, both, or none.

The core depends only on framework packages, so it can be reused by any Laravel application without pulling in a wider ecosystem.

Requirements

  • PHP 8.4+
  • Laravel 13

Installation

The core package is required in every case:

composer require misaf/laravel-email-verification

On its own this gives you the domain allow-list plus the null driver, which treats every address as deliverable — useful for local and testing environments, but it performs no real verification.

First-party drivers

To actually verify deliverability, add one or both driver packages. They are independent of each other and can be installed together:

composer require misaf/laravel-email-verification-emailable
composer require misaf/laravel-email-verification-bouncer
Package Driver name Provider Config file
(core) null none — always Deliverable laravel-email-verification.php
misaf/laravel-email-verification-emailable emailable Emailable laravel-email-verification-emailable.php
misaf/laravel-email-verification-bouncer bouncer Bouncer laravel-email-verification-bouncer.php

Each driver package requires the core and is listed under the core's composer suggest, so composer require misaf/laravel-email-verification will prompt you with what is available.

All service providers are auto-registered.

Publish the config to customise the allowed domains and deliverability wiring:

php artisan vendor:publish --tag=laravel-email-verification-config

The translations can be published as well, if you want to override the failure messages:

php artisan vendor:publish --tag=laravel-email-verification-translations

An install command is also available, which publishes the config and walks you through setup:

php artisan laravel-email-verification:install

Each driver package publishes its own config under a matching tag, e.g.:

php artisan vendor:publish --tag=laravel-email-verification-emailable-config
php artisan vendor:publish --tag=laravel-email-verification-bouncer-config

Using both drivers together

Both drivers register under distinct names on the same manager, so they coexist. default picks the one used when no driver is named, and any rule or facade call can override it per use:

EMAIL_VERIFIER_DRIVER=emailable

EMAILABLE_HOST=https://api.emailable.com/v1/verify
EMAILABLE_API_KEY=...

BOUNCER_HOST=https://api.usebouncer.com/v1.1/email/verify
BOUNCER_API_KEY=...
new EmailValidation();            // the configured default — "emailable" above
new EmailValidation('bouncer');   // this rule only, regardless of the default

Configuration

config/laravel-email-verification.php:

  • default — the deliverability driver name (EMAIL_VERIFIER_DRIVER). The core package provides only null; installing a driver package makes its driver name (emailable, bouncer) available here.
  • allowed_domains — the domains the rule accepts. Comparison is case-insensitive. Leave the list empty to allow any domain.
'allowed_domains' => [
    'example.com',
    'example.org',
],

Usage

use Misaf\LaravelEmailVerification\Rules\EmailValidation;

$request->validate([
    'email' => [
        'bail',
        'email:rfc,strict,spoof,filter,filter_unicode',
        new EmailValidation(),
    ],
]);

The rule is a plain ValidationRule, so it works anywhere Laravel accepts one — form requests, Validator::make(), Filament fields, and so on:

TextInput::make('email')
    ->email()
    ->rules(['bail', new EmailValidation()]);

new EmailValidation() uses the configured default driver. Pass a driver name to override per use: new EmailValidation('bouncer').

Verification Outcomes

Status Meaning Validation result
Deliverable The provider positively classified the address as deliverable Pass
Risky The address may accept mail but has deliverability or quality concerns Fail
Undeliverable The provider positively classified the address as invalid Fail
Unverifiable Verification failed or produced no reliable result Fail

The null driver performs no external verification and always returns Deliverable. Unknown provider states and provider failures must never be reported as deliverable by concrete drivers.

Verifying an address directly

use Misaf\LaravelEmailVerification\Facades\EmailVerifier;
use Misaf\LaravelEmailVerification\Enums\EmailVerificationStatus;

$status = EmailVerifier::verify('user@example.com');           // default driver
$status = EmailVerifier::driver('bouncer')->verify($email);   // specific driver

if ($status === EmailVerificationStatus::Deliverable) {
    // ...
}

Registering a custom driver

use Misaf\LaravelEmailVerification\Contracts\EmailVerifier as EmailVerifierContract;
use Misaf\LaravelEmailVerification\EmailVerifierManager;

app(EmailVerifierManager::class)->extend('my-provider', fn (): EmailVerifierContract => new MyProviderVerifier());

Testing

composer test       # Pest
composer analyse    # PHPStan / Larastan
composer format     # Pint

License

MIT. See LICENSE.