Skip to content

API quickstart

  1. Create a key. In the app, open Profile → API and create a key. Copy it — it’s shown only once. (No API tab? API access starts with any purchase.)

  2. Check it works.

    Terminal window
    export EMAILSHIELD_API_KEY="evf_your_api_key"
    curl https://app.emailshield.co/api/v1/account/credits \
    -H "X-API-Key: $EMAILSHIELD_API_KEY"
    {"credits": 49000, "credits_used_today": 1000, "credits_used_this_month": 12000, "plan_limit": null, "renewal_date": "2026-11-08T10:00:00Z"}
  3. Verify one address. The answer comes back in the same response, usually within a few seconds (at most 30).

    Terminal window
    curl -X POST https://app.emailshield.co/api/v1/verify/single \
    -H "X-API-Key: $EMAILSHIELD_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"email": "jane.doe@example.com"}'
    {
    "email": "jane.doe@example.com",
    "status": "valid",
    "valid": true,
    "score": 0.95,
    "reason": "Mailbox confirmed",
    "details": {"primary_label": "valid", "tags": [], "label_reasons": ["Mailbox confirmed"]},
    "credits_used": 1,
    "credits_remaining": 48999,
    "processed_at": "2026-10-09T12:00:03Z"
    }
  4. Submit a list. Up to 50,000 addresses per call. You get a job_id straight away.

    Terminal window
    curl -X POST https://app.emailshield.co/api/v1/verify/bulk \
    -H "X-API-Key: $EMAILSHIELD_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name": "October campaign", "emails": ["jane.doe@example.com", "info@example.org"]}'
    {"job_id": "3f1c…", "status": "queued", "total_emails": 2, "credits_used": 2, "credits_remaining": 48997, "created_at": "2026-10-09T12:01:00Z"}
  5. Wait for it to finish. Poll the job until terminal is true (or use a webhook).

    Terminal window
    curl https://app.emailshield.co/api/v1/jobs/3f1c… -H "X-API-Key: $EMAILSHIELD_API_KEY"
  6. Read the results, 100 per page by default (up to 1,000), until has_more is false.

    Terminal window
    curl "https://app.emailshield.co/api/v1/jobs/3f1c…/results?page=1&per_page=1000" \
    -H "X-API-Key: $EMAILSHIELD_API_KEY"
import os, time, requests
BASE = "https://app.emailshield.co/api"
session = requests.Session()
session.headers["X-API-Key"] = os.environ["EMAILSHIELD_API_KEY"]
emails = ["jane.doe@example.com", "info@example.org"]
job = session.post(f"{BASE}/v1/verify/bulk", json={"name": "October campaign", "emails": emails}).json()
while True:
status = session.get(f"{BASE}/v1/jobs/{job['job_id']}").json()
if status["terminal"]:
break
time.sleep(15)
page, rows = 1, []
while True:
data = session.get(f"{BASE}/v1/jobs/{job['job_id']}/results",
params={"page": page, "per_page": 1000}).json()
rows += data["results"]
if not data["has_more"]:
break
page += 1
for row in rows:
print(row["email"], row["details"].get("primary_label"))
  • Remove obviously broken addresses before sending: one address that isn’t valid email syntax makes the whole bulk call fail with 422.
  • Handle 402 (out of credits), 429 (over your API allowance) and 503 (new jobs paused, retry after the Retry-After header). Limits and errors →