API Documentation
Validate email addresses over a simple REST API. All endpoints live under https://skipbounce.com/api/v1 and return JSON.
API access requires a Pro or Scale plan. Create keys in Dashboard → API keys.
Authentication
Pass your API key as a Bearer token in the Authorization header. Keys look like sb_live_… and can be revoked at any time.
curl https://skipbounce.com/api/v1/validate?email=name@company.com \
-H "Authorization: Bearer sb_live_YOUR_KEY"Validate one email
/api/v1/validate?email=...Runs the full pipeline in real time — syntax, DNS, blacklists, and a live SMTP mailbox check. Typical response time is 1–5 seconds depending on the receiving server. Each call consumes one validation.
curl "https://skipbounce.com/api/v1/validate?email=petter@moenco.no" \
-H "Authorization: Bearer sb_live_YOUR_KEY"const res = await fetch(
"https://skipbounce.com/api/v1/validate?email=" + encodeURIComponent(email),
{ headers: { Authorization: `Bearer ${process.env.SKIPBOUNCE_KEY}` } }
);
const result = await res.json();
if (result.status !== "deliverable") {
// ask the user to double-check their address
}{
"email": "petter@moenco.no",
"status": "deliverable",
"score": 97,
"checks": {
"valid_syntax": true,
"valid_domain": true,
"mx_found": true,
"smtp_deliverable": true,
"catch_all": false,
"disposable": false,
"free_provider": false,
"role_account": false,
"blacklisted": false
},
"did_you_mean": null,
"mx_record": "aspmx.l.google.com",
"smtp_response": "250 2.1.5 OK",
"duration_ms": 1240
}Batch validation
/api/v1/validate-batchSubmit up to 10,000 emails per request. The call returns immediately with a job id; validation runs asynchronously. Duplicates are removed before counting against your quota.
curl -X POST https://skipbounce.com/api/v1/validate-batch \
-H "Authorization: Bearer sb_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"emails": ["a@example.com", "b@example.com"]}'{
"job_id": "6f6f3d1e-...",
"status": "pending",
"total": 2,
"poll": "https://skipbounce.com/api/v1/jobs/6f6f3d1e-..."
}Job status & results
/api/v1/jobs/:idPoll until status is completed. Pass ?include=results to embed the per-email results. Jobs and their results are deleted 48 hours after completion.
{
"job_id": "6f6f3d1e-...",
"status": "completed",
"total": 2,
"processed": 2,
"counts": {
"deliverable": 1,
"undeliverable": 1,
"risky": 0,
"unknown": 0
},
"expires_at": "2026-08-16T14:00:00Z",
"results": [ /* with ?include=results */ ]
}Result statuses
The mail server explicitly accepted the mailbox. Safe to send.
Hard failure: bad syntax, dead domain, or the server rejected the mailbox. Sending will bounce.
Will probably accept mail, but: catch-all domain, role account (info@, post@), or disposable inbox.
The server gave no definitive answer (greylisting, timeouts). We never guess — treat with care.
Errors & rate limits
Errors always use the same shape and meaningful HTTP status codes:
{
"error": {
"code": "quota_exceeded",
"message": "Validation quota exhausted. Upgrade your plan or wait for the next billing period."
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Malformed input |
| 401 | unauthorized | Missing or invalid API key |
| 402 | quota_exceeded | Monthly validation quota used up |
| 403 | forbidden | Your plan does not include API access |
| 404 | not_found | Unknown job id |
| 429 | rate_limited | Too many requests — max 60/min per key |
| 503 | validation_unavailable | Engine temporarily unreachable; retry with backoff |
Rate limit: 60 requests/minute per key for real-time validation. Batch jobs are queued and don't count toward the per-minute limit.