thenetbotz/email-validator

Laravel package to validate emails using syntax, MX, disposable-domain and SMTP handshake checks.

Maintainers

Package info

github.com/The-NetBotz/email-validator

pkg:composer/thenetbotz/email-validator

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-06-02 19:58 UTC

This package is auto-updated.

Last update: 2026-06-02 20:04:31 UTC


README

A Laravel package that validates email addresses through four progressively stricter layers: syntax → disposable-domain check → MX lookup → SMTP RCPT-TO handshake (with catch-all detection).

No paid API. Works on PHP 8.1+ and Laravel 10/11/12.

Install

composer require thenetbotz/email-validator

Publish the config and disposable-domain list (optional):

php artisan vendor:publish --tag=email-validator-config
php artisan vendor:publish --tag=email-validator-resources

Usage

Facade

use Thenetbotz\EmailValidator\Facades\EmailValidator;

$result = EmailValidator::validate('jane.doe@example.com');

$result->valid;   // bool
$result->reason;  // 'valid' | 'invalid_syntax' | 'no_mx_record' | 'disposable_domain' | 'smtp_rejected' | 'smtp_unreachable' | 'catch_all'
$result->checks;  // ['syntax' => true, 'mx' => true, 'disposable' => true, 'smtp' => true]
$result->message; // server response or null

Dependency injection

use Thenetbotz\EmailValidator\EmailValidator;

public function store(Request $r, EmailValidator $validator) {
    $result = $validator->validate($r->input('email'));
}

As a validation rule

use Thenetbotz\EmailValidator\Rules\ValidEmail;

$request->validate([
    'email' => ['required', new ValidEmail()],
]);

// Reject catch-all domains too:
$request->validate([
    'email' => ['required', new ValidEmail(allowCatchAll: false)],
]);

Batch CSV validation

php artisan email:validate emails.csv --out=results.csv
php artisan email:validate emails.txt --skip-smtp

Configuration

config/email-validator.php:

'checks' => [
    'syntax'     => true,
    'mx'         => true,
    'disposable' => true,
    'smtp'       => true,
],

'smtp' => [
    'timeout'    => 10,
    'port'       => 25,
    'helo_host'  => env('EMAIL_VALIDATOR_HELO', 'localhost'),
    'from_email' => env('EMAIL_VALIDATOR_FROM', 'verify@example.com'),
],

'cache' => [
    'enabled' => true,
    'ttl'     => 86400,
],

Accuracy & speed

Layers enabled Accuracy Speed (sequential)
Syntax only ~50% 100k+/sec
Syntax + MX ~70% ~5k/min
Syntax + MX + Disposable ~75% ~5k/min
All layers (incl. SMTP) ~85–95% ~500–2,000/hour

Caveats:

  • Many ISPs and cloud providers block outbound port 25. Run from a server with port 25 open.
  • Gmail/Outlook/Yahoo intentionally accept any address to prevent enumeration — SMTP can't disprove existence on them.
  • Catch-all domains accept everything; the package flags these via REASON_CATCH_ALL.
  • Aggressive probing can get your IP blacklisted. Cache results (enabled by default).

Testing

composer install
vendor/bin/phpunit

License

MIT