BounceLens

BounceLens Email Check API

A free JSON API that runs the same checks as the BounceLens website. No API key, no signup and no daily limit. Send one address or a list, and get a status and the reasons for each.

The API does not log in to mail servers, so it cannot tell whether a mailbox exists. Addresses that pass are marked unconfirmed, not "verified".

Check one address

GET https://bouncelens.com/api/[email protected]

URL-encode the address. A + sign must be sent as %2B.

curl 'https://bouncelens.com/api/[email protected]'

Check a list

POST https://bouncelens.com/api/check
Content-Type: application/json

{"emails": ["[email protected]", "[email protected]"]}
curl -X POST https://bouncelens.com/api/check \
  -H 'Content-Type: application/json' \
  -d '{"emails": ["[email protected]", "[email protected]"]}'

Response

Both calls return the same shape: one result per address, in the order sent, plus totals.

{
  "summary": {"total": 2, "invalid": 0, "risky": 1, "unconfirmed": 1, "duplicates": 0,
              "disposable": 1, "role": 1, "free": 0, "typos": 0},
  "results": [
    {
      "input": "[email protected]",
      "email": "[email protected]",
      "status": "unconfirmed",
      "reasons": ["Format and domain OK, mailbox not confirmed",
                  "Role address (shared inbox, lower reply rate)"],
      "flags": {"disposable": false, "role": true, "free": false, "duplicate": false, "gateway": false},
      "did_you_mean": null,
      "provider": "Google",
      "mx": "aspmx.l.google.com"
    },
    {
      "input": "[email protected]",
      "email": "[email protected]",
      "status": "risky",
      "reasons": ["Disposable (throwaway) email domain"],
      "flags": {"disposable": true, "role": false, "free": false, "duplicate": false, "gateway": false},
      "did_you_mean": null,
      "provider": null,
      "mx": "mail.mailinator.com"
    }
  ]
}

Status

StatusMeaning
invalidWill bounce: bad format, the domain does not exist, has no mail server, or says it accepts no email.
riskyThrowaway domain, likely typo, no MX record, or the domain could not be looked up.
unconfirmedFormat and domain are OK. The mailbox itself is not confirmed.

Fields

FieldWhat it holds
inputThe address as you sent it.
emailThe cleaned address, or null when the format is invalid.
reasonsPlain-English reasons for the status.
flags.disposableThrowaway email domain.
flags.roleShared inbox such as info@ or sales@.
flags.freeFree provider such as Gmail or Yahoo.
flags.duplicateSame inbox as an earlier address in the same call. Gmail dots and +tags are ignored.
flags.gatewayThe domain's mail goes through a security gateway such as Proofpoint or Mimecast.
did_you_meanThe corrected address when the domain looks like a typo, otherwise null.
providerThe mail host when recognised (Google, Microsoft and others), otherwise null.
mxThe domain's first mail server, or null.

In summary, invalid + risky + duplicates + unconfirmed = total, so unconfirmed is the count of clean, unique addresses.

Limits

LimitValue
Addresses per call500
Different domains per call20. Split longer lists into several calls.
Calls20 per 10 seconds from one IP address

Errors

Errors come back as JSON with one field, for example {"error": "No emails given"}.

HTTP statusWhen
400No address was given, or the body is not JSON.
405A method other than GET or POST.
413More than 500 addresses or more than 20 different domains in one call.
429Too many calls. Wait 10 seconds and try again. This reply is not JSON.

OpenAPI file

The API is described in openapi.json (OpenAPI 3.0), ready to import into Postman and other tools. The API sends CORS headers, so it can be called from a browser.

Privacy

The API does not save the addresses you send. Only the domain name is looked up, through Cloudflare's public DNS. To keep an address out of the request URL, use the POST call. See the Privacy Policy.

Support

Questions or a wrong result? Email [email protected]. If a result looks wrong, the domain (the part after the @) is enough.