Laravel · PHP
Block disposable email in Laravel
Create a custom validation rule and attach it to your RegisterRequest or Fortify/Breeze signup form.
The code
<?php
// app/Rules/NotDisposableEmail.php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Http;
class NotDisposableEmail implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
try {
$response = Http::timeout(5)
->withToken(config('services.piisend.key'))
->post('https://api.piisend.com/api/v1/intelligence/email', ['email' => $value]);
if ($response->successful() && ($response->json('signals.disposable') === true)) {
$fail('Please use a permanent email address.');
}
} catch (\Throwable $e) {
// fail open
}
}
}
// app/Http/Requests/RegisterRequest.php
public function rules(): array
{
return [
'email' => ['required', 'email', new \App\Rules\NotDisposableEmail],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
];
}API key
Add `piisend.key` to `config/services.php` from `PIISEND_API_KEY` env.
Fail-open vs fail-closed
Empty catch allows signup on outage — log exceptions in production.
Pair with verification
Works with Laravel Fortify, Breeze, or Jetstream register controllers.
Send verification email with Piisend
After blocking disposable addresses, send OTP and verification mail through the same Piisend account. One API key for intelligence checks and transactional sends.