Email Verification API Documentation
Real-time single and bulk email validation. Webhooks, job history, detailed results. Works with Python, PHP, Node.js, and any HTTP client.
Contents
Base URL
https://bounceguard.net/api/v1All endpoints are relative to this base URL. Requests and responses use JSON (except file upload which uses multipart/form-data).
Authentication
All requests must include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY- Log in to your BounceGuard account
- Go to the Integration page
- Click "Generate New API Key" and copy it
Possible Results
Mailbox exists and accepts email.
✓ Safe to send
Domain accepts all emails — specific mailbox unconfirmed.
⚠ Risky — may bounce
Mailbox does not exist or address is invalid.
✗ Do not send
No MX records or DNS problem with the domain.
✗ Invalid domain
Rate Limits & Credits
- Each email validation costs 1 credit — single or bulk
- Credits never expire — buy once, use anytime
- Bulk jobs deduct credits when the job completes
- Use
GET /api/v1/creditsto monitor your balance anytime
Single Email Validation
Validate one email address in real-time. Returns result immediately. Each call costs 1 credit.
curl -X POST https://bounceguard.net/api/v1/validate-email \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "username@example.com"}'Response
{
"status": "success",
"email": "username@example.com",
"result": "Valid",
"reason": "Mailbox confirmed to exist",
"remaining_credits": 4999
}Error Responses
// 401 — Invalid or missing API key
{"status": "error", "message": "Invalid API key"}
// 402 — Insufficient credits
{"error": "insufficient_credits", "message": "Not enough credits. You have 0 remaining."}
// 400 — Invalid email format
{"error": "validation_error", "message": "Invalid email format"}
// 404 — File not found
{"error": "not_found", "message": "File not found or unauthorized"}Bulk Email Validation
How it works
/bulk-validate. Response has file_id and URLs./bulk-validate/status/{file_id} every 3–5s until "status": "complete"./bulk-validate/download/{file_id} for the validated CSV.1. Upload CSV
curl -X POST https://bounceguard.net/api/v1/bulk-validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@emails.csv"Response
{
"status": "queued",
"file_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"total_emails": 500,
"urls": {
"status": "https://bounceguard.net/api/v1/bulk-validate/status/a1b2c3d4-...",
"results": "https://bounceguard.net/api/v1/bulk-validate/results/a1b2c3d4-...",
"download": null
},
"webhook": "will fire when complete",
"message": "Validation queued."
}2. Check Status
curl https://bounceguard.net/api/v1/bulk-validate/status/YOUR_FILE_ID \
-H "Authorization: Bearer YOUR_API_KEY"{
"status": "complete",
"file_id": "a1b2c3d4-...",
"processed": 500,
"total": 500,
"results": { "valid": 420, "bad": 55, "catch_all": 20, "domain_invalid": 5 },
"download_url": "https://bounceguard.net/api/v1/bulk-validate/download/a1b2c3d4-..."
}3. Download Results
curl https://bounceguard.net/api/v1/bulk-validate/download/YOUR_FILE_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-o validated_results.csvBulk API — Code Examples
Python
import requests, time
API_KEY = "YOUR_API_KEY"
BASE = "https://bounceguard.net/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1. Upload
with open("emails.csv", "rb") as f:
res = requests.post(f"{BASE}/bulk-validate", headers=HEADERS, files={"file": f})
file_id = res.json()["file_id"]
print(f"Queued: {file_id}")
# 2. Poll
while True:
s = requests.get(f"{BASE}/bulk-validate/status/{file_id}", headers=HEADERS).json()
print(f"Progress: {s['processed']}/{s['total']}")
if s["status"] == "complete":
print("Results:", s["results"])
break
time.sleep(4)
# 3. Download
csv = requests.get(f"{BASE}/bulk-validate/download/{file_id}", headers=HEADERS)
open("validated_results.csv", "wb").write(csv.content)
print("Saved!")Node.js
const fs = require('fs');
const FormData = require('form-data');
const API_KEY = 'YOUR_API_KEY';
const BASE = 'https://bounceguard.net/api/v1';
const HEADERS = { 'Authorization': `Bearer ${API_KEY}` };
async function bulkValidate(csvPath) {
const form = new FormData();
form.append('file', fs.createReadStream(csvPath));
const { file_id } = await (await fetch(`${BASE}/bulk-validate`, {
method: 'POST', headers: { ...HEADERS, ...form.getHeaders() }, body: form
})).json();
console.log('Queued:', file_id);
while (true) {
await new Promise(r => setTimeout(r, 4000));
const s = await (await fetch(`${BASE}/bulk-validate/status/${file_id}`, { headers: HEADERS })).json();
console.log(`${s.processed}/${s.total}`);
if (s.status === 'complete') { console.log('Results:', s.results); break; }
}
const csv = await (await fetch(`${BASE}/bulk-validate/download/${file_id}`, { headers: HEADERS })).text();
fs.writeFileSync('validated_results.csv', csv);
console.log('Saved!');
}
bulkValidate('emails.csv');PHP
<?php
$API_KEY = 'YOUR_API_KEY';
$BASE = 'https://bounceguard.net/api/v1';
$HEADERS = ["Authorization: Bearer $API_KEY"];
// Upload
$ch = curl_init("$BASE/bulk-validate");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true,
CURLOPT_HTTPHEADER=>$HEADERS, CURLOPT_POSTFIELDS=>['file'=>new CURLFile('emails.csv')]]);
$data = json_decode(curl_exec($ch), true);
$file_id = $data['file_id'];
// Poll
while (true) {
sleep(4);
$ch = curl_init("$BASE/bulk-validate/status/$file_id");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>$HEADERS]);
$s = json_decode(curl_exec($ch), true);
echo "{$s['processed']}/{$s['total']}\n";
if ($s['status'] === 'complete') { print_r($s['results']); break; }
}
// Download
$ch = curl_init("$BASE/bulk-validate/download/$file_id");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>$HEADERS]);
file_put_contents('validated_results.csv', curl_exec($ch));Webhooks NEW
Configure a webhook URL to receive automatic notifications when bulk validation completes. No polling required.
Set Webhook
curl -X POST https://bounceguard.net/api/v1/webhook \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://yourserver.com/webhook"}'{
"message": "Webhook configured successfully",
"webhook_url": "https://yourserver.com/webhook",
"ping_status": 200,
"note": "A test ping was sent to your webhook URL"
}Webhook Payload
{
"event": "validation.complete",
"file_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"filename": "emails.csv",
"total": 500,
"results": {
"valid": 420, "invalid": 55, "catch_all": 20, "domain_invalid": 5
},
"download_url": "https://bounceguard.net/api/v1/bulk-validate/download/a1b2c3d4-...",
"timestamp": "2026-04-29T17:29:55.571395Z"
}Python — Zero Polling Flow
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://bounceguard.net/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Set webhook once
requests.post(f"{BASE}/webhook", headers=HEADERS, json={"url": "https://yourserver.com/webhook"})
# Upload — webhook fires automatically when done. No polling needed!
with open("emails.csv", "rb") as f:
res = requests.post(f"{BASE}/bulk-validate", headers=HEADERS, files={"file": f})
print("Queued:", res.json()["file_id"])Credits & Usage NEW
curl https://bounceguard.net/api/v1/credits \
-H "Authorization: Bearer YOUR_API_KEY"{
"credits": { "total": 10000, "used": 1500, "remaining": 8500 },
"plan": "free",
"user": { "email": "you@example.com", "username": "yourname" }
}Job History NEW
Retrieve all past bulk validation jobs with stats, progress, and download URLs. Paginated.
curl "https://bounceguard.net/api/v1/history?page=1&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"{
"jobs": [
{
"file_id": "a1b2c3d4-...",
"filename": "emails.csv",
"status": "complete",
"total": 500,
"processed": 500,
"progress_pct": 100.0,
"results": { "valid": 420, "bad": 55, "catch_all": 20, "domain_invalid": 5, "valid_pct": 84.0 },
"download_url": "https://bounceguard.net/api/v1/bulk-validate/download/a1b2c3d4-...",
"created_at": "2026-04-29T17:22:15Z",
"processing_time_sec": 191
}
],
"pagination": {
"page": 1, "limit": 10, "total_jobs": 24, "total_pages": 3,
"has_next": true, "has_prev": false
}
}Detailed Results NEW
Get individual email results for a completed job. Filter by status and paginate through large datasets.
valid, invalid, catch_all, domain_invalid, all# Get only valid emails
curl "https://bounceguard.net/api/v1/bulk-validate/results/YOUR_FILE_ID?status=valid" \
-H "Authorization: Bearer YOUR_API_KEY"{
"file_id": "a1b2c3d4-...", "filename": "emails.csv", "filter": "valid",
"emails": [
{ "email": "john@example.com", "status": "valid", "status_text": "Valid" },
{ "email": "info@catchall.com", "status": "catch_all", "status_text": "Catch-all" }
],
"summary": { "total": 500, "valid": 420, "invalid": 55, "catch_all": 20, "domain_invalid": 5, "valid_pct": 84.0 },
"pagination": { "page": 1, "limit": 100, "total_items": 420, "total_pages": 5, "has_next": true },
"download_url": "https://bounceguard.net/api/v1/bulk-validate/download/a1b2c3d4-..."
}Auto Validate & Download EASY
The simplest way to use BounceGuard API — one script does everything automatically: uploads your file, waits for validation to complete, and saves the results to your Downloads folder. No manual steps, no file IDs to track.
Python — One Script Does Everything
Install Python requests library first (only needed once):
pip3 install requestsThen run this script — change only API_KEY and csv_path:
import requests, time, os
API_KEY = "YOUR_API_KEY" # Get from Integration page
BASE = "https://bounceguard.net/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
SAVE_FOLDER = os.path.expanduser("~/Downloads") # Change if needed
def validate_and_download(csv_path):
# Step 1: Upload file
print("📤 Uploading file...")
with open(csv_path, "rb") as f:
res = requests.post(f"{BASE}/bulk-validate", headers=HEADERS, files={"file": f})
data = res.json()
if data.get("status") != "queued":
print("❌ Upload failed:", data.get("message"))
return
file_id = data["file_id"]
total = data["total_emails"]
print(f"✅ Uploaded! {total} emails queued (file_id: {file_id})")
# Step 2: Auto poll until complete
print("⏳ Validating emails...")
while True:
status = requests.get(
f"{BASE}/bulk-validate/status/{file_id}", headers=HEADERS
).json()
processed = status.get("processed", 0)
print(f" {processed}/{total} processed...")
if status.get("status") == "complete":
print(f"✅ Validation complete!")
print(f" Valid: {status['results']['valid']}")
print(f" Bad: {status['results']['bad']}")
print(f" Catch-all: {status['results']['catch_all']}")
break
time.sleep(5) # Check every 5 seconds
# Step 3: Auto download
print("📥 Downloading results...")
download_url = status.get("download_url")
if not download_url:
print("❌ Download URL not ready. Try again in a moment.")
return
csv_res = requests.get(download_url, headers=HEADERS)
filename = os.path.join(SAVE_FOLDER, f"results_{file_id[:8]}.csv")
open(filename, "wb").write(csv_res.content)
print(f"✅ Saved to: {filename}")
# ── Run it ──
validate_and_download("/Users/yourname/Downloads/emails.csv") # Change this pathWhat the output looks like
📤 Uploading file...
✅ Uploaded! 500 emails queued (file_id: abc12345-...)
⏳ Validating emails...
0/500 processed...
100/500 processed...
300/500 processed...
500/500 processed...
✅ Validation complete!
Valid: 420
Bad: 55
Catch-all: 20
📥 Downloading results...
✅ Saved to: /Users/yourname/Downloads/results_abc12345.csvEmail and Status.Status values: Valid, Bad, Catch-all, Domain Issue
Single Email — Code Examples
Python
import requests
response = requests.post(
"https://bounceguard.net/api/v1/validate-email",
headers={"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"},
json={"email": "username@example.com"}
)
print(response.json())Node.js
fetch('https://bounceguard.net/api/v1/validate-email', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'username@example.com' })
}).then(r => r.json()).then(console.log);PHP
<?php
$ch = curl_init('https://bounceguard.net/api/v1/validate-email');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true,
CURLOPT_HTTPHEADER=>['Authorization: Bearer YOUR_API_KEY','Content-Type: application/json'],
CURLOPT_POSTFIELDS=>json_encode(['email'=>'username@example.com'])]);
echo curl_exec($ch);Common Use Cases
Prevent Fake Signups
Validate emails in real-time during registration. Fast responses for seamless UX.
Clean Email Lists at Scale
Upload entire CRM exports as CSV. Bulk API processes thousands in background. Configure webhook — get notified automatically when done.
CRM Integration
Export from HubSpot/Salesforce → validate → re-import only valid emails. Use /history to track all past jobs and /bulk-validate/results/{id}?status=valid to extract clean emails programmatically.
Best Practices
- For lists over 100 emails — always use Bulk API, not single validation in a loop
- Use webhooks in production — eliminates polling overhead entirely
- Store
file_idfrom uploads — results re-downloadable anytime via/history - Monitor credits via
GET /credits— top up before running out - Regenerate API key immediately if you suspect it's compromised
Support
Need help? Reach out at support@bounceguard.net — we respond within 24 hours on business days.
Happy validating! 🚀