Documentation

Complete API reference and developer guides for integrating VerifyKit email validation into your application.

Getting Started

Quick Start

Get started with VerifyKit in 3 steps. You'll be validating emails in under 3 minutes.

1

Get Your API Key

Sign up at verifykit.io/dashboard and create an API key. Plans start at $9/mo with SMTP verification and a 14-day money-back guarantee.

2

Make Your First Request

Use your API key to validate an email address:

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

Get Results

Receive comprehensive validation results:

{
  "valid": true,
  "email": "user@example.com",
  "reachable": "safe",
  "score": 0.95,
  "disposable": false,
  "role_based": false,
  "mx": {
    "valid": true,
    "records": ["mail.example.com"]
  },
  "smtp": {
    "valid": true,
    "state": "deliverable"
  }
}

SDKs

Official SDKs make integration with VerifyKit even easier. Choose your preferred language and get started in minutes.

Node.js SDK

Official

Official Node.js SDK with TypeScript support, automatic retries, and comprehensive error handling.

Installation

npm install @verifykit.io/sdk

Quick Start

TypeScript
import { VerifyKit } from '@verifykit.io/sdk';

const client = new VerifyKit({
  apiKey: process.env.VERIFYKIT_API_KEY!
});

// Validate a single email
const result = await client.validate('user@example.com');

if (result.valid) {
  console.log('Email is valid!');
  console.log('Score:', result.score);
  console.log('Reachable:', result.reachable);
} else {
  console.log('Email is invalid');
}

Features

Full TypeScript support
Automatic retries with exponential backoff
Comprehensive error handling
Built-in validation helpers
Bulk email validation
Request metadata & rate limits

Bulk Validation

// Validate multiple emails at once
const emails = [
  'user1@example.com',
  'user2@example.com',
  'invalid@disposable.com'
];

const result = await client.validateBulk(emails);

console.log(`Validated ${result.summary.total} emails`);
console.log(`Valid: ${result.summary.valid}`);
console.log(`Invalid: ${result.summary.invalid}`);

// Check individual results
result.results.forEach(r => {
  console.log(`${r.email}: ${r.valid ? '✓' : '✗'}`);
});

Error Handling

import {
  VerifyKit,
  ValidationError,
  RateLimitError,
  AuthenticationError
} from '@verifykit.io/sdk';

try {
  const result = await client.validate(email);
  // Handle success
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid input:', error.message);
  } else if (error instanceof RateLimitError) {
    console.error('Rate limited. Retry after:', error.retryAfter);
  } else if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  }
}

Configuration

const client = new VerifyKit({
  apiKey: process.env.VERIFYKIT_API_KEY!,
  timeout: 30000,        // Request timeout in ms
  maxRetries: 3,         // Max retry attempts
  debug: false           // Enable debug logging
});

// Skip SMTP verification for faster results
const result = await client.validate(email, {
  skipSmtp: true
});

// Get usage statistics
const usage = await client.getUsage();
console.log(`Used: ${usage.current}/${usage.limit}`);
console.log(`Remaining: ${usage.remaining}`);

PHP SDK

Official

Official PHP SDK with full type safety, automatic retries, and comprehensive error handling. Supports PHP 7.4+ and PHP 8.x.

Installation

composer require verifykit-io/php-sdk

Quick Start

PHP
<?php
require_once __DIR__ . '/vendor/autoload.php';

use VerifyKit\VerifyKit;

$client = new VerifyKit([
    'apiKey' => $_ENV['VERIFYKIT_API_KEY']
]);

// Validate a single email
$result = $client->validate('user@example.com');

if ($result->valid) {
    echo "Email is valid!\n";
    echo "Score: {$result->score}\n";
    echo "Reachable: {$result->reachable}\n";
} else {
    echo "Email is invalid\n";
}

Features

PHP 7.4+ and 8.x support
Automatic retries with exponential backoff
Comprehensive error handling
Built-in validation helpers
Bulk email validation
Request metadata & rate limits

Bulk Validation

<?php
// Validate multiple emails at once
$emails = [
    'user1@example.com',
    'user2@example.com',
    'invalid@disposable.com'
];

$result = $client->validateBulk($emails);

echo "Validated {$result->summary->total} emails\n";
echo "Valid: {$result->summary->valid}\n";
echo "Invalid: {$result->summary->invalid}\n";

// Check individual results
foreach ($result->results as $r) {
    echo "{$r->email}: " . ($r->valid ? '✓' : '✗') . "\n";
}

Error Handling

<?php
use VerifyKit\VerifyKit;
use VerifyKit\Exception\ValidationException;
use VerifyKit\Exception\RateLimitException;
use VerifyKit\Exception\AuthenticationException;

try {
    $result = $client->validate($email);
    // Handle success
} catch (ValidationException $e) {
    echo "Invalid input: {$e->getMessage()}\n";
} catch (RateLimitException $e) {
    echo "Rate limited. Retry after: {$e->retryAfter}\n";
} catch (AuthenticationException $e) {
    echo "Invalid API key\n";
}

Configuration

<?php
$client = new VerifyKit([
    'apiKey' => $_ENV['VERIFYKIT_API_KEY'],
    'timeout' => 30000,        // Request timeout in ms
    'maxRetries' => 3,         // Max retry attempts
    'debug' => false           // Enable debug logging
]);

// Skip SMTP verification for faster results
$result = $client->validate($email, skipSmtp: true);

// Get usage statistics
$usage = $client->getUsage();
echo "Used: {$usage->current}/{$usage->limit}\n";
echo "Remaining: {$usage->remaining}\n";

2FA Node.js SDK

Official

Dedicated SDK for two-factor authentication via email OTP. Separate package from the validation SDK.

Installation

npm install @verifykit.io/2fa

Quick Start

TypeScript
import { VerifyKit2FA } from '@verifykit.io/2fa';

const client = new VerifyKit2FA({
  apiKey: process.env.VERIFYKIT_API_KEY!
});

// Send a verification code
const { request_id } = await client.sendOtp('user@example.com');

// Verify the code the user entered
const result = await client.verifyOtp(request_id, '847293');

if (result.valid) {
  console.log('User verified!');
}

Features

Full TypeScript support
Automatic retries with backoff
Input validation
Detailed error classes

2FA PHP SDK

Official

Dedicated PHP SDK for two-factor authentication via email OTP. Zero dependencies beyond ext-json.

Installation

composer require verifykit-io/2fa-php-sdk

Quick Start

PHP
use VerifyKit2FA\VerifyKit2FA;

$client = new VerifyKit2FA(
    apiKey: $_ENV['VERIFYKIT_API_KEY']
);

// Send a verification code
$result = $client->sendOtp('user@example.com');
$requestId = $result->requestId;

// Verify the code the user entered
$verification = $client->verifyOtp($requestId, '847293');

if ($verification->valid) {
    echo 'User verified!';
}

Features

PHP 7.4+ and 8.0+ support
Automatic retries with backoff
Typed DTOs for results
Zero external dependencies

More SDKs Coming Soon

We're working on official SDKs for more languages. Vote for your preferred language or request a new one.

Python
Ruby
Go
.NET

Authentication

VerifyKit uses API keys for authentication. Include your API key in the Authorization header of every request.

Authentication Header
Authorization: Bearer vk_live_your_api_key_here

Security Best Practices

  • Never commit API keys to version control
  • Store keys in environment variables
  • Use different keys for development and production
  • Rotate keys if they're compromised
  • Never expose keys in client-side code

Environment Variables

.env
VERIFYKIT_API_KEY=vk_live_your_api_key_here
VERIFYKIT_BASE_URL=https://api.verifykit.io

API Reference

POST
/v1/verify

Validate a single email address. Returns comprehensive validation results including syntax, MX records, SMTP verification, and deliverability score.

Request Body

ParameterTypeRequiredDescription
emailstringYesEmail address to validate
skip_smtpbooleanNoSkip SMTP verification for faster results

Real SMTP Verification Included By Default

Unlike competitors who charge extra for SMTP verification, we include it by default in every validation. This ensures 97%+ accuracy out of the box. Use skip_smtp: true only when you need faster results for low-value use cases.

Validation Options

Default (Full SMTP)300-500ms
Recommended

Syntax + MX + Disposable + SMTP verification. 97%+ accuracy.

{ "email": "user@example.com" }
Fast Mode (Skip SMTP)100ms

Syntax + MX + Disposable (100k+ domains, updated daily) checks. 85% accuracy. For real-time forms.

{ "email": "user@example.com", "skip_smtp": true }

Response

{
  "valid": true,
  "email": "user@example.com",
  "reachable": "safe",
  "score": 0.95,
  "quality_grade": "excellent",
  "disposable": false,
  "role_based": false,
  "free_provider": false,
  "mx": {
    "valid": true,
    "records": ["mail.example.com"]
  },
  "smtp": {
    "valid": true,
    "state": "deliverable",
    "full_inbox": false
  },
  "syntax": {
    "valid": true,
    "username": "user",
    "domain": "example.com"
  }
}

Response Fields

FieldTypeDescription
validbooleanOverall validation result
scorenumberQuality score (0.0 - 1.0)
quality_gradestring?"excellent", "good", "fair", or "poor" (only present for emails with valid syntax and MX records)
reachablestring"safe", "risky", or "unknown"
disposablebooleanTemporary/disposable email service
role_basedbooleanGeneric role address (info@, support@)

Understanding Quality Scores & Grades

All emails receive a quality score (0.0-1.0). However, quality grades are only assigned to emails that pass basic validation (valid syntax + valid MX records). This ensures grades are only applied to potentially deliverable emails.

Score Calculation Weights:
  • SMTP Verification (40%) - Most important: actual deliverability
  • Syntax Validation (20%) - Basic email format
  • MX Records (20%) - DNS validation
  • Disposable Check (10%) - Fraud prevention
  • Role-based (5%) - Quality indicator
  • Free Email (5%) - Quality indicator
Excellent (90-100%)

High deliverability, low risk. Safe for critical communications.

Good (70-89%)

Acceptable quality. Moderate deliverability expected.

Fair (50-69%)

Use with caution. High bounce risk. Monitor closely.

Poor (0-49%)

Not recommended. High rejection probability.

💡 Tip: Use quality grades to segment your email lists and prioritize high-quality leads.

POST
/v1/verify/bulk

Validate up to 1,000 email addresses in a single request. Results are returned instantly for batches under 100 emails.

Automatic Duplicate Removal (Pro+)

On Pro and Unlimited plans, we automatically remove duplicate emails before validation. Only unique emails count toward your quota.

Performance

≤100 emails

Instant results in 2-3 seconds

100-1,000 emails

Results in 5-15 seconds

Cost Savings Example

Clean a list of 10,000 emails (with 2,000 duplicates):

Original list:10,000 emails
Duplicates removed (free):-2,000 emails
Actually validated:8,000 emails
Cost at $0.005/email:$40
Competitors charge for all 10,000:$80

You save $40 (50%) with automatic duplicate removal!

Request Body

{
  "emails": [
    "user1@example.com",
    "user2@example.com",
    "user3@example.com"
  ],
  "skip_smtp": false  // Optional: defaults to false (includes SMTP)
}

Response

{
  "results": [
    {
      "email": "user1@example.com",
      "valid": true,
      "score": 0.95,
      "quality_grade": "excellent",
      "reachable": "safe"
    },
    {
      "email": "user2@example.com",
      "valid": false,
      "score": 0.2,
      "quality_grade": "poor",
      "reachable": "risky"
    }
  ],
  "summary": {
    "total": 2,
    "valid": 1,
    "invalid": 1,
    "processing_time_ms": 420
  }
}
GET
/v1/stats

Get usage statistics for your API key, including validations used, remaining quota, and rate limit status.

Response

{
  "current_usage": 750,
  "monthly_limit": 1000,
  "percentage_used": 75,
  "plan": "free",
  "period_start": "2024-01-01T00:00:00Z",
  "period_end": "2024-01-31T23:59:59Z",
  "rate_limit": {
    "requests_per_minute": 10,
    "requests_remaining": 8
  }
}

Two-Factor Auth (2FA)

Overview

Send and verify one-time passcodes (OTP) via email for two-factor authentication.

Plan Availability

  • Growth — 25,000 OTP codes/month
  • Pro — 50,000 OTP codes/month
  • Unlimited — 100,000 OTP codes/month
POST
/v1/2fa/send

Send a 6-digit OTP verification code to an email address. The code expires after 10 minutes.

Parameters

FieldTypeRequiredDescription
emailstringYesEmail address to send the code to
app_namestringNoYour app name (max 50 chars). Shown in the email subject and body for branding.
deliverystringNo"email" (default) sends via VerifyKit. "api" returns the code in the response for you to deliver yourself.

Request

cURL
curl -X POST https://api.verifykit.io/v1/2fa/send \
  -H "Authorization: Bearer vk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "app_name": "MyApp"}'

Response

{
  "request_id": "2fa_abc123...",
  "expires_in": 600,
  "message": "Verification code sent"
}

Bring Your Own Email (delivery: "api")

Set delivery to "api" to receive the OTP code in the response instead of having VerifyKit send the email. This lets you use your own email service for consistent branding.

cURL
curl -X POST https://api.verifykit.io/v1/2fa/send \
  -H "Authorization: Bearer vk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "delivery": "api"}'

Response (delivery: "api")

{
  "request_id": "2fa_abc123...",
  "expires_in": 600,
  "message": "Verification code generated",
  "code": "847293"
}
POST
/v1/2fa/verify

Verify a 6-digit OTP code. Codes are single-use and are invalidated after 5 failed attempts.

Request

cURL
curl -X POST https://api.verifykit.io/v1/2fa/verify \
  -H "Authorization: Bearer vk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"request_id": "2fa_abc123...", "code": "847293"}'

Response (success)

{
  "valid": true,
  "request_id": "2fa_abc123...",
  "message": "Verification successful"
}

Response (failure)

{
  "valid": false,
  "request_id": "2fa_abc123...",
  "message": "Invalid verification code"
}

SDK Examples

Node.js

TypeScript
import { VerifyKit2FA } from '@verifykit.io/2fa';

const client = new VerifyKit2FA({
  apiKey: process.env.VERIFYKIT_API_KEY!
});

// Send an OTP code (app_name is optional, for branded emails)
const { request_id } = await client.sendOtp('user@example.com', {
  appName: 'MyApp'
});

// Or use delivery: "api" to get the code and send it yourself
const { request_id: rid, code } = await client.sendOtp('user@example.com', {
  delivery: 'api'
});
// code = "847293" — send it via your own email service

// Verify the code the user entered
const result = await client.verifyOtp(request_id, '847293');

if (result.valid) {
  console.log('User verified!');
}

PHP

PHP
use VerifyKit2FA\VerifyKit2FA;

$client = new VerifyKit2FA(apiKey: $_ENV['VERIFYKIT_API_KEY']);

// Send an OTP code (app_name is optional, for branded emails)
$result = $client->sendOtp('user@example.com', 'MyApp');
$requestId = $result->requestId;

// Or use delivery "api" to get the code and send it yourself
$result = $client->sendOtp('user@example.com', delivery: 'api');
// $result->code = "847293" — send it via your own email service

// Verify the code the user entered
$verification = $client->verifyOtp($requestId, '847293');

if ($verification->valid) {
    echo 'User verified!';
}

Security & Limits

Single-use codes

Codes are deleted after successful verification

10-minute expiration

Codes expire after 600 seconds

5 max attempts

Code invalidated after 5 wrong attempts

Send rate limit

Max 5 codes per email per 10-minute window

Error Codes

StatusErrorDescription
400Validation ErrorInvalid email or code format
403ForbiddenPlan does not include 2FA (upgrade to Growth+)
429Rate LimitedToo many codes sent or monthly limit exceeded
500Internal Server ErrorUnexpected error processing request

Use Cases

Real-world scenarios where VerifyKit helps you build better products and save money.

Prevent Fake Signups

Block disposable and temporary email addresses at registration. Stop fake accounts before they enter your system.

Registration Form Validation
async function validateSignup(email) {
  const result = await fetch('https://api.verifykit.io/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer vk_live_...',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email })  // Full SMTP verification by default
  }).then(r => r.json());

  // Block disposable emails
  if (result.disposable) {
    throw new Error('Please use a permanent email address');
  }

  // Block low-quality emails
  if (result.score < 0.7) {
    throw new Error('Email appears invalid');
  }

  return result.valid;
}
Fake signups:↓ 90%
Support tickets:↓ 65%
User quality:↑ 85%
Time saved:10h/week

Clean Email Lists

Validate your email list before campaigns. Remove invalid addresses, reduce bounce rates, improve deliverability.

Bulk List Cleaning
import requests

def clean_email_list(email_list):
    response = requests.post(
        'https://api.verifykit.io/v1/verify/bulk',
        headers={'Authorization': 'Bearer vk_live_...'},
        json={'emails': email_list}  # Full SMTP verification included
    )

    results = response.json()

    # Filter valid, deliverable emails
    clean_list = [
        r['email'] for r in results['results']
        if r['valid'] and r['reachable'] == 'safe' and r['score'] > 0.7
    ]

    print(f"Original: {len(email_list)} emails")
    print(f"Clean: {len(clean_list)} emails")
    print(f"Removed: {len(email_list) - len(clean_list)} invalid")

    return clean_list
Email costs:↓ 20%
Bounce rate:↓ 85%
Open rate:↑ 15%
ROI:12x

Real-time Form Validation

Validate emails as users type. Provide instant feedback, improve UX, catch typos before submission.

React Form Component
function EmailInput() {
  const [email, setEmail] = useState('');
  const [status, setStatus] = useState('idle');
  const [error, setError] = useState('');

  const validateEmail = useDebouncedCallback(async (value) => {
    if (!value) return;

    setStatus('validating');

    try {
      const result = await fetch('https://api.verifykit.io/v1/verify', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer vk_live_...',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          email: value,
          skip_smtp: true  // Fast validation for real-time feedback
        })
      }).then(r => r.json());

      if (!result.valid) {
        setError('Email address appears invalid');
        setStatus('error');
      } else if (result.disposable) {
        setError('Please use a permanent email address');
        setStatus('error');
      } else {
        setError('');
        setStatus('valid');
      }
    } catch (err) {
      setStatus('idle');
    }
  }, 500);

  return (
    <input
      type="email"
      value={email}
      onChange={(e) => {
        setEmail(e.target.value);
        validateEmail(e.target.value);
      }}
      className={status === 'error' ? 'border-red-500' : ''}
    />
  );
}
Impact: Better UX, catch typos early, reduce form abandonment

Smart Typo Detection & Correction

Automatically detect and suggest corrections for common email typos. Improve data quality and reduce user frustration.

Typo Detection Example
async function validateWithTypoCheck(email) {
  const result = await fetch('https://api.verifykit.io/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer vk_live_...',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email, skip_smtp: true })
  }).then(r => r.json());

  // Check for typo suggestion
  if (result.did_you_mean) {
    // Show suggestion to user
    const useCorrection = confirm(
      `Did you mean: ${result.did_you_mean}?`
    );

    if (useCorrection) {
      // Validate the corrected email
      return validateWithTypoCheck(result.did_you_mean);
    }
  }

  return result;
}

// Example results:
// user@gmial.com → Suggests: user@gmail.com
// test@hotmial.com → Suggests: test@hotmail.com
// hello@yaho.com → Suggests: hello@yahoo.com
Common Typos Detected:
gmial.com
→ gmail.com
yaho.com
→ yahoo.com
hotmial.com
→ hotmail.com
outlok.com
→ outlook.com
Typos caught:↓ 85%

Quality Grades & Score-based Filtering

Every email receives a quality score (0.0-1.0) and a human-readable grade (excellent/good/fair/poor). Use these to segment users and personalize onboarding.

Quality Grade Calculation:

excellent90-100% score (valid + deliverable + safe)
good70-89% score (valid + mostly safe)
fair50-69% score (valid but risky)
poor0-49% score (invalid or undeliverable)

Note: Grades are only assigned to emails with valid syntax and MX records

Grade-based User Segmentation
async function segmentUser(email) {
  const result = await verifyEmail(email);

  // Use quality_grade for cleaner logic
  switch (result.quality_grade) {
    case 'excellent':
      // High quality - auto-approve, skip extra verification
      return {
        segment: 'premium',
        actions: ['enable_full_access', 'skip_email_verification'],
        onboarding: 'fast_track'
      };

    case 'good':
      // Good quality - standard flow
      return {
        segment: 'standard',
        actions: ['send_verification_email'],
        onboarding: 'normal'
      };

    case 'fair':
      // Risky - require extra verification
      return {
        segment: 'risky',
        actions: ['require_phone_verification', 'limit_initial_access'],
        onboarding: 'cautious'
      };

    case 'poor':
    default:
      // Low quality or no grade - reject
      return {
        segment: 'reject',
        actions: ['block_signup'],
        message: 'Please use a valid email address'
      };
  }
}

// Or use numeric scores for more granular control
if (result.score >= 0.9) { /* ... */ }
else if (result.score >= 0.7) { /* ... */ }
Impact: Personalized onboarding, fraud prevention, better data quality

Error Handling

Handle API errors gracefully to ensure a smooth user experience.

HTTP Status Codes

200

Success

Request completed successfully

400

Bad Request

Invalid parameters or malformed request

401

Unauthorized

Invalid or missing API key

429

Rate Limited

Too many requests, retry after indicated time

500

Server Error

Internal error, retry with exponential backoff

Example Error Handling

async function validateWithRetry(email, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://api.verifykit.io/v1/verify', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.VERIFYKIT_API_KEY}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ email })
      });

      if (response.ok) {
        return await response.json();
      }

      // Handle specific errors
      if (response.status === 401) {
        throw new Error('Invalid API key');
      }

      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || 60;
        console.log(`Rate limited, waiting ${retryAfter}s`);
        await sleep(retryAfter * 1000);
        continue;
      }

      if (response.status === 400) {
        const error = await response.json();
        throw new Error(`Validation error: ${error.message}`);
      }

      // Retry on server errors
      if (response.status >= 500) {
        const backoff = Math.pow(2, i) * 1000;
        console.log(`Server error, retrying in ${backoff}ms`);
        await sleep(backoff);
        continue;
      }

    } catch (error) {
      if (i === maxRetries - 1) throw error;

      const backoff = Math.pow(2, i) * 1000;
      await sleep(backoff);
    }
  }

  throw new Error('Max retries exceeded');
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Plans & Pricing

Four plans designed to grow with you. Each tier builds on the previous one, unlocking more features as your needs grow.

$9
/month

Starter

5,000/month
  • 5,000 validations/month
  • Single API key
  • Real SMTP verification
  • Validation history
$19
/month

Growth

15,000/month
  • 15,000 validations/month
  • Single API key
  • Real SMTP verification
  • Validation history
  • Bulk validation
  • Email OTP 2FA (25k/mo)
popular
$49
/month

Pro

50,000/month
  • 50,000 validations/month
  • Unlimited API keys
  • Duplicate removal
  • Webhooks & callbacks
  • Email OTP 2FA (50k/mo)
$249
/month

Unlimited

unlimited
  • Unlimited validations
  • Unlimited API keys
  • All Pro features
  • Dedicated support
  • Fair usage up to 5M/month
  • Email OTP 2FA (100k/mo)

What's Included in Each Validation Tier

Not all validation is equal. Here's exactly what checks run at each tier so you know what you're getting.

Basic Email Validation
All plans
~100ms · 85% accuracy

Pattern-based checks that run instantly. Good for catching typos and obvious fakes, but cannot confirm if a mailbox actually exists.

Syntax validation

RFC 5322 format checks

MX record lookup

Verifies domain has mail servers

Disposable detection

100k+ throwaway domains

Role-based detection

Flags info@, admin@, support@

Free provider detection

Gmail, Yahoo, Outlook, etc.

Deliverability score

0.0 - 1.0 confidence score

Note: Basic validation tells you if an email looks valid. It checks format and domain, but cannot confirm the mailbox exists. For that, you need SMTP verification.

Real SMTP Verification
Recommended
Starter+
~300-500ms · 97%+ accuracy

Everything in basic validation, plus we connect to the recipient's mail server to verify the mailbox actually exists. This is the only way to know if an email is truly deliverable.

SMTP mailbox check

Connects to mail server, verifies mailbox exists

Catch-all detection

Identifies domains accepting all emails

Full inbox detection

Flags mailboxes that can't receive mail

Deliverability state

safe / risky / invalid classification

Quality grading

excellent / good / fair / poor

Validation history

Browse and filter past results

safe = mailbox confirmed, safe to send
risky = catch-all or unverifiable
invalid = mailbox does not exist

Feature Breakdown by Plan

Each plan includes everything from the tier below it, plus new features. New features at each tier are highlighted.

FeatureStarterGrowthProUnlimited
Monthly validations5,00015,00050,000Unlimited
API keys11UnlimitedUnlimited
Rate limit150/min300/min500/min2,000/min
Basic validation
Real SMTP verification
Validation history
Bulk validation
Email OTP 2FA25k/mo50k/mo100k/mo
Duplicate removal
Webhooks & callbacks
Dedicated support
Fair usage up to 5M/month

What Each Upgrade Unlocks

StarterGrowth ($19/mo)

Unlock bulk validation to validate up to 1,000 emails per request and Email OTP 2FA with 25,000 codes/month. Your validation quota increases from 5,000 to 15,000/month.

GrowthPro ($49/mo)

Unlock unlimited API keys for multi-app setups, automatic duplicate removal in bulk requests, and webhooks & callbacks for async workflows. 2FA quota increases to 50,000 codes/month. Quota jumps to 50,000 validations/month with 500 requests/minute rate limit.

ProUnlimited ($249/mo)

Remove all volume limits with unlimited validations under a fair usage policy of up to 5M/month. Get dedicated support with direct access to our team. 2FA quota increases to 100,000 codes/month. Rate limit increases to 2,000 requests/minute.

Rate Limits

Rate limits protect the API and ensure fair usage across all users.

Limits by Plan

Starter
5,000/month

150 requests/minute, 5,000 validations/month

Growth
15,000/month

300 requests/minute, 15,000 validations/month

Pro
50,000/month

500 requests/minute, 50,000 validations/month

Unlimited

2,000 requests/minute, unlimited validations

How Monthly Quotas Work

📅 Reset Schedule

Monthly quotas reset on the 1st of each calendar month at 00:00 UTC. Everyone's quota refreshes at the same time, making it predictable and easy to plan.

🎁 New Subscriber Bonus

When you subscribe mid-month, you receive your full monthly quota immediately. For example:

• Subscribe on March 15 with Pro plan → Get full 50,000 validations
• Use these until March 31 (16 days)
• April 1 → Fresh 50,000 validations

This means your first month is always a bonus - no prorating!

💡 Why This Approach?

We believe in being generous with our users. Rather than complicated proration or billing cycle tracking, we give you a full quota when you join. Simple, fair, and no surprises.

Rate Limit Headers

Every API response includes rate limit information in the headers:

X-RateLimit-Limit: 500
X-RateLimit-Remaining: 495
X-RateLimit-Reset: 1640000000
X-Monthly-Limit: 50000
X-Monthly-Usage: 1250
Retry-After: 60

Monitor these headers to avoid hitting rate limits. When you receive a 429 status, wait for the time specified in Retry-After before retrying.

Why Choose VerifyKit?

VerifyKit offers the same accuracy as industry leaders, with better value for SMBs, agencies, and indie developers.

Real SMTP Verification

Real SMTP verification available from the Starter plan. Competitors charge separately for this critical feature or lock it behind expensive tiers.

Available from $19/month. 97%+ accuracy with SMTP.

Advanced Fraud Prevention

Comprehensive disposable email detection with 100k+ known domains (updated daily) plus intelligent pattern matching for new services.

100k+ disposable domains (updated daily from GitHub)
Rotating domain detection (catches temp-mail.org, 10minutemail)
Pattern-based detection (catches new services instantly)
Confidence scores (know which detections are certain)

Automatic Duplicate Removal

Pro and Unlimited plans automatically remove duplicate emails in bulk validations. Only pay for unique emails.

Saves money on every bulk validation (Pro+)

Instant Bulk Results

Get instant results for up to 100 emails. Competitors make you wait in a queue.

2-3 seconds for 100 emails

Smart Typo Detection

Automatically detect and suggest corrections for typos like gmial.com → gmail.com.

70+ common typo patterns
Levenshtein distance matching
Confidence scores

97%+ Accuracy

Same accuracy as ZeroBounce and NeverBounce, powered by real SMTP verification.

Industry-leading validation accuracy

Feature Comparison

FeatureVerifyKitZeroBounceNeverBounceHunter.io
SMTP Verification✅ From $19/mo⚠️ Extra cost✅ Yes✅ Yes
Instant Results✅ <3s❌ Queue❌ Queue⚠️ Slow
Duplicate Removal✅ Pro+❌ Charged❌ Charged❌ Charged
Unlimited API Calls✅ Yes❌ Limited❌ Limited❌ Limited
Unlimited Plan✅ Available❌ No❌ No❌ No
Modern API✅ Yes⚠️ Legacy⚠️ Legacy✅ Yes

Choose Your Use Case

Indie Developer / Small Project

Building a product with user signups. Need accurate SMTP verification, validation history, and bulk processing for periodic list cleaning.

Recommended: Growth Plan - 15,000 validations/month ($19/mo)

Growing SaaS / Agency

Running email campaigns for multiple clients or managing several apps. Need unlimited API keys, webhooks, duplicate removal, and high volume.

Recommended: Pro Plan - 50,000 validations/month ($49/mo)

High-Volume SaaS / Enterprise

Large user base with continuous signups. Need unlimited validations with predictable costs and dedicated support. Fair usage up to 5M/month.

Recommended: Unlimited Plan - unlimited validations ($249/mo)

Agency ROI Example

How agencies use VerifyKit to deliver better results to clients while maintaining healthy profit margins:

Client base:10 clients
Avg. emails per client/month:5,000 emails
Total validations:50,000/month
VerifyKit Pro Plan:$49/month
Cost per client:$4.90/month
Charge clients:$25/month each
Total revenue:$250/month
Monthly Profit:$201

Bottom line: Deliver better campaign results to clients while maintaining 80% profit margins on email validation services.

Code Examples

Ready-to-use code snippets in popular languages and frameworks.

Node.js / Express

const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json());

const VERIFYKIT_API_KEY = process.env.VERIFYKIT_API_KEY;

app.post('/api/signup', async (req, res) => {
  const { email, name } = req.body;

  try {
    // Validate email with VerifyKit (includes SMTP verification)
    const validation = await axios.post(
      'https://api.verifykit.io/v1/verify',
      { email },
      {
        headers: {
          'Authorization': `Bearer ${VERIFYKIT_API_KEY}`,
          'Content-Type': 'application/json'
        }
      }
    );

    const result = validation.data;

    // Block invalid or disposable emails
    if (!result.valid || result.disposable) {
      return res.status(400).json({
        error: 'Invalid email address'
      });
    }

    // Continue with signup...
    res.json({ success: true });

  } catch (error) {
    console.error('Validation error:', error);
    res.status(500).json({ error: 'Server error' });
  }
});

app.listen(3000);

Python / Django

import requests
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
import os

VERIFYKIT_API_KEY = os.getenv('VERIFYKIT_API_KEY')

@require_http_methods(["POST"])
def signup(request):
    email = request.POST.get('email')
    name = request.POST.get('name')

    # Validate email with VerifyKit (includes SMTP verification)
    response = requests.post(
        'https://api.verifykit.io/v1/verify',
        headers={
            'Authorization': f'Bearer {VERIFYKIT_API_KEY}',
            'Content-Type': 'application/json'
        },
        json={'email': email}
    )

    result = response.json()

    # Block invalid or disposable emails
    if not result['valid'] or result['disposable']:
        return JsonResponse({
            'error': 'Invalid email address'
        }, status=400)

    # Continue with signup...
    return JsonResponse({'success': True})

Ruby / Rails

require 'net/http'
require 'json'

class SignupsController < ApplicationController
  def create
    email = params[:email]
    name = params[:name]

    # Validate email with VerifyKit (includes SMTP verification)
    uri = URI('https://api.verifykit.io/v1/verify')
    request = Net::HTTP::Post.new(uri)
    request['Authorization'] = "Bearer #{ENV['VERIFYKIT_API_KEY']}"
    request['Content-Type'] = 'application/json'
    request.body = { email: email }.to_json

    response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end

    result = JSON.parse(response.body)

    # Block invalid or disposable emails
    unless result['valid'] && !result['disposable']
      render json: { error: 'Invalid email address' }, status: 400
      return
    end

    # Continue with signup...
    render json: { success: true }
  end
end

PHP / Laravel

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class SignupController extends Controller
{
    public function store(Request $request)
    {
        $email = $request->input('email');
        $name = $request->input('name');

        // Validate email with VerifyKit (includes SMTP verification)
        $response = Http::withHeaders([
            'Authorization' => 'Bearer ' . env('VERIFYKIT_API_KEY'),
            'Content-Type' => 'application/json'
        ])->post('https://api.verifykit.io/v1/verify', [
            'email' => $email
        ]);

        $result = $response->json();

        // Block invalid or disposable emails
        if (!$result['valid'] || $result['disposable']) {
            return response()->json([
                'error' => 'Invalid email address'
            ], 400);
        }

        // Continue with signup...
        return response()->json(['success' => true]);
    }
}

?>

Questions?

Need help integrating VerifyKit? Have a specific use case not covered here? We're here to help.

Contact Support