Product Guide
Everything you need to go from a messy contact list to a clean, send-ready one. Building an integration instead? Jump to the API reference.
Getting started
Create an account and you land in the dashboard with 10,000 free credits, no card required. The sidebar is the whole product: Verify Email for one-off checks, Bulk Lists for cleaning whole files, Deliverability for domain audits, History for your activity and credit ledger, and API for programmatic access.
Verify one email
Open Verify Email, type an address and hit verify. InboxValid has a live SMTP conversation with the receiving mail server, so the answer reflects whether the mailbox exists right now, not what a stale database remembers. Each check costs 1 credit and takes about 2 seconds.
You get back a status pill plus the details behind it:
| Status | What to do with it |
|---|
| valid | Safe to send |
| invalid | Remove it; it will bounce |
| catch_all | The domain accepts everything, so the mailbox can't be confirmed. Send cautiously. |
| risky | Deliverable but flagged, for example a role address like info@. Decide per campaign. |
| disposable | A throwaway inbox. Remove it from any long-term list. |
| unknown | The server wouldn't give a clear answer (greylisting and similar). Re-verify later. |
The risk score (0 to 100, lower is safer) combines the SMTP outcome with flags like role account, free provider and catch-all, so you can set your own cutoff instead of trusting a single label.
Clean a bulk list
Open Bulk Lists. You can paste addresses directly or upload a file: CSV, Excel (.xlsx) or JSON, up to 50,000 emails per job. For files, InboxValid auto-detects which column holds the emails; click a different column header in the preview if it guessed wrong. Duplicates and non-email values are dropped before anything is charged.
Credits are held upfront, 1 per email, and anything unused is refunded when the job settles. While the job runs you see a live progress bar and counters. When it finishes you get:
Metrics and charts. Per-status counts with percentages and a breakdown donut so you can judge list quality at a glance, for example "82% valid, 9% invalid, 6% catch-all".
Email search. Rather than scrolling thousands of rows, type any part of an address to look up its exact result, status, risk score and reason.
CSV export. Download all results, or filter the export to one status. "Valid only" gives you a send-ready file for your campaign tool.
Deliverability audits
Clean lists only matter if your own domain is set up to deliver. Open Deliverability, enter a sending domain and InboxValid grades it (A to F) across 8 checks: MX, SPF, DKIM, DMARC, PTR, DNSBL blocklist listing, MTA-STS and BIMI. Each failing check comes with a concrete recommendation, and you get a verdict on whether the domain passes the Gmail, Yahoo and Microsoft bulk-sender requirements. An audit costs 5 credits.
Spam-trap risk
A mailbox can accept mail and still be unsafe for a campaign. Read the spam-trap guide to understand pristine, recycled, typo and domain traps, and how InboxValid returns known or suspected trap evidence as a risky signal.
Credits & billing
| Action | Cost |
|---|
| Verify one email | 1 credit |
| Bulk job | 1 credit per email, unused refunded |
| Deliverability audit | 5 credits |
There are three ways to hold credits, and you are on exactly one at a time. Free grants its credits once, when you sign up, and never tops them up. A subscription grants its allowance every cycle and rolls the unused part into the next one, for as long as it runs; cancel and the rolled-over balance goes with it. Credit packs are bought outright under Buy Credits (UPI, card or netbanking via Razorpay) and are valid for 12 months from purchase, with volume tiers lowering the per-credit price automatically. A subscription and credit packs cannot run at the same time, so packs are unavailable while a subscription is active.
Plan credits are always spent before bought ones, so a plan ending never takes credits you paid for. History keeps the full ledger: every grant, charge, refund and expiry with the balance after each movement, plus an activity trail of everything done on the account.
API keys
The API page in the dashboard manages your keys and includes a quickstart. Create a key, copy it when shown (it appears exactly once) and pass it as a bearer token:
Authorization: Bearer iv_live_...
Everything the dashboard does is available over the API: verify at signup, clean lists from your CRM, watch job progress over SSE and export results as CSV. See the API reference for every endpoint with request and response examples.
Try it on your own list10,000 free credits cleans a real list, not a demo.
Get started freeAPI Docs
The InboxValid REST API lets you verify emails, audit domain deliverability and run bulk jobs from your own code. Every endpoint returns JSON and is authenticated with an API key. New to the product? Start with the product guide.
Authentication
Create an API key from the API page in the dashboard. The full key (starting with iv_live_) is shown once at creation, so store it securely. Pass it as a bearer token on every request:
Authorization: Bearer iv_live_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
The base URL is https://api.example.com. Requests without a valid key return 401 with { "error": "invalid api key" }.
Credits & errors
Verification is metered in credits: 1 credit per single verify, 1 per email in a bulk job (held upfront, unused credits refunded) and 5 per deliverability audit. New accounts start with 10,000 free credits.
Errors always have the shape { "error": "message" }:
| Status | Meaning |
|---|
| 400 | Bad request, for example a malformed email or domain |
| 401 | Missing or invalid API key |
| 402 | Insufficient credits (code: "insufficient_credits") |
| 403 | Organization suspended |
| 404 | Resource not found |
| 429 | Rate limit exceeded, or your plan's daily credit cap is spent (code: "daily_cap_reached", with cap) |
| 502 | Verification engine temporarily unavailable |
Verify an email
POST/v1/verify
Runs a live check on a single address: syntax, MX lookup and an SMTP conversation with the receiving server, plus catch-all, disposable, role-account and free-provider detection. Costs 1 credit.
curl -X POST https://api.example.com/v1/verify \
-H "Authorization: Bearer iv_live_..." \
-H "Content-Type: application/json" \
-d '{"email": "sara@acmecorp.com"}'
{
"email": "sara@acmecorp.com",
"domain": "acmecorp.com",
"status": "valid",
"sub_status": null,
"risk_score": 12,
"mx_found": true,
"mx_host": "aspmx.l.google.com",
"provider": "Gmail",
"is_role": false,
"is_disposable": false,
"is_catch_all": false,
"trap_kind": null,
"trap_confidence": null,
"free": false
}
status is one of:
| Status | Meaning |
|---|
| valid | The mailbox exists and accepts mail |
| invalid | The mailbox was rejected by the server |
| catch_all | The domain accepts mail for any address |
| risky | Deliverable but flagged, for example a role account |
| disposable | A temporary or throwaway domain |
| unknown | Inconclusive, for example greylisting; not charged against your list quality |
sub_status adds detail when available (for example mailbox_not_found or mailbox_full), and risk_score is 0 to 100, lower is safer. When maintained intelligence finds a trap signal, the top-level status remains risky and the optional trap_kind and trap_confidence fields describe the evidence. No verifier can guarantee detection of every private trap.
Deliverability audit
POST/v1/deliverability
Grades a sending domain across 8 checks: MX, SPF, DKIM, DMARC, PTR, DNSBL listing, MTA-STS and BIMI, and tells you whether it passes the Gmail, Yahoo and Microsoft bulk-sender rules. Costs 5 credits.
curl -X POST https://api.example.com/v1/deliverability \
-H "Authorization: Bearer iv_live_..." \
-H "Content-Type: application/json" \
-d '{"domain": "acmecorp.com"}'
{
"domain": "acmecorp.com",
"score": 85,
"grade": "A",
"passes_bulk_rules": true,
"provider": "Gmail",
"checks": {
"spf": { "state": "pass", "detail": "SPF record found: v=spf1 ...", "recommendation": null },
"dkim": { "state": "pass", "detail": "DKIM selectors found", "recommendation": null },
"dmarc": { "state": "pass", "detail": "DMARC policy: reject", "recommendation": null },
"mx": { "state": "pass", "detail": "MX records: aspmx.l.google.com (10)" },
"ptr": { "state": "warn", "detail": "PTR record not found for sending IP",
"recommendation": "Configure reverse DNS on your sending IP" },
"dnsbl": { "state": "pass", "detail": "Not listed on common blocklists" },
"mta_sts": { "state": "warn", "detail": "No MTA-STS policy" },
"bimi": { "state": "warn", "detail": "No BIMI record" }
}
}
Each check is pass, warn or fail, with a human-readable detail and a fix recommendation where one applies.
Bulk jobs
POST/v1/jobs/bulk
Verifies up to 50,000 emails per job. The list is de-duplicated automatically and credits are held upfront, 1 per email; anything unused is refunded when the job settles.
curl -X POST https://api.example.com/v1/jobs/bulk \
-H "Authorization: Bearer iv_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "Q3 leads", "emails": ["a@acme.com", "b@example.org"]}'
{ "id": "job_cuid", "total": 2, "status": "queued" }
To carry extra columns (e.g. name, company) through to your results and CSV export, send rows instead of emails, plus metaColumns listing the keys to include:
curl -X POST https://api.example.com/v1/jobs/bulk \
-H "Authorization: Bearer iv_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Q3 leads",
"metaColumns": ["first_name", "company"],
"rows": [
{"email": "a@acme.com", "meta": {"first_name": "Ada", "company": "Acme"}},
{"email": "b@example.org", "meta": {"first_name": "Ben", "company": "Example"}}
]
}'
POST/v1/jobs/upload
For large lists, upload the file itself (multipart) instead of a JSON body, the server streams it, so jobs can reach the configured maximum (far above the inline ~50k body limit). Send the file plus optional name, emailColumn (header name; omit for a plain .txt list) and metaColumns (JSON array of headers to keep) as form fields. The server counts the rows, holds the credits, and queues verification; the response includes the record total.
curl -X POST https://api.example.com/v1/jobs/upload \
-H "Authorization: Bearer iv_live_..." \
-F "name=Q3 leads" \
-F "emailColumn=email" \
-F 'metaColumns=["first_name","company"]' \
-F "file=@leads.csv"
{ "id": "job_cuid", "status": "queued", "total": 1500 }
To check the count and credit cost before committing, add -F "preflight=true". The job is created as pending and the response adds cost, balance and sufficient; nothing is charged until you POST /v1/jobs/{id}/confirm.
{ "id": "job_cuid", "status": "pending", "total": 1500,
"cost": 1500, "balance": 5000, "sufficient": true }
GET/v1/jobs/{id}
Returns the job with live counters:
{
"id": "job_cuid",
"name": "Q3 leads",
"status": "running",
"total": 2000,
"processed": 1250,
"valid": 980, "invalid": 170, "risky": 40,
"catchAll": 35, "unknown": 20, "disposable": 5,
"createdAt": "2026-06-12T09:00:00.000Z",
"finishedAt": null
}
GET /v1/jobs lists your jobs, newest first. Supports take (max 100, default 100) and skip for pagination, and returns a total count alongside the jobs array.
GET/v1/jobs/{id}/results
Pages through per-email results. Supports ?status=valid|invalid|risky|catch_all|unknown|disposable, q (case-insensitive email search), take (max 1000, default 200) and skip for pagination. The response includes a total count of matching rows.
curl "https://api.example.com/v1/jobs/job_cuid/results?status=valid&take=500" \
-H "Authorization: Bearer iv_live_..."
GET/v1/jobs/{id}/export
Downloads the full results as a CSV file (columns: email, domain, status, sub_status, risk_score, provider, is_catch_all, is_role, is_disposable, trap_kind, trap_confidence, free). Add ?status=valid to export only one status, for example your cleaned send-ready list.
curl -OJ "https://api.example.com/v1/jobs/job_cuid/export?status=valid" \
-H "Authorization: Bearer iv_live_..."
GET/v1/jobs/{id}/events
A Server-Sent Events stream of live progress. Each message is a JSON snapshot of the counters above; the stream closes when the job completes or fails.
data: {"processed": 1250, "total": 2000, "status": "running", "valid": 980, ...}
data: {"processed": 2000, "total": 2000, "status": "completed", ...}
Account & usage
GET/me
Returns your organization, plan and current credit balance.
GET/v1/stats
{
"creditBalance": 950,
"creditsUsed": 50,
"emailsVerified": 50,
"jobsRun": 1,
"deliverabilityAudits": 0
}
GET/v1/ledger
The append-only credit ledger: grants, charges and refunds with the balance after each movement.
GET/v1/activity
The audit trail of everything done on the account, via dashboard or API key. Filter with ?action=verify and page with take (max 500).
Ready to integrate?Create an account, grab an API key and verify your first 100 emails free.
Get your API key