How to Detect Disposable Email Addresses in Symfony

Disposable email addresses let users register with throwaway inboxes, abuse free trials, and disappear without a trace.

For Symfony applications, the cleanest solution is a single API call at the point of registration that catches these addresses before they reach your database.

This guide shows you how to integrate Spamova's disposable email detection into a Symfony application using the HttpClient component.

What You Will Need

A Spamova API key from your account. Store it in your Symfony environment configuration - never hardcode it in your application.

In .env:

SPAMOVA_API_KEY=your_api_key_here

Checking a Single Email Address

Symfony's HttpClient component handles the API call cleanly. The /api/v1/check endpoint accepts a POST request with a single email and returns a full result object.

use Symfony\Contracts\HttpClient\HttpClientInterface;   $response = $httpClient->request('POST', 'https://spamova.com/api/v1/check', [ 'auth_bearer' => 'YOUR_API_KEY', 'json' => [ 'email' => 'james847@mailinator.com', ], ]); $result = $response->toArray();

The response looks like this:

{ "email": "james847@mailinator.com", "syntax": "valid", "is_disposable": true, "risk_score": 98, "mx": "valid", "website_status": "redirect" }

syntax catches malformed addresses before any further processing. is_disposable is the primary flag. risk_score provides a 0-100 confidence level for handling ambiguous domains that are suspicious but not yet confirmed on any list. mx validates that the domain has functioning mail infrastructure. website_status reveals whether the domain resolves to a real website, redirects elsewhere, or returns nothing.

Adding a Custom Validator Constraint

The idiomatic Symfony approach is a custom constraint and validator. This integrates cleanly with Symfony's form and validation system and can be applied to any form type or DTO.

First, create the constraint:

namespace App\Validator;   use Symfony\Component\Validator\Constraint;   #[\Attribute] class NotDisposableEmail extends Constraint { public string $message = 'Disposable email addresses are not allowed.'; }

Then create the validator:

namespace App\Validator;   use Symfony\Component\Validator\ConstraintValidator; use Symfony\Contracts\HttpClient\HttpClientInterface;   class NotDisposableEmailValidator extends ConstraintValidator { public function __construct( private HttpClientInterface $httpClient, private string $apiKey ) {}   public function validate(mixed $value, \Symfony\Component\Validator\Constraint $constraint): void { $response = $this->httpClient->request('POST', 'https://spamova.com/api/v1/check', [ 'auth_bearer' => $this->apiKey, 'json' => ['email' => $value], 'timeout' => 3, ]); $result = $response->toArray();   if (($result['is_disposable'] ?? false) || ($result['risk_score'] ?? 0) >= 70) { $this->context->buildViolation($constraint->message)->addViolation(); } } }

Wire the API key in services.yaml:

App\Validator\NotDisposableEmailValidator: arguments: $apiKey: '%env(SPAMOVA_API_KEY)%'

Then apply it to your registration DTO or form:

use App\Validator\NotDisposableEmail; use Symfony\Component\Validator\Constraints as Assert;   class RegistrationDto { #[Assert\NotBlank] #[Assert\Email] #[NotDisposableEmail] public string $email = ''; }

Checking Multiple Emails at Once

For auditing existing users or processing imported contact lists, use the /api/v1/bulk endpoint. It accepts up to 100 emails per request and returns a results array alongside a meta object showing checks used and remaining quota.

$response = $httpClient->request('POST', 'https://spamova.com/api/v1/bulk', [ 'auth_bearer' => 'YOUR_API_KEY', 'json' => [ 'emails' => [ 'james847@mailinator.com', 'sarah115@tempmail.com', 'steve.wozniak@gmail.com', ], ], ]);   $result = $response->toArray(); // $result['results'] - array of check results // $result['meta']['checks_remaining'] - remaining quota

Requests with more than 100 emails are rejected in full. Split larger arrays into chunks of 100 before sending, processing each batch separately.

Get Started

Get your API key from your account, wire it into your services.yaml, and apply the constraint to your registration form. Disposable email protection is live in your Symfony application in minutes.