API Documentation
Everything you need to integrate MailSentry into your application.
Authentication
All API requests require an API key passed via the X-API-Key header.
Get your API key by signing up free.
# Include in every request
X-API-Key: ms_live_your_api_key_herePOST /api/v1/verify
Validate an email address with all 8 checks and get a risk score.
Request
POST https://mailsentry.dev/api/v1/verify
Content-Type: application/json
X-API-Key: your_key
{
"email": "user@example.com"
}Response
{
"email": "user@example.com",
"score": 95,
"verdict": "valid",
"checks": {
"syntax": { "valid": true },
"mx_records": { "valid": true, "records": ["mx1.example.com"] },
"disposable": { "is_disposable": false },
"role_based": { "is_role_based": false },
"free_provider": { "is_free": false },
"typo": { "has_typo": false, "suggestion": null },
"smtp": { "valid": true, "catch_all": false }
},
"response_time_ms": 42
}Score & Verdicts
| Score Range | Verdict | Recommendation |
|---|---|---|
| 90-100 | valid | Safe to accept |
| 60-89 | caution | Accept with verification email |
| 30-59 | risky | Consider rejecting |
| 0-29 | invalid | Reject |
Scoring Logic
The score starts at 100 and deductions are applied:
| Check | Deduction |
|---|---|
| Invalid syntax | Score = 0 (instant fail) |
| No MX records | -40 |
| Disposable email | -30 |
| Has typo | -15 |
| Role-based address | -10 |
| SMTP mailbox not found | -50 |
Bulk Validation
Validate hundreds or thousands of emails in a single request. Submit a list, receive a job ID, then poll for results or wait for a webhook callback.
Create a Bulk Job
POST https://mailsentry.dev/api/v1/bulk
Content-Type: application/json
X-API-Key: your_key
{
"emails": [
"jane@example.com",
"bob@tempmail.org",
"info@company.co"
]
}Response (Job Created)
{
"id": "job_abc123",
"status": "processing",
"total_emails": 3,
"processed": 0,
"created_at": "2026-03-18T12:00:00Z"
}Get Job Results
GET https://mailsentry.dev/api/v1/bulk/job_abc123
X-API-Key: your_keyResponse (Completed)
{
"id": "job_abc123",
"status": "completed",
"total_emails": 3,
"processed": 3,
"results": [
{ "email": "jane@example.com", "score": 95, "verdict": "valid" },
{ "email": "bob@tempmail.org", "score": 12, "verdict": "invalid" },
{ "email": "info@company.co", "score": 72, "verdict": "caution" }
],
"completed_at": "2026-03-18T12:00:04Z"
}Each email in the results array includes the same score, verdict, and checks object as the single verify endpoint. Every email validated counts toward your monthly usage quota.
Email Finder
Find a person's most likely email address given their name and company domain. We generate common email patterns and verify each one via MX + SMTP checks.
Request
POST https://mailsentry.dev/api/v1/finder
Content-Type: application/json
X-API-Key: your_key
{
"first_name": "Jane",
"last_name": "Smith",
"domain": "acme.com"
}Response
{
"email": "jane.smith@acme.com",
"confidence": 94,
"status": "found",
"patterns_tested": 6,
"domain": "acme.com"
}Confidence Levels
| Confidence | Meaning |
|---|---|
| 80–100 | High — SMTP confirmed the mailbox exists |
| 50–79 | Medium — MX valid but SMTP inconclusive (catch-all domain) |
| 0–49 | Low — pattern matched but couldn't verify |
If no valid pattern is found, the response returns "status": "not_found" with "email": null. Each finder search counts as one check toward your monthly quota.
Code Examples
JavaScript / Node.js
const response = await fetch("https://mailsentry.dev/api/v1/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "ms_live_your_key_here"
},
body: JSON.stringify({ email: "user@example.com" })
});
const result = await response.json();
if (result.score < 50) {
console.log("Risky email — consider rejecting");
}
if (result.checks.typo.has_typo) {
console.log("Did you mean:", result.checks.typo.suggestion);
}Python
import requests
response = requests.post(
"https://mailsentry.dev/api/v1/verify",
json={"email": "user@example.com"},
headers={"X-API-Key": "ms_live_your_key_here"}
)
result = response.json()
print(f"Score: {result['score']} — {result['verdict']}")cURL
curl -X POST https://mailsentry.dev/api/v1/verify \
-H "Content-Type: application/json" \
-H "X-API-Key: ms_live_your_key_here" \
-d '{"email": "user@example.com"}'Error Codes
| Status | Meaning |
|---|---|
400 | Bad request — missing or invalid email |
401 | Unauthorized — missing or invalid API key |
402 | Payment required — monthly limit reached |
429 | Too many requests — rate limit exceeded |
500 | Server error — try again later |
Rate Limits
| Plan | Monthly Checks | Rate Limit |
|---|---|---|
| Free | 1,000 | 10 req/min |
| Starter ($9/mo) | 10,000 | 60 req/min |
| Pro ($29/mo) | 50,000 | 200 req/min |
| Business ($79/mo) | 200,000 | 500 req/min |
| Enterprise ($199/mo) | 500,000 | 1,000 req/min |
Rate Limit Headers
Every API response includes these headers so you can handle throttling programmatically:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per minute for your plan |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
X-Monthly-Remaining | Checks remaining in your monthly quota |
// Example response headers
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 187
X-RateLimit-Reset: 1710763200
X-Monthly-Remaining: 48,234Webhooks
Available on Pro plans and above. Configure a webhook URL in your dashboard to receive real-time notifications.
Supported Events
| Event | Description |
|---|---|
bulk.completed | A bulk validation job has finished processing |
usage.threshold | You've used 80% or 100% of your monthly quota |
usage.limit_reached | Monthly limit reached — requests are paused |
Webhook Payload
POST https://your-app.com/webhook
{
"event": "bulk.completed",
"timestamp": "2026-03-18T12:00:04Z",
"data": {
"job_id": "job_abc123",
"total_emails": 500,
"valid": 423,
"invalid": 77
}
}Webhooks are sent as POST requests with a JSON body. Verify the X-MailSentry-Signature header to confirm the request came from MailSentry.
Best Practices
Retry with Exponential Backoff
If you receive a 429 or 500 response, retry after a delay. Double the wait time on each retry (e.g., 1s, 2s, 4s) up to a maximum of 30 seconds.
async function verifyWithRetry(email, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const res = await fetch("/api/v1/verify", { ... });
if (res.status !== 429 && res.status !== 500) return res.json();
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
}
throw new Error("Max retries reached");
}Cache Results
Email validity doesn't change every minute. Cache verification results for 24–72 hours to avoid redundant API calls. This reduces your usage and improves response times in your application.
Handle Timeouts
Set a timeout of 10 seconds on your HTTP client. SMTP checks occasionally take longer if the target mail server is slow. If a request times out, the email is likely valid but unverifiable — treat it as caution.
Use Bulk for Large Lists
If you're validating more than 20 emails at once, use the Bulk Validation endpoint instead of calling the single verify endpoint in a loop. Bulk jobs are optimized for throughput and won't trigger rate limits.
Versioning
Current version: v1. All endpoints are prefixed with /api/v1/. Breaking changes will be announced at least 90 days in advance via email and dashboard notifications. Non-breaking additions (new response fields, new endpoints) are shipped continuously without version bumps.