Set up the key and a single verify function
Store the API key in an environment variable and read it only on the server. VeriDock issues deterministic free test keys, so you can run the code below locally without spending any paid checks. The function sends a GET request to the verify endpoint with the address URL encoded, aborts after five seconds, and returns the parsed JSON.
export async function verifyEmail(email: string) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);
try {
const url = "https://api.veridock.io/v1/verify?email=" + encodeURIComponent(email);
const res = await fetch(url, {
headers: { Authorization: "Bearer " + process.env.VERIDOCK_API_KEY },
signal: controller.signal,
});
if (!res.ok) throw new Error("verify failed: HTTP " + res.status);
return (await res.json()) as {
status: "deliverable" | "undeliverable" | "risky" | "unknown";
reason: string; score: number; suggestion: string | null;
};
} finally { clearTimeout(timer); }
}Validate before you call the API
A network call is the expensive part, so filter obvious junk first. Trim the input, reject empty strings and anything without exactly one @, and cap the length at 254 characters. This keeps malformed submissions from counting against your quota and gives the user instant feedback. Leave the real syntax rules to the API, which returns invalid_syntax for anything it cannot parse.
Turn the response into a decision
The two fields that drive your logic are status and reason. Undeliverable is a hard rejection, and when the suggestion field is set you can offer the corrected address in the same message. Risky needs a per-reason policy: most teams reject disposable and accept role_account and catch_all. Unknown should be accepted, because it means the mail server did not answer rather than that the address is bad.
- undeliverable: return a 400 with the suggestion if present.
- risky with reason disposable: return a 400 asking for a permanent address.
- risky with any other reason: accept and record the reason for later review.
- deliverable or unknown: accept.
Handle failures without blocking signups
Two kinds of failure need separate handling. An API error, such as a 401 from a bad key, a 4xx from a rate limit or exhausted spend cap, or a timeout, means you got no result at all. A status of unknown is not an error; it is a valid answer. Catch the first kind, log the domain and HTTP status, and fail open by accepting the signup so a verification outage never becomes an outage on yours.
For production, wrap the call in a retry with a short backoff for 5xx responses, set a per-key spend cap in the VeriDock dashboard so a bug cannot run up a bill, and store status, reason, and score next to the user record so you can revisit decisions later. The full field reference is in the docs at /docs.
Fail open on API errors and fail closed only on undeliverable. A verification outage should never stop a real user from signing up.
Key takeaways
0/4Try it on a real address
Run syntax, DNS, MX, disposable, and role checks on any address. No signup needed.
Enter an address and press Check.
Runs real syntax, DNS and mail-server checks.
This demo checks syntax, domain, mail server, disposable and role-address rules. Sign up free for live mailbox checks.
Frequently asked questions
Verify addresses with one API call.
250 free checks every month, recurring. Unknown results are never billed.