Skip to content
Comece com 100 créditos de verificação grátis
Qualisend
Todos os artigos
Engenharia / 12 de junho de 2026

Validar um endereço de e-mail no Laravel, da regra à caixa de entrada

7 minutes read

Qualisend team
Ilustração de um array de regras do Laravel afunilando de email:rfc para email:rfc,dns até uma regra DeliverableEmail que verifica a caixa de entrada.

Validar um endereço de e-mail no Laravel dá vontade de tratar como uma linha só — adicionar email a um array de validação e seguir em frente. Essa regra é um bom começo, mas responde apenas à primeira das três perguntas que a validação de verdade faz. O endereço tem o formato correto? O domínio dele consegue receber e-mail? A caixa de entrada realmente existe? O Laravel é peculiar porque sua regra email nativa consegue responder às duas primeiras em uma única linha; a terceira é um problema de rede que vale a pena delegar. Este guia constrói cada camada sobre o próprio validador do Laravel e mostra exatamente onde o framework para. Ele amplia o guia de validação de e-mail em PHP: o Laravel envolve os mesmos blocos de construção do PHP — e filter_var está a uma palavra-chave de distância — em uma API muito mais agradável.

A resposta curta#

Use a regra email:rfc,dns do Laravel para a sintaxe e a consulta MX em uma única passagem e, depois, uma API de verificação para a checagem SMTP da caixa de entrada — o mais barato primeiro, encerrando cedo com bail assim que uma camada for decisiva. Não tente abrir uma sessão SMTP a partir da sua aplicação para sondar caixas de entrada por conta própria: a porta 25 de saída é bloqueada na maioria dos hosts, e a resposta depende da reputação do IP de envio e do greylisting que você não vai querer reimplementar. Cada camada elimina endereços de forma mais barata que a anterior; só a última consegue aprovar um endereço.

Camadas 1 e 2: sintaxe e DNS em uma só regra#

A regra email é sustentada pelo pacote egulias/email-validator, e ela aceita estilos que decidem o quão rígida ela é. Por padrão, aplica o estilo rfc (gramática das RFC 5321/5322). O estilo que importa para a validação é o dns, que adiciona uma consulta ao vivo e confirma que o domínio resolve uma rota de e-mail — um registro MX, com um registro A como alternativa. Peça os dois e o Laravel faz a sintaxe e a checagem de domínio em uma única regra:

public function store(Request $request)
{
    $validated = $request->validate([
        'email' => ['required', 'email:rfc,dns'],
    ]);

    // $validated['email'] is well-formed AND its domain can receive mail.
}

Os outros estilos vale a pena conhecer. email:filter executa o filter_var($email, FILTER_VALIDATE_EMAIL) do PHP — exatamente a checagem do guia de PHP — e filter_unicode permite algumas partes locais em Unicode. strict rejeita os avisos de ponto final e pontos consecutivos que o parser da RFC tolera. E spoof protege contra caracteres homógrafos enganosos, então, para um formulário de cadastro público, email:rfc,dns,spoof é um padrão sensato. Em um form request fica assim:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreSubscriberRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'email' => ['required', 'email:rfc,dns,spoof'],
        ];
    }
}

Por que email:rfc,dns ainda não é sinal verde#

Passar em email:rfc,dns significa que a string está bem formada e que o domínio consegue receber e-mail. Não diz nada sobre a existência daquela caixa de entrada específica. noreply-9f2x@gmail.com passa. definitely-fake@gmail.com também. Ambos são inentregáveis, porque o registro MX é um fato sobre o domínio e a caixa de entrada é um fato que você só descobre perguntando ao servidor de e-mail. Essa é a mesma parede que faz a validação de e-mail por regex falhar: nenhuma dose de correspondência de padrões, e nenhuma consulta DNS, atravessa de "o domínio aceita e-mail" para "este endereço aceita".

Se quiser ver a diferença você mesmo, cole um endereço sintaticamente perfeito no verificador de e-mail gratuito e observe uma string aprovada pela regra voltar como undeliverable.

Camada 3: a caixa de entrada realmente existe?#

Confirmar uma caixa de entrada específica significa a conversa de entrega SMTP: conectar ao host de e-mail, emitir RCPT TO, ler a resposta e desconectar antes de enviar qualquer coisa. Em princípio, você poderia programar isso em PHP, mas não deveria executá-lo a partir do seu servidor de aplicação — a maioria dos provedores de nuvem bloqueia a porta 25 de saída, a resposta depende da reputação do IP de onde você conecta, e os servidores de recebimento fazem greylisting e limitam a taxa de remetentes desconhecidos. E tem mais: como funciona a verificação de e-mail percorre o pipeline completo, incluindo domínios catch-all que aceitam todo endereço e derrotam uma sondagem ingênua. Esta é a camada que vale a pena delegar.

Chamando a Qualisend a partir de uma regra de validação personalizada#

O Laravel deixa a delegação limpa: envolva a chamada de API em um objeto de regra e coloque-o no mesmo array de regras. Gere um com o Artisan:

php artisan make:rule DeliverableEmail

Mantenha a chave fora do seu código configurando-a através de config/services.php, que a lê do seu .env:

// config/services.php
'qualisend' => [
    'key' => env('QUALISEND_API_KEY'),
],

Então a regra chama o endpoint de verificação com a facade Http, lê o envelope result e falha apenas quando o veredito é undeliverable:

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
    {
        $response = Http::withToken(config('services.qualisend.key'))
            ->timeout(10)
            ->post('https://api.qualisend.com/v1/verify', ['email' => $value]);

        // On our own outage or a rate limit, don't block a real signup.
        if ($response->failed()) {
            return;
        }

        $result = $response->json('result');

        if (($result['status'] ?? null) === 'undeliverable') {
            $fail('This email address appears to be undeliverable.');
        }
    }
}

Http::withToken() define o cabeçalho de autenticação bearer, ->post() envia o corpo JSON, e $response->json('result') extrai o objeto result aninhado com acesso por ponto. O endpoint acima é um placeholder — consulte a referência da API para a URL base e o formato de requisição exatos — mas a resposta é lida de volta assim:

{
  "result": {
    "status": "deliverable",
    "score": 95,
    "reason": null,
    "sub_flags": { "role": false, "disposable": false, "free": false, "catch_all": false }
  }
}

status é um dentre deliverable, risky, undeliverable ou unknown. A regra acima falha de forma dura apenas em undeliverable e deixa risky e unknown passarem, para que você decida mais adiante o que fazer com eles — condicionar pelo score, ou ramificar em uma entrada de sub_flags como disposable — em vez de transformar um endereço limítrofe em um erro de formulário. Trate o JSON acima como o formato, não como o contrato; a lista completa de campos vive na documentação para desenvolvedores.

Juntando as camadas para validar um endereço de e-mail no Laravel#

Componha as três em um único form request, o mais barato primeiro, e deixe o bail parar na primeira falha para que a regra de API só rode em endereços que já passaram pela sintaxe e pela checagem MX:

namespace App\Http\Requests;

use App\Rules\DeliverableEmail;
use Illuminate\Foundation\Http\FormRequest;

class StoreSubscriberRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'email' => [
                'bail',
                'required',
                'email:rfc,dns',
                new DeliverableEmail(),
            ],
        ];
    }

    public function messages(): array
    {
        return [
            'email.email' => 'Enter a valid email address on a real domain.',
        ];
    }
}

bail é o truque todo. Um endereço malformado ou um domínio inativo falha localmente e nunca gasta um crédito de API; só os endereços que valem a ida e volta pela rede chegam à camada SMTP. Faça o type-hint do request no seu controller e o Laravel roda o pipeline antes mesmo de o corpo do seu método executar:

public function store(StoreSubscriberRequest $request)
{
    // Every layer has passed — safe to persist.
    $subscriber = Subscriber::create($request->validated());

    return redirect()->route('subscribers.index');
}

É a estratificação, não o framework, que torna a validação confiável — o mesmo formato da versão em PHP, com o Laravel colapsando as duas primeiras camadas em uma só regra. Rode o pipeline síncrono rápido no cadastro e reserve a passagem mais lenta, confirmada por SMTP, para o trabalho de bastidores: o guia de cadastro serverless mostra o padrão em tempo real, e como limpar uma lista de e-mails cobre o lado do processamento em lote.

Perguntas frequentes#

A regra email do Laravel verifica se o domínio existe?#

Só se você pedir. A regra email simples valida a sintaxe com o pacote egulias/email-validator (o estilo rfc). Adicione o estilo dnsemail:rfc,dns — e o Laravel também confirma que o domínio resolve uma rota de e-mail, então um domínio inventado ou inativo falha na mesma passagem. Nenhum dos estilos contata a caixa de entrada, então uma aprovação ainda significa "com cara de entregável", não "entregável".

Qual é a diferença entre email:rfc, email:filter e email:dns?#

rfc valida contra as RFC 5321/5322 via egulias e é o padrão do Laravel. filter executa o filter_var($email, FILTER_VALIDATE_EMAIL) do PHP — exatamente a checagem do guia de PHP — enquanto filter_unicode permite algum Unicode. dns adiciona uma consulta MX ao vivo, e spoof rejeita caracteres homógrafos enganosos. Você os combina com vírgulas, então email:rfc,dns é o portão prático de sintaxe mais domínio.

Como verifico se uma caixa de entrada existe no Laravel?#

Não com uma regra nativa — a confirmação da caixa de entrada exige uma conversa SMTP que você não deveria executar a partir do seu servidor de aplicação, porque a porta 25 é amplamente bloqueada e o resultado depende da reputação do seu IP de envio. Envolva uma API de verificação em um objeto ValidationRule personalizado, chame-a com a facade Http, leia o envelope result e falhe em undeliverable. Coloque-a depois de email:rfc,dns com bail para que ela só rode em endereços que já passaram pelas camadas locais.

A regra dns vai deixar o envio dos meus formulários mais lento?#

Pode deixar. O estilo dns realiza uma consulta DNS ao vivo a cada validação, então um resolvedor lento ou inacessível trava a requisição. Tudo bem para um único formulário de cadastro, mas mantenha-o fora de importações em massa, e não o empilhe com uma chamada de API síncrona a menos que você tenha definido um timeout no cliente Http — como a regra DeliverableEmail acima faz com ->timeout(10).


Pronto para adicionar a camada da caixa de entrada? Jogue um endereço no verificador de e-mail gratuito para ver um endereço aprovado pela regra voltar como inentregável, e depois conecte o mesmo veredito à sua ValidationRule com os exemplos de copiar e colar da referência da API.

Your reputation, protected.

Clean your first list in minutes. 100 free credits, no card required.

Get started