Tutorial · PHP & Laravel

Validate email addresses in PHP

PHP has email validation built in, but it stops at the format. Here is how to go all the way to a mailbox check.

Updated October 1, 2026 · 2 min read

Validating an email address in PHP with filter_var and FILTER_VALIDATE_EMAIL

1. Format check with filter_var

$email = trim($_POST['email'] ?? '');

if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
    exit('Please enter a valid email address.');
}

2. Does the domain accept email?

$domain = substr(strrchr($email, '@'), 1);
if (!checkdnsrr($domain, 'MX') && !checkdnsrr($domain, 'A')) {
    exit('This email domain does not exist.');
}

3. Check the mailbox with the API

function validate_email_api(string $email): array {
    $ch = curl_init('https://api.emailvalidation.io/v1/info?email=' . urlencode($email));
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => ['apikey: ' . getenv('EMAILVALIDATION_KEY')],
    ]);
    $body = curl_exec($ch);
    curl_close($ch);
    return json_decode($body, true) ?? [];
}

$result = validate_email_api($email);
if (($result['state'] ?? '') === 'undeliverable' || !empty($result['disposable'])) {
    exit('Please use a valid, permanent email address.');
}

Laravel

$request->validate([
    'email' => ['required', 'email:rfc,dns', function ($attribute, $value, $fail) {
        try {
            $r = Http::withHeaders(['apikey' => config('services.emailvalidation.key')])
                ->timeout(10)
                ->get('https://api.emailvalidation.io/v1/info', ['email' => $value])
                ->json();
        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            return; // API not reachable in time: let the address through
        }
        if (($r['state'] ?? null) === 'undeliverable' || ($r['disposable'] ?? false)) {
            $fail('Please use a valid, permanent email address.');
        }
    }],
]);

If the API can’t be reached in time, the catch lets the address through rather than blocking the sign-up.

WordPress: WooCommerce and Gravity Forms

The same API call works inside WordPress plugins. For shops, WooCommerce email verification at checkout adds it to both the classic checkout and the Checkout block; for contact and lead forms, the Gravity Forms email validation filter shows an error on the Email field before the entry is saved.

Validate email in other languages

Frequently asked questions

Is filter_var FILTER_VALIDATE_EMAIL enough?

It is a solid format check, but it accepts addresses on domains that do not exist and mailboxes that were never created. Combine it with an MX check and, for sign-ups and imports, an API check.

How do I validate email DNS in Laravel?

Use the rule email:rfc,dns. It checks the format and that the domain has DNS records, but not whether the mailbox exists.

Email validation API

Validate emails in your app

emailvalidation.io checks syntax, MX records and the mailbox over SMTP, flags disposable, role and free addresses and returns a quality score, in one request.

/v1/info Email validation API Read the documentation

100 free validations every month. No credit card required.

GET https://api.emailvalidation.io/v1/info?email=support@emailvalidation.io

{
  "email": "support@emailvalidation.io",
  "user": "support",
  "tag": "",
  "domain": "emailvalidation.io",
  "format_valid": true,
  "mx_found": true,
  "smtp_check": true,
  "catch_all": null,
  "role": true,
  "disposable": false,
  "free": false,
  "score": 0.64,
  "state": "deliverable",
  "reason": "low_quality",
  "did_you_mean": "",
  "catch_all_resolution": null,
  "bounce_probability": null,
  "status": "valid",
  "sub_status": "role_based",
  "explanation": "The mailbox exists, but it is a role address (such as info@ or support@), usually read by a team rather than one person.",
  "recommended_action": "send_with_caution"
}

Keep reading

Start using our email validation software today!

Get 100 validations per month for free