API Reference

Documentation

The Zoravel API lets you verify email addresses in real time. Integrate it into your registration forms, CRM, or any system where email quality matters.

Authentication

All API requests must include your API key as a Bearer token in the Authorization header. You can generate API keys from Settings → API Keys.

Header
Authorization: Bearer zrv_your_api_key_here

Verify an email

POST /api/v1/verify

Verifies a single email address and returns a full breakdown of all checks performed. Deducts 1 credit per request.

Request

Body - application/json
{"email": "user@example.com"}

Response

200 OK
{
  "email": "user@example.com",
  "status": "valid",
  "safe_to_send": true,
  "verification_reason": "Mailbox verified successfully",
  "checks": {
    "syntax": "pass",
    "dns": "pass",
    "smtp": "pass",
    "catch_all": "false",
    "disposable": "pass",
    "role_based": "pass"
  }
}

Status values

The status field gives you the overall verdict for the address.

valid

Syntax is correct, domain has MX records, and SMTP confirmed the mailbox exists. safe_to_send: true.

invalid

Address does not exist or cannot receive email. Caused by bad syntax, missing domain, no MX records, or the mail server explicitly rejected the address. Do not send.

accept_all

Domain accepts all addresses regardless of whether the mailbox exists. Individual mailboxes cannot be confirmed. Send with caution.

disposable

Known temporary or disposable email provider such as Mailinator or Guerrilla Mail. High bounce risk.

role_based

Role-based address such as info@, admin@, or support@. These are shared inboxes with typically lower engagement rates.

unknown

Verification could not be completed due to a network timeout or unresponsive mail server. Try again later.

Check fields

The checks object gives you the result of each individual verification step.

syntax
pass / fail

Validates the email format against RFC 5322. Checks for valid characters, proper @ placement, and a valid domain part.

dns
pass / fail / risky

Checks that the domain exists and has MX records configured to receive email. risky means the domain exists but has no MX records.

smtp
pass / fail / risky

Performs an SMTP handshake with the mail server to check if the mailbox exists without sending an email. risky means the server was unreachable or timed out.

catch_all
true / false

Whether the domain accepts all email addresses regardless of whether the mailbox exists. true means the domain is catch-all and individual mailboxes cannot be confirmed.

disposable
pass / fail

Checks against a list of known temporary and disposable email providers such as Mailinator and Guerrilla Mail.

role_based
pass / fail

Detects role-based addresses such as info@, admin@, support@, and noreply@. These are often shared inboxes with lower engagement rates.

Error codes

400

Bad Request

Missing or invalid email parameter in the request body.

401

Unauthorised

Missing or invalid API key. Check your Authorization header.

402

Payment Required

Your account has insufficient credits. Purchase more at zoravel.com/billing.

429

Too Many Requests

Rate limit exceeded. Maximum 60 requests per minute per API key. Check the Retry-After header.

Rate limiting

Each API key is limited to 60 requests per minute. The following headers are included in every response:

X-RateLimit-Limit

Maximum number of requests allowed per minute.

X-RateLimit-Remaining

Number of requests remaining in the current window.

Retry-After

Seconds to wait before retrying. Only present on 429 responses.

Code examples

cURL

Shell
curl -X POST https://zoravel.com/api/v1/verify \
  -H "Authorization: Bearer zrv_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

JavaScript

JavaScript
const response = await fetch("https://zoravel.com/api/v1/verify", {
  method: "POST",
  headers: {
    "Authorization": "Bearer zrv_your_api_key_here",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ email: "user@example.com" })
});

const result = await response.json();
console.log(result.status);        // "valid"
console.log(result.safe_to_send);  // true