Skip to main content

Integration Guidelines

Best practices for integrating ClearBounce API into your application.

Rate Limits​

Each API key can make 100 requests per minute. Every API response includes these headers:

HeaderMeaning
X-RateLimit-LimitRequests allowed per minute
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-ResetSeconds until the window resets

When you exceed the limit, you'll receive a 429 Too Many Requests response with a Retry-After header (in seconds).

For lists, use batch verification instead of calling /verify in a loop. Need a higher limit? Contact support@clearbounce.net.

Handling Rate Limits​

async function verifyWithRetry(email, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch('https://api.clearbounce.net/api/v1/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({ email })
});

if (response.status === 429) {
// Wait for the time the API asks for, then retry
const retryAfter = Number(response.headers.get('Retry-After')) || 60;
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}

return response.json();
}
throw new Error('Rate limit exceeded after retries');
}

Timeouts​

  • Recommended timeout: 30 seconds
  • Maximum verification time: ~15 seconds for complex domains
  • Some mail servers respond slowly; plan accordingly

Best Practices​

1. Verify at Point of Entry​

// Good: Verify during registration
async function handleRegistration(email, password) {
const verification = await verifyEmail(email);

if (verification.status === 'undeliverable') {
throw new Error('Please enter a valid email address');
}

if (verification.status === 'risky') {
// Show warning but allow registration
console.warn('Email may have deliverability issues');
}

// Proceed with registration
await createUser(email, password);
}

2. Cache Results​

Email verification results are valid for 24-48 hours. Cache results to save credits:

const cache = new Map();

async function verifyWithCache(email) {
const cached = cache.get(email);
if (cached && Date.now() - cached.timestamp < 24 * 60 * 60 * 1000) {
return cached.result;
}

const result = await verifyEmail(email);
cache.set(email, { result, timestamp: Date.now() });
return result;
}

3. Handle Different Statuses​

function handleVerificationResult(result) {
switch (result.status) {
case 'deliverable':
// Safe to send
return { accept: true, message: 'Email verified' };

case 'undeliverable':
// Do not send
return { accept: false, message: 'Undeliverable email address' };

case 'risky':
// Your decision based on risk tolerance
if (result.checks.isDisposable) {
return { accept: false, message: 'Disposable emails not allowed' };
}
if (result.checks.isCatchAll) {
return { accept: true, message: 'Warning: catch-all domain' };
}
return { accept: true, message: 'Proceed with caution' };

case 'unknown':
// Could not verify - your decision
return { accept: true, message: 'Could not verify, proceed anyway' };

default:
return { accept: false, message: 'Verification failed' };
}
}

4. Use Bulk Verification for Lists​

For verifying more than 100 emails, use bulk verification:

// Upload emails for bulk verification
const uploadResponse = await fetch('https://api.clearbounce.net/api/v1/bulk/upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
emails: ['email1@example.com', 'email2@example.com', /* ... */]
})
});

const { jobId } = await uploadResponse.json();

// Poll the job status until it finishes
let job;
do {
await new Promise(resolve => setTimeout(resolve, 5000));

const statusResponse = await fetch(
`https://api.clearbounce.net/api/v1/bulk/status/${jobId}`,
{ headers: { 'X-API-Key': 'YOUR_API_KEY' } }
);

({ job } = await statusResponse.json());
} while (job.status === 'pending' || job.status === 'processing');

// Fetch the per-address results once the job is completed
if (job.status === 'completed') {
const resultsResponse = await fetch(
`https://api.clearbounce.net/api/v1/bulk/results/${jobId}`,
{ headers: { 'X-API-Key': 'YOUR_API_KEY' } }
);
const { results } = await resultsResponse.json();
}

Security Recommendations​

Never Expose API Keys​

// ❌ Bad: API key in client-side code
const API_KEY = 'cb_live_xxx'; // Exposed!

// ✅ Good: API key on server-side only
// Server endpoint that proxies to ClearBounce
app.post('/api/verify', async (req, res) => {
const result = await fetch('https://api.clearbounce.net/api/v1/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.CLEARBOUNCE_API_KEY
},
body: JSON.stringify({ email: req.body.email })
});
res.json(await result.json());
});

Validate Input​

function isValidEmailFormat(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}

// Only call API for valid-looking emails
if (!isValidEmailFormat(email)) {
return { status: 'undeliverable', reason: 'Invalid format' };
}

// Now call ClearBounce API
const result = await verifyEmail(email);

Webhook Integration (Coming Soon)​

For bulk verification, webhooks will notify you when jobs complete:

// Your webhook endpoint
app.post('/webhooks/clearbounce', (req, res) => {
const { jobId, status, results } = req.body;

if (status === 'completed') {
// Process results
processVerificationResults(results);
}

res.status(200).send('OK');
});