Email verification API in PHP
To verify an email address in PHP, check its syntax with filter_var() first, then send a GET request to https://simpleverifier.com/api/v1/verify with your key in the Authorization header. The JSON response says valid, risky or invalid. Reject only invalid, and let the address through if the API times out.
By SimpleVerifier Team
Before you start
- Create a key on the API keys page. Keys start with
sv_live_and are shown once. - Set
SIMPLEVERIFIER_KEYin your server environment (ApacheSetEnv, PHP-FPMenv[], or your host's panel) so the key never sits in code you commit. - API access is included in the Pro plan ($29.99/month) and the Email + Phone plan ($49.99/month). See pricing.
1. Add the helper
One function, no dependencies beyond the cURL extension. It returns null instead of throwing when the API cannot answer, so a slow mail server never breaks your form.
<?php
// simpleverifier.php — PHP 7.4+ with the cURL extension
/**
* Returns "valid", "risky" or "invalid", or null when the API could not
* answer (timeout, rate limit, outage). Treat null as "let it through".
*/
function simpleverifier_status(string $email): ?string
{
$email = trim($email);
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
return 'invalid'; // fails the local syntax check, no API call made
}
$key = getenv('SIMPLEVERIFIER_KEY');
if ($key === false || $key === '') {
error_log('SIMPLEVERIFIER_KEY is not set');
return null;
}
$ch = curl_init('https://simpleverifier.com/api/v1/verify?email=' . rawurlencode($email));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key],
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($body === false || $code !== 200) {
error_log('SimpleVerifier unavailable, HTTP ' . $code);
return null;
}
$data = json_decode($body, true);
return is_array($data) && isset($data['status']) ? $data['status'] : null;
}2. Use it when a form is submitted
Block only invalid. A risky address may still work (catch-all domains accept everything), so accept it and keep the status if you want to review it later.
<?php
require __DIR__ . '/simpleverifier.php';
$errors = [];
$email = $_POST['email'] ?? '';
$status = simpleverifier_status($email);
if ($status === 'invalid') {
$errors['email'] = 'This email address cannot receive mail. Please check it.';
}
if ($errors === []) {
// Save the signup. $status is "valid", "risky" or null (API unavailable).
// Storing it lets you review risky signups later.
}What the API returns
GET or POST https://simpleverifier.com/api/v1/verify with email runs the syntax, domain, disposable-domain and live mailbox checks in one call and returns:
{
"email": "jane@company.com",
"status": "valid",
"reason": "Mailbox exists",
"mailbox_checked": true
}Every snippet above follows the same rule: only a successful response with status set to invalid blocks a person.
| Result | What it means | What to do |
|---|---|---|
| valid | The mail server confirmed the mailbox exists. | Accept. |
| risky | The domain is real but the mailbox couldn't be confirmed: catch-all domains, role addresses like info@, providers that hide mailbox status. | Accept on signup forms. Store the status and keep these out of cold campaigns. |
| invalid | Bad format, no mail server, a disposable domain, or the mailbox doesn't exist. | Reject and ask the person to check the address. |
| timeout, 429 or 503 | The check didn't finish: a slow mail server, too many calls this minute, or a brief outage. | Accept (fail open) and log it. Re-check later if it matters. |
| 401 or 402 | The key is wrong or revoked, or the subscription isn't active. | Accept, and alert yourself: every check is being skipped until it's fixed. |
Errors return JSON with an error message. Each key can make 120 calls a minute; for thousands of addresses, upload a CSV in the dashboard instead.
Phone numbers and spreadsheets
The same key works with /api/v1/phone?phone=…&country=… to validate a phone number and normalise it to E.164, with live carrier lookups on the Email + Phone plan. The request and response are in the API reference. To check a column of addresses without code, use the Google Sheets add-on with the same key.
Common questions
- Isn't filter_var(FILTER_VALIDATE_EMAIL) enough to validate an email in PHP?
- It only checks the format. An address like jane@compnay.com passes filter_var but has no mail server, and a well-formed address at a real company can still point to a mailbox that does not exist. Use filter_var first to skip obvious junk without spending an API call, then let the API check the domain and the mailbox.
- Should I use GET or POST?
- Either works. GET with the email in the query string is simplest with cURL. If you would rather keep addresses out of any request logs along the way, POST a JSON body of {"email": "..."} to the same URL with a Content-Type: application/json header.
- How much does the SimpleVerifier API cost?
- API access is included in the paid plans: Pro at $29.99/month and Email + Phone at $49.99/month. There are no per-call credits. Each key can make 120 calls a minute.
- Should I reject risky addresses?
- Not on a signup or contact form. Risky means the mailbox couldn't be confirmed, which includes every address at a catch-all company domain. Accept it, store the status, and leave risky addresses out of cold outreach.
- What if the API is slow or down?
- Let the address through. A mailbox check can take several seconds when a mail server is slow, so cap the wait at about 30 seconds (less on a busy form) and treat a timeout, a 429 or a 503 as unknown rather than invalid.