Verify every email before you sendFewer bounces. A safe sender reputation.

Clean your list before a campaign. We check each address down to the mailbox — and when nobody can be sure, we say so instead of guessing.

100 free credits when you sign up

Check an address
jane.doe@acme.comVerify
Safe mailbox_exists

The mailbox exists. Send.

Domain
acme.com
Mail server
aspmx.l.google.com
Provider
Google
mark@northwind.ioVerify
Invalid mailbox_not_found

The mail server says this mailbox doesn't exist.

Domain
northwind.io
Mail server
mail.northwind.io
Provider
Other
anyone@contoso.comVerify
Catch-all catch_all_domain

The domain accepts every address, so nobody can confirm this one.

Domain
contoso.com
Mail server
contoso-com.mail.protection.outlook.com
Provider
Microsoft 365
ceo@fabrikam.ioVerify
Unknown mailbox_full

The inbox is full right now. Check again later — no credit used.

Domain
fabrikam.io
Mail server
mx1.fabrikam.io
Provider
Other
Down to the mailboxWe ask the mail server itself.
Never a false “safe”Catch-all stays catch-all.
Unknown is freeNo sure answer, no credit used.
Nothing is sentWe stop before any email goes out.
How it works

A clean list in three steps

1

Upload a CSV or call the API

Drop in your list, or send addresses from your own app.

2

We check every address

The syntax, the domain's mail servers, then the mailbox itself over SMTP — without sending an email.

SyntaxListsDomainMailbox
3

Get the clean list

Download it as a CSV, or get the results on your webhook.

The results

Four answers. All of them honest.

Some mail servers won't tell anyone whether a mailbox exists. When that happens, you'll know.

Safe

The mailbox exists

The mail server confirmed it, and the domain doesn't accept every address.

Send
Invalid

It can't receive mail

A domain without a mail server, or a mailbox that doesn't exist.

Remove it
Catch-all

Nobody can confirm it

The domain accepts every address, real or not. We never call it safe.

Your call — send with care
Unknown

No sure answer yet

A temporary reply, a full inbox or a throwaway address. Unknown results don't cost a credit.

Leave out or re-check later
Features

Everything a clean list needs

Bulk listsUpload a CSV. It's checked in the background — download the clean list when it's done.
API and signed webhooksVerify in real time, or send a list and get the results on your webhook, signed.
Catch-all detectionDomains that accept every address are found and flagged — never passed off as safe.
Disposable, role and free flagsThrowaway addresses, info@ and sales@ inboxes, free webmail — flagged on every result.
Instant re-checksFresh results are reused, so checking an address again takes no time.
A real mailbox checkWe ask each address's own mail server whether the mailbox exists — no guessing from patterns.
For developers

One address, or a whole list. A clear answer.

Check an address in real time, or send a list and get the results on your webhook. Only status: "safe" is safe to send to — the reason says why.

  • An API key per appIn the X-API-Key header.
  • Real-time checksOne at a time per account, up to 60 a minute — submit a list to check many.
  • Bulk listsUp to 100,000 addresses in one call — a task id back in seconds, results as JSON or CSV.
  • Signed webhooksWhen a list is done, we post to your URL — signed, so you know it's us.
Read the API docs
Request
curl -X POST https://verifier.salesbullet.ai/api/v1/verify \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane.doe@acme.com"}'
Response
{
  "email": "jane.doe@acme.com",
  "status": "safe",
  "reason": "mailbox_exists",
  "is_safe_to_send": true,
  "is_valid_syntax": true,
  "is_disposable": false,
  "is_role_account": false,
  "is_free_email": false,
  "domain": "acme.com",
  "mx_accepts_mail": true,
  "mx_records": ["aspmx.l.google.com", "alt1.aspmx.l.google.com"],
  "mx_host": "aspmx.l.google.com",
  "provider": "google",
  "checked_at": "2026-10-10T09:14:03.4129875Z",
  "from_cache": false
}
Send a list
curl -X POST https://verifier.salesbullet.ai/api/v1/bulk \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "October campaign",
       "emails": ["jane.doe@acme.com", "mark@northwind.io"],
       "callback_url": "https://your-app.com/hooks/verifier"}'
Response — 202
{
  "task_id": "bk_3f9c1a2b7d4e5f6a7b8c",
  "status": "queued",
  "total": 2
}
Get the results
curl https://verifier.salesbullet.ai/api/v1/bulk/bk_3f9c1a2b7d4e5f6a7b8c/results?format=csv \
  -H "X-API-Key: YOUR_API_KEY"
Response — CSV
email,status,reason,is_safe_to_send,is_disposable,is_role_account,is_free_email
jane.doe@acme.com,safe,mailbox_exists,true,false,false,false
mark@northwind.io,invalid,mailbox_not_found,false,false,false,false
We post to your URL
POST https://your-app.com/hooks/verifier
X-Event: bulk.completed
X-Event-Id: evt_6f1d2c3b9a8e7d6c5b4a3f2e
X-Timestamp: 1791624107
X-Signature: hex HMAC-SHA256 of "{X-Timestamp}.{body}" with your secret
Body
{
  "event": "bulk.completed",
  "event_id": "evt_6f1d2c3b9a8e7d6c5b4a3f2e",
  "created_at": "2026-10-10T09:21:47.5304183Z",
  "data": {
    "task_id": "bk_3f9c1a2b7d4e5f6a7b8c",
    "name": "October campaign",
    "status": "completed",
    "source": "api",
    "total": 2,
    "unique_total": 2,
    "checked": 2,
    "counts": { "safe": 1, "invalid": 1, "catch_all": 0, "unknown": 0 },
    "credits_reserved": 2,
    "credits_charged": 2,
    "file_name": null,
    "created_at": "2026-10-10T09:14:03.512094Z",
    "started_at": "2026-10-10T09:14:03.598731Z",
    "completed_at": "2026-10-10T09:21:47.401265Z",
    "error": null,
    "results_url": "https://verifier.salesbullet.ai/api/v1/bulk/bk_3f9c1a2b7d4e5f6a7b8c/results"
  }
}
Pricing

Credits only for sure answers

List prices from $15 for 5,000 checks. Unknown results are free, and you start with 100 free credits.

See pricing
$0.80per 1,000 — our lowest rate
100free credits on sign-up
1 creditper address checked
$0for unknown results
Questions

Good to know

How do you know a mailbox exists?

We ask the domain's own mail server, the same way an email would be delivered — and stop before anything is sent. The person never gets an email from us.

Why isn't every address “safe” or “invalid”?

Some domains accept every address, and some mail servers only answer later. We tell you that (catch-all or unknown) rather than guess — a wrong “safe” is what causes bounces.

Should I send to catch-all addresses?

It's your call. Many are real, but nobody can confirm them. If your sender reputation matters most, leave them out or send to them in small batches.

What does a check cost?

One credit per address; unknown results don't cost a credit. You get 100 free when you sign up — need more? Verification comes with every SalesBullet plan.

Can I use it from my own app?

Yes. Check one address in real time with the API, or send a whole list and get the results on a signed webhook. See the API docs.

Send to real people only.

Start with 100 free credits. Clean your next list in minutes.