Check Email Code
Verify the OTP delivered by POST /v3/email/send/ and get the final verification result plus email intelligence: deliverability, breach exposure (is_breached and the breaches list from a breach-intelligence database), disposable-provider detection, and duplicate usage of the address across your sessions.
How the check finds the verification. Matching is by your application plus the email address — request_id is not an input. The most recent pending verification created within the last 5 minutes is checked. If there is none (never sent, already finalized, undeliverable at send time, or older than 5 minutes) the endpoint returns 200 with status: "Expired or Not Found".
Attempt budget. Each verification allows 3 code attempts. The first two wrong codes return status: "Failed" with the attempts remaining and email: null; the third wrong code finalizes the verification as Declined with an EMAIL_CODE_ATTEMPTS_EXCEEDED warning and returns the full email report. Codes are compared case-insensitively (relevant for alphanumeric_code sends); only the most recently sent code is valid.
Outcomes. Approved — correct code and no declining risk. Declined — terminal: the code was correct but a declining risk matched (a DECLINE action below, a blocklisted address, or the address found undeliverable at finalization), or the attempt budget was exhausted. Failed — wrong code, attempts remaining. Expired or Not Found — nothing to check. On Approved/Declined the request_id equals the send’s request_id (the session id) and email carries the full report (is_breached, breaches, is_disposable, is_undeliverable, warnings, lifecycle, matches); on Failed and Expired or Not Found the request_id is a one-off random UUID.
Risk actions. duplicated_email_action, breached_email_action, and disposable_email_action decide what happens when the corresponding risk is detected on a correct code: DECLINE flips the final status to Declined; NO_ACTION (default) records the risk in email.warnings without affecting the status.
Billing. Checks are free — the credit is consumed by the successful send.
Session persistence. A finalized check updates the session created by the send (visible in the Business Console, queryable via GET /v3/session/{sessionId}/decision/) and fires a status.updated webhook.
Sandbox. Sandbox API keys skip all processing: code 123456 returns a static Approved payload with a simplified email object (status, email, is_breached, is_disposable, is_undeliverable); any other code returns Failed. Nothing is persisted.
Authentication. Send your application’s API key in the x-api-key header. Missing or invalid credentials return 403 ({"detail": "You do not have permission to perform this action."}) — this API never returns 401.
Rate limit. Shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns 429.
Authorizations
Body
The same email address used in the matching POST /v3/email/send/ call. This is what links the check to the send.
"alice@example.com"
The OTP the end user received: 4–8 digits, or 4–8 letters/digits when alphanumeric_code: true was used at send time. Comparison is case-insensitive.
10"123456"
What to do when the same address was already used and approved by a different user (only previously Approved verifications count) (different vendor_data) of your application. DECLINE flips the final status to Declined; NO_ACTION records the risk in email.warnings and fills email.matches.
NO_ACTION, DECLINE What to do when the address appears in known data breaches (email.is_breached). DECLINE flips the final status to Declined; NO_ACTION records the risk in email.warnings.
NO_ACTION, DECLINE What to do when the domain belongs to a disposable/temporary-mail provider (email.is_disposable). DECLINE flips the final status to Declined; NO_ACTION records the risk in email.warnings.
NO_ACTION, DECLINE Response
Check completed — wrong codes and missing verifications also return 200; inspect status, not the HTTP code. email is populated only on finalized outcomes (Approved/Declined), null on Failed, and absent on Expired or Not Found.
On Approved/Declined: the session id of the matched verification — identical to the request_id returned by POST /v3/email/send/. On Failed and Expired or Not Found: a random one-off UUID that cannot be looked up later.
Approved — correct code, no declining risk. Declined — terminal: a declining risk matched or the attempt budget (3) was exhausted. Failed — wrong code, attempts remaining. Expired or Not Found — no pending verification for this address in the last 5 minutes.
Approved, Declined, Failed, Expired or Not Found Human-readable explanation of the outcome, including the number of attempts remaining after a wrong code.
Full email report. Present (non-null) only on finalized outcomes (Approved/Declined); null on Failed and absent on Expired or Not Found.
vendor_data of the matched verification's session. null on Expired or Not Found.
metadata of the matched verification's session. null on Expired or Not Found.
Timestamp of this check response.