Verify a list of addresses
/api/v1/verificationsChecks whether each address has a mailbox — without sending anything. We ask the recipient's mail server directly, the way a sending server would, and stop before any message is sent.
Costs 10 send credits per unique address, charged when the verification starts. Duplicates
and letter case are removed first, so Ada@x.com and ada@x.com are one address. If you
have fewer credits than the list needs, nothing starts and nothing is charged (a 402).
Most answers arrive within seconds. Gmail mailboxes are checked at a steady pace, so a large
list can take a while; addresses still being checked read pending. Anything we cannot
answer within a day is refunded.
Send an Idempotency-Key header so a retried request is never charged twice. Up to
50,000 addresses per verification, and up to 3 running at once.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Send a unique value — a UUID is ideal — to make this request safe to retry. If we have already answered a request with the same key and the same body, you get that exact response back with `Idempotent-Replayed: true` and nothing is sent a second time. Reusing a key with a DIFFERENT body is a 409, because answering the first response to a second message would silently swallow it. Keys are scoped to your organization and honoured for 24 hours. A 5xx does not record a key: we cannot say whether the message left, so your retry genuinely retries. Omit the header and nothing changes. |
Request body
emailsarray<string>requiredThe addresses to check.
labelstringYour own name for this verification.
Request
/api/v1/verificationscurl -X POST 'https://app.mailyte.com/api/v1/verifications' \
-H 'Authorization: Bearer mk_live_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"emails": [],
"label": "<string>"
}'const response = await fetch('https://app.mailyte.com/api/v1/verifications', {
method: 'POST',
headers: {
Authorization: 'Bearer mk_live_YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"emails": [],
"label": "<string>"
}),
});
const { data } = await response.json();import requests
response = requests.post(
"https://app.mailyte.com/api/v1/verifications",
headers={"Authorization": "Bearer mk_live_YOUR_API_KEY"},
json={
"emails": [],
"label": "<string>"
},
)
data = response.json()["data"]<?php
$response = Http::withToken('mk_live_YOUR_API_KEY')
->post('https://app.mailyte.com/api/v1/verifications', [
'emails' => [],
'label' => '<string>',
]);
$data = $response->json('data');require "net/http"
require "json"
uri = URI("https://app.mailyte.com/api/v1/verifications")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer mk_live_YOUR_API_KEY"
request["Content-Type"] = "application/json"
request.body = {
"emails": [],
"label": "<string>"
}.to_json
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }Response
Started. Poll the verification until `status` is `finished`.
dataobjectobjectstringverificationidstringstatusstringrunning | finished | expired | failed`running` until every address has an answer, then `finished`. `expired`: the checker could not answer some addresses within a day; they stay `pending` and their credits were refunded.
sourcestringlist | contacts | import | campaign`list`: addresses you sent (10 send credits each). `contacts`: your never-checked contacts (free). `import` and `campaign`: checks we run automatically when you import contacts or start a campaign (free).
labelstringnulltotalintegerUnique addresses in the run.
countsobjectAlways sums to `total`.
validintegerThe mailbox exists.
invalidintegerDoes not exist, cannot receive mail, or is not an address. Mail to these is refused.
riskyintegerThrowaway, catch-all or role address: may not reach a person.
unknownintegerThe provider would not confirm either way (Yahoo and AOL never do). Sent as normal.
pendingintegerStill being checked.
credits_chargedintegerSend credits this run cost: 10 per address for a `list`, 0 otherwise.
credits_refundedintegerCredits given back for addresses the checker could not answer.
created_atstringfinished_atstringnull
Returned inside the standard envelope.
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist. |
403 | The key is valid but may not do this: it lacks the required scope, its IP allowlist does not include you, or this endpoint does not accept API keys. |
404 | No such resource in this organization. |
422 | The request was understood but the values were not acceptable. |
429 | Too many requests, or the organization has spent its sending allowance. `Retry-After` says how long to wait. |
Every status, with what causes it and what to do, is on the error reference.