Valider un email en temps réel
Ce guide couvre les scénarios courants d'intégration de la validation email unitaire.
Cas d'usage
- Formulaire d'inscription → valider l'email avant de créer le compte
- Lead generation → qualifier les emails à l'entrée
- CRM → vérifier les emails d'une fiche contact
Validation simple (sans SMTP)
Gratuite, instantanée (~100-300ms). Idéale pour la validation en temps réel.
- cURL
- TypeScript
- Python
- PHP
curl -X POST https://api.yeswecheck.fr/v2/email/validate \
-H "X-API-Key: $YESWECHECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
interface ValidationResult {
email: string;
status: 'valid' | 'invalid' | 'risky' | 'unknown';
score: number;
syntax: { valid: boolean; normalized: string };
dns: { hasMxRecords: boolean };
disposable: { isDisposable: boolean };
roleAccount: { isRoleAccount: boolean };
typo: { hasTypo: boolean; suggestions: string[] };
metadata: { creditsUsed: number; processingTimeMs: number };
}
async function validateEmail(email: string): Promise<ValidationResult> {
const response = await fetch('https://api.yeswecheck.fr/v2/email/validate', {
method: 'POST',
headers: {
'X-API-Key': process.env.YESWECHECK_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});
if (!response.ok) {
throw new Error(`YesWeCheck error: ${response.status}`);
}
return response.json();
}
import httpx
import os
async def validate_email(email: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.yeswecheck.fr/v2/email/validate",
headers={"X-API-Key": os.environ["YESWECHECK_API_KEY"]},
json={"email": email},
timeout=10.0,
)
response.raise_for_status()
return response.json()
function validateEmail(string $email): array
{
$response = file_get_contents(
'https://api.yeswecheck.fr/v2/email/validate',
false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Content-Type: application/json',
'X-API-Key: ' . getenv('YESWECHECK_API_KEY'),
]),
'content' => json_encode(['email' => $email]),
],
])
);
return json_decode($response, true);
}
Validation avec SMTP
Recommandée pour les listes de haute valeur. Consomme 1 crédit par email validé.
const result = await validateEmail('[email protected]');
// Résultat avec SMTP activé
const fullResult = await fetch('https://api.yeswecheck.fr/v2/email/validate', {
method: 'POST',
headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
smtp: true,
smtpTimeout: 8000, // 8 secondes (défaut)
}),
}).then(r => r.json());
console.log(fullResult.smtp);
// {
// performed: true,
// deliverable: true,
// responseCode: 250,
// responseMessage: "OK"
// }
Logique de décision recommandée
function shouldAcceptEmail(result: ValidationResult): {
accept: boolean;
reason?: string;
suggestion?: string;
} {
// 1. Syntaxe invalide → refus immédiat
if (!result.syntax.valid) {
return { accept: false, reason: 'Adresse email invalide' };
}
// 2. Pas de MX records → domaine inexistant
if (!result.dns.hasMxRecords) {
return { accept: false, reason: 'Domaine email inexistant' };
}
// 3. Email jetable → refus ou avertissement
if (result.disposable.isDisposable) {
return {
accept: false,
reason: 'Les adresses email temporaires ne sont pas acceptées',
};
}
// 4. Typo détectée → suggérer la correction
if (result.typo.hasTypo && result.typo.suggestions.length > 0) {
return {
accept: true,
suggestion: result.typo.suggestions[0],
};
}
// 5. Role account → accepter avec avertissement
if (result.roleAccount.isRoleAccount) {
return {
accept: true,
reason: 'Conseil : utilisez une adresse personnelle plutôt que info@ ou support@',
};
}
// 6. SMTP échoué → email n'existe pas
if (result.smtp.performed && !result.smtp.deliverable) {
return { accept: false, reason: 'Cette boîte email n\'existe pas' };
}
return { accept: true };
}
Intégration dans un formulaire React
import { useState, useCallback } from 'react';
function EmailInput({ onValidated }: { onValidated: (email: string, valid: boolean) => void }) {
const [email, setEmail] = useState('');
const [status, setStatus] = useState<'idle' | 'checking' | 'valid' | 'invalid' | 'risky'>('idle');
const [suggestion, setSuggestion] = useState<string | null>(null);
const [message, setMessage] = useState('');
const validate = useCallback(async (value: string) => {
if (!value || !value.includes('@')) return;
setStatus('checking');
setSuggestion(null);
try {
// Appel via votre API backend (ne pas exposer la clé en frontend)
const result = await fetch('/api/validate-email', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: value }),
}).then(r => r.json());
setStatus(result.status);
if (result.typo?.hasTypo && result.typo.suggestions[0]) {
setSuggestion(result.typo.suggestions[0]);
setMessage(`Vouliez-vous dire ${result.typo.suggestions[0]} ?`);
} else if (result.status === 'invalid') {
setMessage('Adresse email invalide');
} else if (result.disposable?.isDisposable) {
setStatus('invalid');
setMessage('Les adresses temporaires ne sont pas acceptées');
} else {
setMessage('');
}
onValidated(value, result.status === 'valid');
} catch {
setStatus('idle');
}
}, [onValidated]);
return (
<div>
<input
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
onBlur={e => validate(e.target.value)}
placeholder="[email protected]"
style={{
borderColor:
status === 'valid' ? '#10B981' :
status === 'invalid' ? '#EF4444' :
status === 'risky' ? '#F59E0B' : '#E2E8F0',
}}
/>
{status === 'checking' && <span>⏳ Vérification...</span>}
{message && (
<p style={{ color: status === 'risky' ? '#F59E0B' : '#EF4444' }}>
{message}
</p>
)}
{suggestion && (
<button onClick={() => { setEmail(suggestion); validate(suggestion); }}>
Utiliser {suggestion}
</button>
)}
</div>
);
}
Suggestions de domaine (autocomplétion)
// Obtenir des suggestions de domaines populaires pour la France
const suggestions = await fetch('https://api.yeswecheck.fr/v2/email/suggest/domain', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
// Pas d'auth requise pour ce endpoint
body: JSON.stringify({ country: 'FR', partial: 'gm', count: 5 }),
}).then(r => r.json());
// { suggestions: [{ domain: "gmail.com", provider: "Google", ... }] }
Détection de fautes de frappe
curl -X POST https://api.yeswecheck.fr/v2/email/suggest/typo-domain \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
{
"original": "[email protected]",
"hasTypo": true,
"suggestion": "[email protected]",
"confidence": 0.97
}