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:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute |
X-RateLimit-Remaining | Requests left in the current window |
X-RateLimit-Reset | Seconds 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');
});