Email Verification API
Check that an email address is valid and reachable, and optionally that it belongs to a named person or organisation.
What it verifies
Checks that an email address is real, active and reachable by testing its format, its domain and the mail server's own reply, and reports what is known about the domain. Send a person's name or an organisation's name as well and the answer says whether the address belongs to them. An address that does not pass is still a complete answer: the response says so and which check failed. An address that is not a valid email at all is rejected as invalid input.
Who uses it
- Lenders and fintechs checking the email given at onboarding or on a loan application
- Fraud and risk teams screening for fake, disposable or generic addresses
- Platforms that want to confirm an address belongs to the person or company who gave it
Request and response
https://verification.techinnoverz.com/api/v1/contactability/emailCheck that an email address is valid and reachable, and optionally who it belongs to. This call is billed when it returns a successful result.
Request body
emailstringrequiredThe email address to check.
individualNamestringoptionalOptional. A person's name to compare with the name in the address.
establishmentNamestringoptionalOptional. An organisation's name to compare with the address's domain.
consentstringrequiredMust be "Y". Records that the end customer consented to this check; logged against the transaction.
referenceIdstringoptionalYour own id, echoed back in the response for reconciliation.
Example requests
curl -X POST "https://verification.techinnoverz.com/api/v1/contactability/email" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "asha.sample@example.com",
"individualName": "Asha Sample",
"establishmentName": "Sample Enterprise Solutions",
"consent": "Y",
"referenceId": "app_20915"
}'const res = await fetch("https://verification.techinnoverz.com/api/v1/contactability/email", {
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"email": "asha.sample@example.com",
"individualName": "Asha Sample",
"establishmentName": "Sample Enterprise Solutions",
"consent": "Y",
"referenceId": "app_20915"
}),
});
const result = await res.json();import requests
res = requests.post(
"https://verification.techinnoverz.com/api/v1/contactability/email",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"email": "asha.sample@example.com",
"individualName": "Asha Sample",
"establishmentName": "Sample Enterprise Solutions",
"consent": "Y",
"referenceId": "app_20915",
},
timeout=15,
)
result = res.json()200 response — status "found"
{
"status": "found",
"data": {
"email": "asha.sample@example.com",
"isVerified": true,
"isEmailValid": true,
"isEstablishmentMatched": true,
"isIndividualMatched": true,
"establishmentMatches": [
{
"establishmentName": "SAMPLE ENTERPRISE SOLUTIONS PRIVATE LIMITED",
"establishmentId": "PYKRP2460100000",
"matchedDomain": "example.com",
"source": "epfo",
"matchedEmailId": "hr@example.com",
"individuallyMatched": true,
"score": 1
}
],
"nameInEmail": "asha.sample",
"individualMatchScore": 1,
"domain": {
"name": "example.com",
"ageInYears": 6,
"createdAt": "2019-11-06 08:57:28+00:00",
"updatedAt": "2025-10-18 09:14:20+00:00",
"expiresAt": "2029-11-06 08:57:28+00:00",
"isExpired": false
},
"isWebmail": false,
"hasMxRecords": true,
"isSmtpServerValid": true,
"isSmtpEmailValid": true,
"isGenericEmail": false
},
"source": "provider",
"dataAsOf": "2026-11-03T09:30:00.000Z",
"referenceId": "app_20915",
"billing": {
"charged": true,
"walletBalance": "12450.00"
},
"txnId": "txn_8c31ba90",
"livemode": true
}Fields returned in data
emailstringoptionalThe address that was checked.
isVerifiedbooleanoptionalOverall result: true when all the major checks passed (the address is valid and reachable, and any name or organisation you sent matched).
isEmailValidbooleanoptionalWhether the address exists and can receive mail (the domain's mail records and the mail server's own reply both agree).
isEstablishmentMatchedbooleanoptionalWhether the organisation you sent matches the address's domain. null when you sent no organisation.
isIndividualMatchedbooleanoptionalWhether the person you sent matches the name in the address. null when you sent no name.
establishmentMatchesarrayoptionalOrganisations the domain is linked to in official records, each with establishmentName, establishmentId, matchedDomain, source, matchedEmailId, individuallyMatched and a score from 0 to 1. Empty when none were looked up.
nameInEmailstringoptionalThe name part of the address, before the @.
individualMatchScorenumberoptionalHow closely the person you sent matches the name in the address, 0 to 1. null when you sent no name.
domainobjectoptionalWhat is known about the address's domain: name, ageInYears, createdAt, updatedAt, expiresAt and isExpired.
isWebmailbooleanoptionalWhether the domain is a public webmail service such as Gmail or Outlook.
hasMxRecordsbooleanoptionalWhether the domain has mail (MX) records.
isSmtpServerValidbooleanoptionalWhether the domain's mail server could be reached.
isSmtpEmailValidbooleanoptionalWhether the mail server says the mailbox exists.
isGenericEmailbooleanoptionalWhether the address looks generic, such as info@, hr@ or support@.
Error codes
Errors return a non-200 HTTP status and the same envelope, so your retry logic and your reconciliation agree.
400 INVALID_INPUTA field is missing or malformed. The details list each problem. Not charged.
401 INVALID_KEYThe key is missing, revoked, or not a key we issued.
402 WALLET_EMPTYYour available balance is below the price of this call. Top up and retry. Not charged.
403 PRODUCTION_NOT_ENABLEDA live key was used before live access was enabled for your account. Use a test key, or ask us to enable live access.
403 TEST_NOT_ENABLEDA test key was used before test (UAT) access was enabled for your account. Ask us to enable it.
403 API_NOT_ENABLEDThis check is switched off for your account, or is not available for live use yet.
403 IP_NOT_ALLOWEDThe key is restricted to certain IP addresses and this call came from another.
403 ACCOUNT_SUSPENDEDThe account is suspended. Contact support.
404 NO_DATAA valid request, but no record was found. Not charged.
404 ROUTE_NOT_FOUNDThere is no endpoint at that path.
405 METHOD_NOT_ALLOWEDUse the method shown in the Allow header.
409 IDEMPOTENCY_IN_PROGRESSA call with the same Idempotency-Key is still being processed. Retry after the delay in Retry-After.
413 PAYLOAD_TOO_LARGEThe request body is too large. Not charged.
415 UNSUPPORTED_MEDIA_TYPESend the request with Content-Type: application/json.
422 IDEMPOTENCY_KEY_REUSEDThis Idempotency-Key was already used with a different request body. Use a new key for a new request.
429 RATE_LIMITEDToo many requests or too many at once. Wait for the Retry-After delay.
500 INTERNAL_ERRORSomething went wrong on our side. Not charged. Quote the txnId if you contact support.
502 SOURCE_ERRORThe data source returned an error. Not charged.
503 SOURCE_DOWNThe data source is unavailable right now. Not charged. Retry after the delay in Retry-After.
504 SOURCE_TIMEOUTThe data source did not answer in time. Not charged.
{
"status": "error",
"error": {
"code": "NO_DATA",
"message": "No record found for the given input. Not charged."
},
"billing": {
"charged": false
},
"txnId": "txn_8c31ba91",
"livemode": true
}Billing
You are charged only on successful hits. Failed, no-data and error calls are free.
Every response carries billing.charged and your remaining billing.walletBalance. Per-hit pricing is set on your rate card; book a demo to get yours.
All API documentation · OpenAPI specification · Docs as plain text
