Official PHP SDK for VerifyKit - The most reliable email validation and verification API.
✨ Simple & Intuitive - Clean API design that's easy to use
🚀 Fast & Reliable - Built-in retry logic and error handling
📦 Modern PHP - PHP 8 features with PHP 7.4+ compatibility
🔄 Automatic Retries - Smart retry logic with exponential backoff
⚡ Bulk Validation - Validate up to 1,000 emails in a single request
🛡️ Rate Limit Handling - Automatic rate limit detection and retry
📊 Usage Tracking - Monitor your API usage and quota
- PHP 7.4 or higher (PHP 8.0+ recommended)
- ext-json
- ext-filter
Install via Composer:
composer require verifykit/sdk<?php
require 'vendor/autoload.php';
use VerifyKit\VerifyKit;
// Initialize with your API key from environment variable
$client = new VerifyKit(
apiKey: $_ENV['VERIFYKIT_API_KEY'] // Get your API key from https://verifykit.io/dashboard/api-keys
);
// Validate a single email
$result = $client->validate('user@example.com');
echo $result->valid ? 'Valid' : 'Invalid';- Installation
- Quick Start
- Authentication
- Usage Examples
- Configuration
- API Reference
- Error Handling
- Advanced Features
- Contributing
- License
Get your API key from the VerifyKit Dashboard.
<?php
use VerifyKit\VerifyKit;
$client = new VerifyKit(
apiKey: $_ENV['VERIFYKIT_API_KEY']
);Environment Variables:
# .env file
VERIFYKIT_API_KEY=vk_live_your_api_key_here<?php
use VerifyKit\VerifyKit;
$client = new VerifyKit(apiKey: $_ENV['VERIFYKIT_API_KEY']);
$result = $client->validate('user@example.com');
echo "Email: {$result->email}\n";
echo "Valid: " . ($result->valid ? 'Yes' : 'No') . "\n";
echo "Reachable: {$result->reachable}\n"; // 'valid', 'invalid', 'risky', 'unknown'
echo "Score: {$result->score}\n"; // 0-1 quality score
echo "Quality Grade: {$result->qualityGrade}\n"; // 'excellent', 'good', 'fair', 'poor'
echo "Disposable: " . ($result->disposable ? 'Yes' : 'No') . "\n";
echo "Role-based: " . ($result->roleBased ? 'Yes' : 'No') . "\n";
echo "Free Email: " . ($result->freeEmail ? 'Yes' : 'No') . "\n";
echo "Reason: {$result->reason}\n";
if ($result->didYouMean) {
echo "Did you mean: {$result->didYouMean}?\n";
}<?php
// Skip SMTP validation for faster results (less accurate)
$result = $client->validate('user@example.com', skipSmtp: true);The SDK automatically detects common email typos and suggests corrections:
<?php
use VerifyKit\VerifyKit;
$client = new VerifyKit(apiKey: $_ENV['VERIFYKIT_API_KEY']);
// Validate an email with a typo
$result = $client->validate('user@gmial.com'); // Note: "gmial" instead of "gmail"
if ($result->didYouMean) {
echo "Did you mean: {$result->didYouMean}?\n";
// Output: "Did you mean: user@gmail.com?"
// Ask user to confirm or automatically correct
$confirmedEmail = $result->didYouMean;
$correctedResult = $client->validate($confirmedEmail);
echo "Corrected email is " . ($correctedResult->valid ? 'valid' : 'invalid') . "\n";
}
// Common typos detected:
// - gmial.com → gmail.com
// - gmai.com → gmail.com
// - hotmial.com → hotmail.com
// - yaho.com → yahoo.com
// - outlok.com → outlook.com
// And many more...<?php
$emails = [
'john.doe@gmail.com',
'jane.smith@company.com',
'invalid@email',
'test@disposable.com'
];
$result = $client->validateBulk($emails);
// Summary statistics
echo "Total: {$result->summary->total}\n";
echo "Valid: {$result->summary->valid}\n";
echo "Invalid: {$result->summary->invalid}\n";
echo "Risky: {$result->summary->risky}\n";
echo "Processing Time: {$result->summary->processingTimeMs}ms\n";
echo "Duplicates Removed: {$result->summary->duplicatesRemoved}\n";
// Individual results
foreach ($result->results as $email) {
$status = $email->valid ? '✓' : '✗';
echo "{$status} {$email->email}\n";
}<?php
$result = $client->validateBulk($emails);
if ($result->summary->quotaExceeded) {
echo "Processed {$result->summary->total} emails\n";
echo "Skipped {$result->summary->emailsSkipped} emails due to quota\n";
echo "Remaining quota: {$result->summary->quotaRemaining}\n";
}<?php
$usage = $client->getUsage();
echo "Current: {$usage->current}\n"; // Current month usage
echo "Limit: {$usage->limit}\n"; // Monthly limit
echo "Remaining: {$usage->remaining}\n"; // Remaining validations
echo "Percentage: {$usage->percentage}%\n"; // Usage percentage
echo "Period Start: {$usage->periodStart}\n"; // Billing period start
echo "Period End: {$usage->periodEnd}\n"; // Billing period end<?php
$client->validate('user@example.com');
$metadata = $client->getLastMetadata();
if ($metadata) {
echo "Request ID: {$metadata->requestId}\n";
echo "Cache: {$metadata->cache}\n"; // 'HIT' or 'MISS'
echo "Response Time: {$metadata->responseTime}ms\n";
if ($metadata->rateLimit) {
echo "Rate Limit: {$metadata->rateLimit->limit}\n";
echo "Remaining: {$metadata->rateLimit->remaining}\n";
echo "Reset: {$metadata->rateLimit->reset}\n";
}
if ($metadata->usage) {
echo "Current Usage: {$metadata->usage['current']}/{$metadata->usage['limit']}\n";
}
}<?php
use VerifyKit\VerifyKit;
$client = new VerifyKit(
// Required: Your API key (use environment variable)
apiKey: $_ENV['VERIFYKIT_API_KEY'],
// Optional: Base URL (default: 'https://api.verifykit.io')
baseUrl: 'https://api.verifykit.io',
// Optional: Request timeout in seconds (default: 30)
timeout: 30,
// Optional: Maximum number of retries (default: 3)
maxRetries: 3,
// Optional: Enable debug logging (default: false)
debug: true,
// Optional: Custom headers
headers: [
'X-Custom-Header' => 'value'
]
);Validate a single email address.
Parameters:
$email(string): The email address to validate$skipSmtp(bool): Skip SMTP validation for faster results
Returns: ValidationResult
Example:
$result = $client->validate('user@example.com', skipSmtp: false);Validate multiple email addresses at once (up to 1,000).
Parameters:
$emails(string[]): Array of email addresses to validate$skipSmtp(bool): Skip SMTP validation for faster results
Returns: BulkValidationResult
Example:
$result = $client->validateBulk([
'user1@example.com',
'user2@example.com'
]);Get current API usage statistics.
Returns: UsageStats
Example:
$usage = $client->getUsage();
echo "Used: {$usage->current}/{$usage->limit}";Get metadata from the last API request.
Returns: ResponseMetadata|null
Example:
$metadata = $client->getLastMetadata();
echo $metadata?->requestId;The SDK provides detailed exception classes for different scenarios:
<?php
use VerifyKit\VerifyKit;
use VerifyKit\Exception\ValidationException;
use VerifyKit\Exception\AuthenticationException;
use VerifyKit\Exception\RateLimitException;
use VerifyKit\Exception\QuotaExceededException;
use VerifyKit\Exception\TimeoutException;
use VerifyKit\Exception\NetworkException;
use VerifyKit\Exception\ServerException;
use VerifyKit\Exception\VerifyKitException;
$client = new VerifyKit(apiKey: $_ENV['VERIFYKIT_API_KEY']);
try {
$result = $client->validate('invalid-email');
} catch (ValidationException $e) {
echo "Invalid email format: {$e->getMessage()}\n";
} catch (AuthenticationException $e) {
echo "Invalid API key: {$e->getMessage()}\n";
} catch (RateLimitException $e) {
echo "Rate limit exceeded, retry after: {$e->retryAfter}\n";
} catch (QuotaExceededException $e) {
echo "Monthly quota exceeded: {$e->getMessage()}\n";
echo "Upgrade at: {$e->upgradeUrl}\n";
} catch (TimeoutException $e) {
echo "Request timeout: {$e->timeout}s\n";
} catch (NetworkException $e) {
echo "Network error: {$e->getMessage()}\n";
} catch (ServerException $e) {
echo "Server error, request ID: {$e->requestId}\n";
} catch (VerifyKitException $e) {
echo "VerifyKit error: {$e->getMessage()}\n";
} catch (\Exception $e) {
echo "Unknown error: {$e->getMessage()}\n";
}All VerifyKit exceptions include:
getMessage(): Human-readable error messagecode: Machine-readable error codestatusCode: HTTP status coderequestId: Request ID for debuggingdocumentation: Link to relevant documentation
The SDK automatically retries failed requests with exponential backoff:
<?php
$client = new VerifyKit(
apiKey: 'vk_live_...',
maxRetries: 5 // Retry up to 5 times (default: 3)
);Retries are attempted for:
- Network errors
- Timeout errors
- Server errors (5xx)
- Rate limit errors (with appropriate delay)
The SDK automatically handles rate limits by:
- Detecting rate limit errors (429)
- Waiting for the
Retry-Afterduration - Retrying the request automatically
<?php
// The SDK handles this automatically
try {
$result = $client->validate('user@example.com');
} catch (RateLimitException $e) {
// Only throws if max retries exceeded
echo "Still rate limited after retries\n";
}Enable debug logging to see detailed request/response information:
<?php
$client = new VerifyKit(
apiKey: 'vk_live_...',
debug: true
);
// Logs will show:
// - Request details
// - Response metadata
// - Retry attempts
// - Error informationConfigure request timeouts:
<?php
$client = new VerifyKit(
apiKey: 'vk_live_...',
timeout: 60 // 60 seconds
);The SDK includes comprehensive test coverage:
# Run all tests
composer test
# Run only unit tests (fast, no API key required)
./vendor/bin/pest tests/Unit
# Run integration tests (requires VERIFYKIT_API_KEY)
export VERIFYKIT_API_KEY=vk_test_your_key
./vendor/bin/pest --group=integration
# Generate coverage report
composer test:coverage- Unit Tests (
tests/Unit/) - Fast tests without API calls - Integration Tests (
tests/Integration/) - Real API tests- API functionality tests
- Error handling tests
- Retry logic tests
- Performance tests
See tests/README.md for detailed testing documentation.
Check out the examples directory for more usage examples:
basic-usage.php- Basic single email validationbulk-validation.php- Bulk email validationtypo-detection.php- Email typo detection and correctionerror-handling.php- Comprehensive error handling
Contributions are welcome! Please feel free to submit a Pull Request.
- 📧 Email: support@verifykit.io
- 📖 Documentation: https://verifykit.io/docs
MIT © Nuno Miguel Duarte Unip. Lda
Made with ♥ by the VerifyKit team