Laravel email verification

Verify emails in Laravel at registration

Wire Verifly into your Laravel app with a small service and a custom validation rule. Undeliverable, disposable, and role addresses get rejected on the register form before a user record is ever created.

Verify an email from LaravelAPI
$response = Http::withToken(config('services.verifly.key'))
    ->get('https://verifly.email/api/v1/verify', ['email' => $email]);

$verdict = $response->json('result'); // deliverable | undeliverable | risky

Real-time SMTP mailbox checks

Single, batch, and async bulk verification

Disposable, role account, and catch-all detection

Pay-as-you-go credits with no subscription lock-in

Search fit

Built for Laravel email verification

Use Verifly when you need a simple API, predictable pricing, and clean JSON results before emails hit your product, CRM, or campaign tool.

Reject undeliverable emails on the Laravel register form request
Block disposable and role addresses before they reach your users table
Verify inside a FormRequest so the error attaches to the email field
Batch-clean an existing users table with an artisan command

Why Laravel's built-in email rule is not enough

Laravel ships with two email validators. The plain email rule only checks that a string looks like an address, and email:dns confirms the domain has an MX record. Neither one tells you whether the specific mailbox actually exists. A registrant can type a syntactically perfect address at a real domain that will hard-bounce every welcome email, password reset, and receipt you send.

When those bounces pile up, your sending domain's reputation drops with Gmail, Outlook, and the rest, and even your legitimate transactional mail starts landing in spam. Signup forms are also a favorite target for disposable inboxes and abuse, so filtering throwaway domains at the door keeps your database clean and your metrics honest.

Verifly runs a live SMTP mailbox check and returns a deliverable / undeliverable / risky verdict plus disposable, role, and catch-all flags. Because it is a plain HTTP GET, it drops naturally into a Laravel service class, a FormRequest rule, or a queued job. You bring your API key, Laravel does the rest.

Add a custom validation rule that rejects undeliverable emails

  1. Grab a free Verifly key at verifly.email/api/v1/autonomous/register — 100 credits, no card, no captcha.
  2. Add VERIFLY_API_KEY to your .env and expose it under config/services.php as services.verifly.key.
  3. Create an invokable rule with php artisan make:rule DeliverableEmail and call Verifly inside it using the Http facade.
  4. Attach the rule to the email field in your registration FormRequest so the failure shows up as a normal validation error.
  5. Optionally treat risky / catch-all as a soft pass and only hard-reject undeliverable, depending on how strict you want signup to be.
app/Rules/DeliverableEmail.php
<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Http;

class DeliverableEmail implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $res = Http::withToken(config('services.verifly.key'))
            ->timeout(15)
            ->get('https://verifly.email/api/v1/verify', ['email' => $value]);

        if ($res->failed()) {
            return; // fail open: don't block signup on a verifier outage
        }

        $data = $res->json();

        if (($data['result'] ?? null) === 'undeliverable' || ($data['disposable'] ?? false)) {
            $fail('Please use a real, deliverable email address.');
        }
    }
}

Use the rule inside a FormRequest

Referencing the rule from a FormRequest keeps the check off your controller and lets Laravel's validator attach the error straight to the email field, so your Blade or Inertia form renders it like any other message. Fail-open on a verifier outage is deliberate: a temporary API hiccup should never lock legitimate users out of registration.

app/Http/Requests/RegisterRequest.php
public function rules(): array
{
    return [
        'name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'email:rfc,dns', 'unique:users', new \App\Rules\DeliverableEmail()],
        'password' => ['required', 'confirmed', 'min:8'],
    ];
}

FAQ

Frequently asked questions

Does this replace Laravel's email:dns rule?

No — keep email:rfc,dns as a cheap first pass that rejects malformed strings and dead domains for free. The Verifly rule runs after it and adds the live mailbox check that DNS validation cannot do, so you only spend a credit on addresses that already look plausible.

Will a Verifly outage block all my signups?

Only if you want it to. The example rule fails open: if the HTTP call errors or times out, it returns without adding a validation error, so registration still works. You can flip that to fail-closed if a verified email is mandatory in your flow.

Should I reject risky and catch-all addresses too?

That is a product decision. Catch-all domains accept mail for any address, so no verifier can confirm a specific mailbox. Many Laravel apps only hard-reject undeliverable plus disposable and let risky through with a flag stored on the user record.

How do I verify emails already in my users table?

Write an artisan command that pulls addresses in chunks and posts them to POST /verify/batch, then mark or soft-delete the undeliverable rows. Verifly's bulk pipeline handles large lists in a single async job.

What does it cost to verify Laravel signups?

Pricing is pay-as-you-go from $2 per 1,000 checks down to $0.60 per 1,000 at volume, with 100 free credits to start and no monthly minimum, so a low-traffic app pays only for the signups it actually receives.

Can I run the check in a queued job instead of inline?

Yes. If you don't want to add latency to the register request, accept the signup, dispatch a queued job that calls Verifly, and flag or disable the account asynchronously if the address comes back undeliverable.