Verification API
One call, and you know what happens if you send.
Check addresses at signup and before every send, so bad data never reaches your list or your sender reputation. Bearer token in, verdict out, with the score and reason codes behind it.
Request and response
The whole integration, on one screen.
No SDK, no client to construct, no wrapper to learn. A bearer token, one POST, and an object whose field names your code can branch on.
curl -X POST https://api.bounceintel.com/v1/check_email \
-H "Authorization: Bearer $BOUNCEINTEL_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'{
"input": "[email protected]",
"is_reachable": "safe",
"syntax": {
"domain": "stripe.com",
"username": "ada",
"is_valid_syntax": true
},
"mx": {
"accepts_mail": true,
"records": ["aspmx.l.google.com", "alt1.aspmx.l.google.com"]
},
"smtp": {
"can_connect_smtp": true,
"is_deliverable": true,
"is_catch_all": false,
"is_disabled": false,
"has_full_inbox": false
},
"misc": {
"is_disposable": false,
"is_role_account": false,
"is_b2c": false
},
"provider": "google_workspace",
"provider_rules_applied": true,
"score": {
"score": 100,
"category": "valid",
"sub_reason": "deliverable",
"safe_to_send": true,
"confidence": 0.97,
"confidence_level": "high",
"reason_codes": ["deliverable", "tenant_history_positive"]
},
"bounce_risk": {
"score": 3,
"category": "low",
"confidence": 0.94,
"action": "send",
"model_version": "br-2026.06",
"risk_factors": [
{
"signal": "smtp_is_deliverable",
"direction": "decreases_risk",
"contribution": -0.41,
"description": "Mailbox accepted the recipient at RCPT TO."
}
]
}
}- 01
One endpoint
POST /v1/check_email with an address. There is no session to establish.
- 02
Reason codes
Documented codes you can branch on, not free-text English.
- 03
Score you own
A 0 to 100 number, so your threshold is a config value rather than our decision.
- 04
Honest unknowns
An inconclusive check returns 200 with an unknown verdict, never a fabricated one.
- 05
Batch as a job
POST /v1/bulk takes a list and returns a job id you poll.
- 06
Rotatable keys
More than one live key, revoked independently, without downtime.
Getting started
From no account to a verdict in your own code.
- 01
Create a key
Keys are issued from the dashboard. You can hold more than one live at a time and revoke them independently, so a rotation costs no downtime.
- 02
Send the address
One POST with an Authorization header and a JSON body. There is no session to establish and no handshake before it.
- 03
Branch on the response
Read the verdict, or the score against your own threshold, or the reason codes. All three are in the same object, so you never make a second call to find out why.
- 04
Scale to lists
The same key submits a batch as a job and polls it. The verdicts are identical to the ones the single endpoint returns, because it is the same pipeline.
Reference
The surface you integrate against.
Four endpoints and two headers. The full reference, with a live playground, is in the documentation.
| Endpoint or header | Kind | What it does |
|---|---|---|
| POST /v1/check_email | synchronous | Verify one address and get the scored report back in the same response. This is the call almost every integration makes. |
| POST /v1/bulk | job | Submit a list and get a job id. Accepts far more addresses than you would want to hold a connection open for. |
| GET /v1/bulk/{job_id} | job | Poll a job for its state and how far through it is, so your own UI can show progress rather than a spinner. |
| GET /v1/bulk/{job_id}/results | json | csv | Fetch a finished job's rows, paged, as JSON or as the same CSV the dashboard downloads. |
| Authorization: Bearer | header | How every request authenticates. Keep the key on your server: a key that reaches the browser is a public credit balance. |
| 429 / Retry-After | header | What you get if you outrun your plan's rate limit. Wait the number of seconds in the header and retry; nothing is charged for a rejected request. |
FAQ
What developers ask first
How do I authenticate?
An Authorization header with a bearer token. Keep the key on your server: a key that reaches the browser is a public credit balance.
What should I do with an unknown verdict?
Let the user through, flag the record and re-check later. Most unknowns are the receiving server declining to answer rather than a fact about the address.
Which plans include API keys?
Any paid plan, monthly or pay as you go. Free accounts verify in the dashboard, which is enough to see the response shape first.
Can I call it from the browser?
No. Proxy it through your own server. A key in the browser is a public credit balance.
What are the rate limits?
They are set per plan rather than published as one global number, because a signup-form integration and a nightly list run need very different shapes. When you exceed yours the API answers 429 with a Retry-After header and does not charge for the request.
Is there an SDK?
No, and that is the point. One endpoint with a JSON body needs no client library, and a thin wrapper is a dependency you have to keep current for no gain. Every language in the samples above uses its own standard HTTP client.
Read the response before you write against it.
100 credits on signup, no card. Run real addresses and see the exact object your code will get.