EmailVerify Pro

Recipes

Working solutions: clean a CRM export, gate a signup form, block disposable addresses, verify a mailing list in CI, keep a suppression list in sync.

View as Markdown →

Complete, working solutions to the things people actually build. Every snippet runs as-is once you substitute your key.

Clean a CRM export before a campaign

You have a CSV of leads and want only the addresses that will land.

emailverify login
emailverify bulk --file leads.csv --out verified.json --timeout 300

--file accepts one address per line, a JSON array, or a CSV — for a CSV it picks the column containing an @. Then keep only the sendable ones:

jq -r '.results[] | select(.status == "valid" or .status == "accept_all") | .email' \
  verified.json > safe-to-send.txt

Or in Python, using the deliverability score rather than the raw status:

import csv, json
from emailverify import Client

client = Client.from_env()

with open("leads.csv") as fh:
    emails = [row["email"] for row in csv.DictReader(fh) if row.get("email")]

safe, risky = [], []
for i in range(0, len(emails), 100):                 # bulk caps at 100 per call
    for r in client.bulk(emails[i:i + 100])["results"]:
        score = r.get("deliverability_score") or {}
        target = safe if score.get("can_send") else risky
        target.append(r["email"])

print(f"{len(safe)} safe, {len(risky)} risky")
open("safe-to-send.txt", "w").write("\n".join(safe))

Gate a signup form

Validate syntax instantly on the client, then verify properly on the server before you create the account.

// server side — never trust the browser for this
const res = await fetch(
  `https://emailverifypro.com/validate?email=${encodeURIComponent(email)}`,
  { headers: { "X-API-Key": process.env.EMAILVERIFY_API_KEY } }
);
const data = await res.json();

if (data.is_disposable) {
  return reject("Please use a permanent email address.");
}
if (data.did_you_mean) {
  return suggest(`Did you mean ${data.did_you_mean}?`);
}
if (!data.deliverability_score?.can_send) {
  return reject("We couldn't verify that address.");
}

Keep the full check off the request path where you can — it can take seconds. Either run it asynchronously after signup, or use GET /validate/quick for a fast DNS-only answer and follow up properly in a background job.

Catch typos at the point of entry

curl "https://emailverifypro.com/verify/typo?email=someone@gmial.com"
{"email": "someone@gmial.com", "did_you_mean": "someone@gmail.com", "confidence": 0.97}

Block disposable addresses

r = client.verify("test@mailinator.com")
if r["is_disposable"]:
    raise ValueError("Disposable addresses are not accepted")

Find someone's address

r = client.call("find-email", domain="example.com",
                first_name="Jane", last_name="Doe")
print(r["email"], r["confidence"])

It learns the domain's convention from addresses it has already seen, builds the likely candidates, and verifies them.

Keep a suppression list in step with your ESP

Point your ESP's webhook at the matching receiver and bounces feed back automatically:

ESPWebhook URL
SendGridhttps://emailverifypro.com/webhooks/sendgrid
Amazon SEShttps://emailverifypro.com/webhooks/ses
Postmarkhttps://emailverifypro.com/webhooks/postmark
Mailchimphttps://emailverifypro.com/webhooks/mailchimp

Or record outcomes yourself:

client.call("bounce", email="hard-bounced@example.com", bounce_type="hard")
client.call("delivered", email="landed@example.com")

Every report improves the model for your future verifications.

Verify in CI before a send

# .github/workflows/verify-list.yml
name: Verify mailing list
on:
  pull_request:
    paths: ["lists/**.csv"]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pipx install emailverify
      - name: Verify and fail on undeliverable addresses
        env:
          EMAILVERIFY_API_KEY: ${{ secrets.EMAILVERIFY_API_KEY }}
        run: |
          emailverify bulk --file lists/campaign.csv --out out.json --json
          bad=$(jq '[.results[] | select(.status == "invalid")] | length' out.json)
          echo "$bad undeliverable addresses"
          test "$bad" -eq 0

Re-verify a warm list on a schedule

Addresses decay — people leave companies and domains lapse. Re-check anything older than 90 days:

emailverify raw POST /admin/reverify --body '{"older_than_days": 90}'

Deduplicate before you spend credits

Gmail dots, plus-addressing and case differences all hide duplicates:

emailverify dedup --file leads.txt
{"original_count": 5000, "unique_count": 4380, "duplicates_removed": 620}

Ask an AI assistant to do it

With the MCP server connected, these all work as plain requests: