Validate emails the Laravel way — a facade, config, and a drop-in Deliverable validation rule.
Require the package with Composer. It supports Laravel 11, 12 & 13, and the service provider and BounceShift facade are auto-discovered.
composer require bounceshift/laravelAdd your credentials to .env. Create an API token in your dashboard; your organization ID is your team ID.
BOUNCESHIFT_API_KEY=your-api-key
BOUNCESHIFT_ORGANIZATION_ID=your-organization-idTo customize the timeout, retries, or base URL, publish the config file:
php artisan vendor:publish --tag=bounceshift-configCall the BounceShift facade. You get back a typed result with the status, a 0–100 confidence score, and helper flags:
use BounceShift\Laravel\Facades\BounceShift;
$result = BounceShift::validate('[email protected]');
$result->status->value; // 'valid', 'catch_all', 'unknown', 'invalid', ...
$result->confidence; // 0-100
$result->isSafeToSend(); // true for 'valid' or 'catch_all'
$result->isCatchAll; // bool
$result->fromCache; // bool — no credit is spent on a cache hit
$result->creditsUsed; // intPrefer dependency injection? Resolve the underlying client from the container instead of the facade:
use BounceShift\Client;
$result = app(Client::class)->validate('[email protected]');Deliverable validation ruleThis is the reason to use the Laravel package: a drop-in rule for your form requests and validators. Add it to any email field to stop undeliverable addresses at the point of entry.
use BounceShift\Laravel\Rules\Deliverable;
$request->validate([
'email' => ['required', 'email', new Deliverable],
]);It is lenient by default, on purpose. It rejects only addresses that are decisively bad — invalid, disposable, do_not_mail, abuse, and spamtrap. It passes valid, catch_all, unknown, and risky, because a probe that can't reach a mailbox — common for catch-all domains and throttled providers like Outlook and Gmail — should never block a real person at signup. And if the API is unreachable, the rule fails open, so an outage never blocks your users.
When you want to be stricter, opt in explicitly:
// Also reject "risky"/"unknown" results:
'email' => ['required', 'email', (new Deliverable)->strict()],
// Or require a minimum confidence score (0-100):
'email' => ['required', 'email', (new Deliverable)->minConfidence(70)],Reach for strict() or minConfidence() only when you know your unknown rate is low — otherwise you will reject real users whose mailbox provider throttles verification.
Every result carries a status, a 0–100 confidence, and granular flags. isSafeToSend() is true for valid and catch_all. See how we measure accuracy for what each status means and why we abstain instead of guessing.
Related terms
Get 100 free validations to test our service. No credit card required.
Start Free Trial