One API call. Three checks.
Your signup form rejects bad emails. Or it doesn't, and you find out when your welcome emails bounce. One POST request. JSON response. You see exactly what passed and what didn't.
Your first API call in 3 minutes
No SDK to install. No complex auth flow. Just an API key and a POST request.
-
1
Get your API key
Sign up and copy your key from the dashboard. No credit card required.
-
2
Send the request
POST to /v1/verify with the email and your API key in the Authorization header.
-
3
Check the response
status: "good" means valid. status: "bad" means invalid. You'll also see which checks passed.
Authentication
Every request needs your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Two validation levels. You choose.
MX validation is fast and catches most bad emails. SMTP validation connects to the mail server for maximum accuracy. Pick what your use case needs.
MX Validation
Checks syntax, domain, and mail server configuration. Fast. Catches typos and dead domains.
- Syntax validation (catches typos)
- Domain and MX record check
- Disposable email detection
- Best for bulk list cleaning
SMTP Validation
Connects to the recipient's mail server and asks if the mailbox exists. Slower. Most accurate.
- Everything in MX validation
- SMTP handshake verification
- Catch-all server detection
- Best for real-time signup validation
API Endpoints
Three endpoints. That's it. No versioning headaches. No deprecated routes.
/v1/verify
Email Validation
Request
{
"email": "[email protected]",
"validation_type": "mx"
}
validation_type:
"mx" (1 credit) or
"smtp" (10 credits, Premium)
Response
{
"email": "[email protected]",
"status": "good",
"validation_type": "mx",
"credits_used": 1
}
status:
"good" (valid) or
"bad" (invalid)
/v1/usage
Account Usage
Check your current plan, credits balance, and rate limits.
/v1/filters
Create Filter
Add emails, domains, or IPs to your custom blacklist.
/v1/filters
List Filters
Retrieve all your filters with pagination and search.
/v1/filters/:id
Delete Filter
Remove a filter from your blacklist by ID.
Code samples
Copy, paste, modify. No SDK required.
# Validate an email (MX validation - 1 credit)
curl -X POST https://api.mailcop.net/v1/verify \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "validation_type": "mx"}'
# SMTP validation (10 credits, Premium only)
curl -X POST https://api.mailcop.net/v1/verify \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "validation_type": "smtp"}'
# Check your account usage
curl -X GET https://api.mailcop.net/v1/usage \
-H "Authorization: Bearer YOUR_API_KEY"
require "net/http"
require "json"
class MailCopClient
BASE_URL = "https://api.mailcop.net/v1"
def initialize(api_key)
@api_key = api_key
end
def verify_email(email, validation_type: "mx")
uri = URI("#{BASE_URL}/verify")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{@api_key}"
request["Content-Type"] = "application/json"
request.body = { email: email, validation_type: validation_type }.to_json
response = http.request(request)
JSON.parse(response.body)
end
def usage
uri = URI("#{BASE_URL}/usage")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{@api_key}"
response = http.request(request)
JSON.parse(response.body)
end
end
# Usage
client = MailCopClient.new("YOUR_API_KEY")
result = client.verify_email("[email protected]")
puts result["status"] # => "good" or "bad"
import requests
class MailCopClient:
BASE_URL = "https://api.mailcop.net/v1"
def __init__(self, api_key):
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def verify_email(self, email, validation_type="mx"):
response = requests.post(
f"{self.BASE_URL}/verify",
headers=self.headers,
json={"email": email, "validation_type": validation_type}
)
return response.json()
def usage(self):
response = requests.get(
f"{self.BASE_URL}/usage",
headers=self.headers
)
return response.json()
# Usage
client = MailCopClient("YOUR_API_KEY")
result = client.verify_email("[email protected]")
print(result["status"]) # => "good" or "bad"
<?php
class MailCopClient {
private $apiKey;
private $baseUrl = "https://api.mailcop.net/v1";
public function __construct($apiKey) {
$this->apiKey = $apiKey;
}
public function verifyEmail($email, $validationType = "mx") {
return $this->request("POST", "/verify", [
"email" => $email,
"validation_type" => $validationType
]);
}
public function usage() {
return $this->request("GET", "/usage");
}
private function request($method, $path, $data = null) {
$curl = curl_init();
$url = $this->baseUrl . $path;
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . $this->apiKey,
"Content-Type: application/json"
]
]);
if ($data) {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response, true);
}
}
// Usage
$client = new MailCopClient("YOUR_API_KEY");
$result = $client->verifyEmail("[email protected]");
echo $result["status"]; // => "good" or "bad"
class MailCopClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = "https://api.mailcop.net/v1";
}
async verifyEmail(email, validationType = "mx") {
const response = await fetch(`${this.baseUrl}/verify`, {
method: "POST",
headers: {
"Authorization": `Bearer ${this.apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ email, validation_type: validationType })
});
return response.json();
}
async usage() {
const response = await fetch(`${this.baseUrl}/usage`, {
headers: {
"Authorization": `Bearer ${this.apiKey}`
}
});
return response.json();
}
}
// Usage
const client = new MailCopClient("YOUR_API_KEY");
const result = await client.verifyEmail("[email protected]");
console.log(result.status); // => "good" or "bad"
Rate Limits
Rate limits reset every 5 minutes. Need more? Upgrade or contact us.
Error Codes
All errors return JSON with an error field.
| Code | Description |
|---|---|
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid API key |
| 402 | Payment Required - Insufficient credits |
| 403 | Forbidden - IP not allowed |
| 422 | Unprocessable - Invalid validation type |
| 429 | Too Many Requests - Rate limit exceeded |