Bounce Protect

Clean your email lists before you send

API Documentation

Integrate Bounce Protect email validation into your app with our simple REST API. Each validation costs 1 credit.

Not a developer? You can validate email lists without writing any code using our upload dashboard. The API is for teams who want to integrate validation directly into their apps or workflows.

Quickstart

Validate your first email in under 60 seconds. Get your API key from the dashboard.

bash
curl -X POST https://bounceprotect.com/api/v1/validate/email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "john.doe@company.com"}'
json
{
  "email": "john.doe@company.com",
  "status": "valid",
  "status_reason": "valid_domain_with_mx",
  "status_explanation": "Domain mail servers detected",
  "deliverability_score": 92,
  "signals": {
    "is_disposable": false,
    "is_role_account": false,
    "is_free_provider": false,
    "is_possible_typo": false,
    "suggested_domain": null,
    "has_mx": true,
    "has_spf": true,
    "has_dmarc": true
  },
  "send_recommendation": "SEND",
  "credits_remaining": 4999
}

Authentication

All API requests must include your API key in the Authorization header using the Bearer scheme.

bash
Authorization: Bearer bp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Generate and manage your API keys in the API Keys dashboard. Never expose your API key in client-side code.

Validate email

POST/api/v1/validate/email

Validate a single email address. Costs 1 credit.

Request body

ParameterTypeDescription
emailrequiredstringThe email address to validate.

Example

bash
curl -X POST https://bounceprotect.com/api/v1/validate/email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "sarah@company.com"}'

Node.js

javascript
const response = await fetch('https://bounceprotect.com/api/v1/validate/email', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ email: 'sarah@company.com' }),
});

const result = await response.json();
console.log(result.status); // "valid" | "risky" | "invalid" | "unknown"

Python

python
import requests

response = requests.post(
    'https://bounceprotect.com/api/v1/validate/email',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    json={'email': 'sarah@company.com'}
)

result = response.json()
print(result['status'])  # "valid" | "risky" | "invalid" | "unknown"

PHP

php
$response = file_get_contents('https://bounceprotect.com/api/v1/validate/email', false,
  stream_context_create(['http' => [
    'method' => 'POST',
    'header' => "Authorization: Bearer YOUR_API_KEY\r\nContent-Type: application/json\r\n",
    'content' => json_encode(['email' => 'sarah@company.com']),
  ]])
);

$result = json_decode($response, true);
echo $result['status']; // "valid" | "risky" | "invalid" | "unknown"

Validate bulk

POST/api/v1/validate/bulk

Validate up to 100 emails in a single request. Costs 1 credit per email.

Request body

ParameterTypeDescription
emailsrequiredstring[]Array of email addresses to validate. Maximum 100 per request.

Example

bash
curl -X POST https://bounceprotect.com/api/v1/validate/bulk \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["sarah@company.com", "noreply@brand.com", "test@gmail.com"]}'

Response

json
{
  "results": [
    {
      "email": "sarah@company.com",
      "status": "valid",
      "status_reason": "valid_domain_with_mx",
      "deliverability_score": 92,
      "send_recommendation": "SEND",
      "signals": { "is_disposable": false, "is_role_account": false, "has_mx": true }
    },
    {
      "email": "noreply@brand.com",
      "status": "risky",
      "status_reason": "role_address",
      "deliverability_score": 35,
      "send_recommendation": "DO_NOT_SEND",
      "signals": { "is_disposable": false, "is_role_account": true, "has_mx": true }
    }
  ],
  "total": 2,
  "credits_used": 2,
  "credits_remaining": 4997
}

Node.js

javascript
const response = await fetch('https://bounceprotect.com/api/v1/validate/bulk', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    emails: ['sarah@company.com', 'noreply@brand.com', 'test@gmail.com'],
  }),
});

const { results, credits_remaining } = await response.json();
const safe = results.filter(r => r.send_recommendation === 'SEND');
console.log(`${safe.length} safe to send, ${credits_remaining} credits left`);

Account balance

GET/api/v1/account/balance

Returns your current credit balance.

bash
curl https://bounceprotect.com/api/v1/account/balance \
  -H "Authorization: Bearer YOUR_API_KEY"
json
{
  "credits_remaining": 4999,
  "dashboard_url": "https://bounceprotect.com/dashboard/usage"
}

Response fields

FieldTypeDescription
statusstring"valid" | "risky" | "invalid" | "unknown"
status_reasonstringMachine-readable reason code e.g. free_email_provider, disposable_domain, invalid_syntax
status_explanationstringPlain-English explanation of the status.
deliverability_scorenumber0-100 score. Higher is better. 90+ is safe to send, below 40 is high risk.
signals.is_disposablebooleanTemporary or disposable email provider detected.
signals.is_role_accountbooleanRole-based address detected (info@, noreply@, etc).
signals.is_free_providerbooleanFree email provider detected (Gmail, Yahoo, etc).
signals.is_possible_typobooleanPossible domain typo detected.
signals.suggested_domainstring | nullSuggested corrected domain if a typo was detected.
signals.has_mxboolean | nullDomain has valid MX records.
signals.has_spfboolean | nullDomain has SPF record configured.
signals.has_dmarcboolean | nullDomain has DMARC record configured.
send_recommendationstring"SEND" | "SEND_WITH_CAUTION" | "REVIEW" | "DO_NOT_SEND" — our recommendation based on all signals combined. The fastest way to action results without building your own scoring logic.
credits_remainingnumberYour remaining credit balance after this request.

Error codes

StatusCodeMeaning
400Bad RequestMissing or invalid request body. Check that email is a valid string.
401UnauthorizedMissing, invalid, or revoked API key.
402Payment RequiredInsufficient credits. Top up at bounceprotect.com/dashboard/usage.
429Too Many RequestsRate limit exceeded. Slow down your requests.
500Server ErrorSomething went wrong on our end. Try again.

Best practices

When to block vs allow at point of entry

When validating emails at signup or form submission, we recommend this approach:

StatusRecommendationReason
validAllowSafe to proceed. Domain has mail servers and passed all checks.
riskyAllow with cautionReview the signals. Free providers and catch-alls are often legitimate. Block disposable and role accounts if your use case requires it.
invalidBlockEmail will bounce. Do not send to invalid addresses.
unknownAllowCould not be verified. Treat as valid and monitor bounce rates.

Deliverability score guide

ScoreRatingAction
90-100ExcellentSafe to send. High confidence this is a real, active inbox.
70-89GoodGenerally safe. May be a free provider or have minor signals.
40-69ModerateReview before sending. Catch-all, new domain, or role account.
1-39High riskAvoid sending. Disposable, invalid syntax, or no mail servers.
0InvalidDo not send. Email is definitively invalid.

Rate limits

PlanRequests/secondBulk limit
Pro10 req/sUp to 100 emails per bulk request.
Agency50 req/sUp to 100 emails per bulk request.
Scale200 req/sUp to 100 emails per bulk request.

Rate limit headers are included in every response. If you exceed the limit you will receive a 429 response. Implement exponential backoff in your client.

Changelog

v1.0

March 2026 — Initial release

  • Single email validation endpoint
  • Bulk validation up to 100 emails per request
  • Account balance endpoint
  • API key management dashboard
  • Deliverability scoring (0-100)
  • Multi-signal detection: disposable, role accounts, domain typos, SPF/DMARC