Email validation

Check deliverability before you send — with the same engine that delivers your mail. One credit per fresh address; cache hits are free.

Single check

curl -X POST https://api.inkpigeon.com/api/v1/validate \
  -H "Authorization: Bearer $INKPIGEON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "someone@example.com"}'
{
  "email": "someone@example.com",
  "normalized_email": "someone@example.com",
  "status": "valid",              // valid | risky | invalid | unknown
  "valid": true,
  "deliverable": true,
  "syntax_valid": true,
  "domain_exists": true,
  "mx_found": true,
  "smtp_verified": true,          // live mailbox probe (when eligible)
  "catch_all": false,
  "disposable": false,
  "role_account": false,
  "free_provider": false,
  "typo_detected": false,
  "suggested_domain": null,
  "risk_score": 5,                // 0 safe … 100 risky
  "confidence": 0.95,
  "checks": [ {"stage": "syntax", "result": "pass", "detail": ""}, ... ],
  "warnings": [],
  "errors": [],
  "validation_time_ms": 84,
  "cached": false,
  "pending_recheck": false        // a deeper check is queued; verdict improves
}

unknown is a first-class outcome, not an error: the mail server gave no definitive answer (greylisting, catch-all, timeout). When that happens a background recheck is queued automatically and the stored verdict upgrades itself — pending_recheck: true tells you it is coming.

Bulk list cleaning

Upload a CSV (up to 50 MB), tell us which column holds the address, and download the same file back with validation_status, validation_risk and validation_reason columns appended. Rows that are obviously not addresses cost nothing; addresses you already validated are re-used for free.

# 1. Upload — returns the job with counters at zero
curl -X POST https://api.inkpigeon.com/api/v1/validate/bulk \
  -H "Authorization: Bearer $INKPIGEON_API_KEY" \
  -F "file=@list.csv" -F "email_column=Email"

# 2. Poll — counters advance as rows are validated
curl https://api.inkpigeon.com/api/v1/validate/bulk/{job_id} \
  -H "Authorization: Bearer $INKPIGEON_API_KEY"

# 3. Download the annotated CSV (your columns + verdict columns)
curl -OJ https://api.inkpigeon.com/api/v1/validate/bulk/{job_id}/download \
  -H "Authorization: Bearer $INKPIGEON_API_KEY"

# 4. Optionally apply the clean-up
curl -X POST https://api.inkpigeon.com/api/v1/validate/bulk/{job_id}/apply \
  -H "Authorization: Bearer $INKPIGEON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"suppress_invalid": true}'

Running out of credits mid-file doesn't fail the job — remaining rows come back marked unchecked, never guessed at. Files are deleted 7 days after the job finishes; the summary counters remain.

Verdicts

validSafe to send — the mailbox or domain accepts mail.
riskyDeliverable with caution: catch-all, role account, disposable, or no proper MX.
invalidDo not send: bad syntax, dead domain, or the server rejected the mailbox.
unknownNo definitive answer yet — retried automatically, never guessed.

Limits & metering

Validation credits are a monthly plan limit (Settings → Billing shows yours; GET /api/v1/validate/quota returns it). A fresh validation consumes one credit; a cached result within its TTL is free and never blocked. The standard X-RateLimit-* headers apply.

Want to try it without a key? The free checker runs the heuristic pipeline on single addresses, no signup.