Email Validation API Integration Guide: Best Practices for Developers
Max Kruger
March 1, 2026
Adding email validation to your signup flow is one of the highest-ROI fraud prevention steps you can take. But the implementation details matter — validate in the wrong place or handle edge cases poorly, and you'll either miss fraud or frustrate legitimate users.
This guide covers the practical patterns that work in production.
Where to Validate
You have three options for when to validate an email address, and the right answer depends on your product:
Option 1: On Form Submit (Recommended)
Validate the email when the user submits the signup form, before creating the account. This is the most common pattern and provides the best balance of security and user experience.
// In your registration controller
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . config('services.fidro.api_key'),
])->post('https://api.fidro.io/v1/validate/email', [
'email' => $request->email,
]);
$validation = $response->json();
if ($validation['disposable'] ?? false) {
return back()->withErrors([
'email' => 'Please use a permanent email address.',
]);
}
Option 2: On Field Blur (Real-time)
Validate as soon as the user tabs out of the email field. This gives instant feedback but makes more API calls (including for partially typed addresses if debouncing isn't implemented properly).
Best for: high-traffic signup forms where you want to catch issues early.
Option 3: Post-Signup (Async)
Allow signup to complete immediately, then validate the email asynchronously via a queue job. Flag suspicious accounts for review rather than blocking them.
Best for: products where conversion rate is critical and you'd rather review flagged accounts manually.
Handling the Response
A validation API returns more than just "valid" or "invalid." Here's how to use the full response:
{
"email": "user@example.com",
"valid": true,
"disposable": false,
"dns_valid": true,
"free_provider": true,
"domain_age_days": 9125,
"risk_score": 0.15
}
Decision Matrix
| Signal | Action |
|---|---|
disposable: true |
Block or require phone verification |
dns_valid: false |
Block — the domain can't receive email |
risk_score > 0.7 |
Flag for review, add friction |
free_provider: true |
Allow, but note for B2B products |
domain_age_days < 30 |
Add to review queue |
Don't treat every signal as a hard block. Layer them together and set thresholds based on your risk tolerance.
Error Handling and Resilience
Your signup flow should never break because a third-party API is down. Follow these principles:
Fail Open
If the validation API times out or returns a 5xx error, allow the signup and queue a background validation job:
try {
$validation = $this->validateEmail($email);
if ($validation['disposable']) {
return $this->rejectSignup('Please use a permanent email address.');
}
} catch (\Exception $e) {
// Log the failure, allow signup, validate async
Log::warning('Email validation API unavailable', ['email' => $email]);
dispatch(new ValidateEmailJob($user));
}
Set Timeouts
Don't let a slow API response hold up your entire signup flow. Set aggressive timeouts (2-3 seconds max) and fall back to the fail-open path:
$response = Http::timeout(3)->post('https://api.fidro.io/v1/validate/email', [
'email' => $email,
]);
Cache Results
If the same email is submitted multiple times (common with form resubmissions), cache the validation result to avoid redundant API calls:
$cacheKey = 'email_validation:' . md5($email);
$validation = Cache::remember($cacheKey, now()->addHours(24), function () use ($email) {
return $this->callValidationApi($email);
});
Rate Limiting Considerations
Fidro's free plan includes 200 validations per month. To stay within limits:
- Cache aggressively — Most signups include form resubmissions. Cache results for at least 24 hours.
- Skip known-good domains — If you only care about disposable detection, you can skip validation for emails from
gmail.com,outlook.com, etc. (though this misses other risk signals). - Validate only at signup — Don't re-validate on every login. The email was checked when the account was created.
Testing Your Integration
Before going live, test against known disposable domains to verify your integration works:
# Should return disposable: true
curl -X POST https://api.fidro.io/v1/validate/email \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"email": "test@mailinator.com"}'
# Should return disposable: false
curl -X POST https://api.fidro.io/v1/validate/email \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"email": "test@gmail.com"}'
You can also use Fidro's free email checker tool to interactively test addresses without writing code.
Next Steps
- Sign up for a free Fidro account — 200 validations/month included
- Read the API documentation for the full response schema
- Implement validation in your signup flow using the patterns above
- Monitor your fraud metrics and adjust thresholds as needed