Real-time email verification with plain PHP and cURL — works in any framework, from Laravel to WordPress.
Send a GET request with the email and your API token.
The helper below also handles interim Unknown results by waiting
RetryAfterSeconds and retrying automatically.
<?php
const API_URL = 'https://api.validemail.net/';
const API_KEY = 'YOUR_API_KEY'; // find it in your ValidEmail dashboard
function verifyEmail(string $email, int $maxRetries = 3): array
{
$result = [];
for ($attempt = 0; $attempt < $maxRetries; $attempt++) {
$url = API_URL . '?' . http_build_query(['email' => $email, 'token' => API_KEY]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 90);
$body = curl_exec($ch);
if ($body === false) {
throw new RuntimeException('Request failed: ' . curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("Request failed with HTTP {$status}: {$body}");
}
$result = json_decode($body, true);
// "Unknown" means the verification is still in progress (e.g. greylisting).
if ($result['State'] === 'Unknown' && !empty($result['RetryAfterSeconds'])) {
sleep($result['RetryAfterSeconds']);
continue;
}
return $result;
}
return $result; // still pending after $maxRetries — treat as risky
}
$result = verifyEmail('someone@example.com');
echo 'Valid: ' . ($result['IsValid'] ? 'yes' : 'no') . PHP_EOL;
echo 'Score: ' . $result['Score'] . PHP_EOL;
echo 'State: ' . $result['State'] . PHP_EOL;
echo 'Reason: ' . $result['Reason'] . PHP_EOL;
if ($result['IsValid'] && $result['Score'] >= 80) {
echo 'Safe to send.' . PHP_EOL;
}
State = "Unknown")
Some mail servers greylist first-time senders or respond slowly. Instead of failing, the API returns an
interim 200 OK result with State = "Unknown", a Reason of
PENDING or GREYLISTED, and a RetryAfterSeconds hint while the
verification finishes in the background.
RetryAfterSeconds seconds, then repeat the same request to get the final verdict.Unknown as "not yet decided" — never as a delivery failure.The balance endpoint is free to call and never consumes a credit — perfect for a pre-flight check before verifying a large list.
$balance = json_decode(
file_get_contents('https://api.validemail.net/balance?token=' . API_KEY),
true
)['balance'];
echo "Credits remaining: {$balance}" . PHP_EOL;
| HTTP Status | Meaning | What to do |
|---|---|---|
| 200 OK | The request was processed. Check State — a result with State = "Unknown" and a RetryAfterSeconds value is an interim answer, not a final verdict. |
Use the result. If State is Unknown, retry the same request after RetryAfterSeconds. |
| 400 Bad Request | Missing email/token parameter, no credits remaining, or a transient processing failure. |
Check the response text. If you are out of credits, top up your balance before retrying. |
| 401 Unauthorized | The API key is invalid or unknown. | Verify the token value against the API key shown in your dashboard. |
| 403 Forbidden | The account attached to this API key is inactive. | Contact info@validemail.net to reactivate the account. |
| 429 Too Many Requests | You exceeded your per-second request limit. The response body includes the configured limit. | Slow down and retry with backoff, or contact us to raise your rate limit. |
Explore every response field and status code in the full API reference.