Official BillionVerify PHP SDK for email verification.
Documentation: https://billionverify.com/docs
- PHP 8.1 or higher
- Composer
composer require billionverify/billionverify-php<?php
require 'vendor/autoload.php';
use BillionVerify\Client;
$client = new Client('your-api-key');
// Verify a single email
$result = $client->verify('user@example.com');
echo $result['data']['status']; // 'valid', 'invalid', 'unknown', 'catchall', 'risky', 'disposable', 'role'$client = new Client(
apiKey: 'your-api-key', // Required
baseUrl: 'https://api.billionverify.com/v1', // Optional
timeout: 30, // Optional: Request timeout in seconds (default: 30)
retries: 3 // Optional: Number of retries (default: 3)
);$result = $client->verify(
email: 'user@example.com',
checkSmtp: true // Optional: Perform SMTP verification (default: true)
);
echo $result['data']['email']; // 'user@example.com'
echo $result['data']['status']; // 'valid'
echo $result['data']['score']; // 0.95
echo $result['data']['is_deliverable']; // true
echo $result['data']['is_disposable']; // falseVerify up to 50 emails in a single synchronous request.
$results = $client->verifyBatch(
emails: ['user1@example.com', 'user2@example.com', 'user3@example.com'],
checkSmtp: true // Optional
);
echo $results['data']['total_emails']; // 3
echo $results['data']['valid_emails']; // 2
echo $results['data']['credits_used']; // 2
foreach ($results['data']['results'] as $item) {
echo "{$item['email']}: {$item['status']}\n";
}For larger lists (up to 100,000 emails), upload a file for asynchronous processing.
// Upload a file
$job = $client->uploadFile(
filePath: '/path/to/emails.csv',
checkSmtp: true, // Optional: Perform SMTP verification (default: true)
emailColumn: 'email', // Optional: Column name (auto-detected if null)
preserveOriginal: true // Optional: Keep original columns in result (default: true)
);
echo $job['data']['task_id']; // '7143874e-21c5-43c1-96f3-2b52ea41ae6a'
// Check job status (with optional long-polling)
$status = $client->getFileJobStatus(
jobId: $job['data']['task_id'],
timeout: 60 // Optional: Wait up to 60 seconds for completion (0-300)
);
echo $status['data']['progress_percent']; // 45
// Wait for completion (polling)
$completed = $client->waitForFileJobCompletion(
jobId: $job['data']['task_id'],
pollInterval: 5, // seconds
maxWait: 600 // seconds
);
// Download results with optional filters
$results = $client->getFileJobResults(
jobId: $job['data']['task_id'],
valid: true, // Include valid emails
invalid: false, // Exclude invalid emails
catchall: true, // Include catch-all emails
role: false, // Exclude role emails
unknown: false, // Exclude unknown emails
disposable: false, // Exclude disposable emails
risky: false // Exclude risky emails
);Check API health (no authentication required).
// Static method - can be called without an API key
$health = Client::healthCheck();
echo $health['status']; // 'ok'
echo $health['time']; // Unix timestamp
// With custom base URL
$health = Client::healthCheck('https://api.billionverify.com');$credits = $client->getCredits();
echo $credits['data']['credits_balance']; // 9500
echo $credits['data']['credits_consumed']; // 500// Create a webhook (secret is returned in response - store it securely!)
$webhook = $client->createWebhook(
url: 'https://your-app.com/webhooks/billionverify',
events: ['file.completed', 'file.failed']
);
echo $webhook['data']['id']; // Webhook ID
echo $webhook['data']['secret']; // Store this securely!
// List webhooks
$webhooks = $client->listWebhooks();
// Delete a webhook
$client->deleteWebhook($webhook['data']['id']);
// Verify webhook signature
$isValid = Client::verifyWebhookSignature(
payload: $rawBody,
signature: $signatureHeader,
secret: 'your-stored-webhook-secret'
);use BillionVerify\Client;
use BillionVerify\Exception\AuthenticationException;
use BillionVerify\Exception\RateLimitException;
use BillionVerify\Exception\ValidationException;
use BillionVerify\Exception\InsufficientCreditsException;
use BillionVerify\Exception\NotFoundException;
use BillionVerify\Exception\TimeoutException;
use BillionVerify\Exception\BillionVerifyException;
try {
$result = $client->verify('user@example.com');
} catch (AuthenticationException $e) {
echo "Invalid API key\n";
} catch (RateLimitException $e) {
echo "Rate limited. Retry after {$e->getRetryAfter()} seconds\n";
} catch (ValidationException $e) {
echo "Invalid input: {$e->getMessage()}\n";
echo "Details: {$e->getDetails()}\n";
} catch (InsufficientCreditsException $e) {
echo "Not enough credits (HTTP 402)\n";
} catch (NotFoundException $e) {
echo "Resource not found\n";
} catch (TimeoutException $e) {
echo "Request timed out\n";
} catch (BillionVerifyException $e) {
echo "Error [{$e->getErrorCode()}]: {$e->getMessage()}\n";
}Available webhook events:
file.completed- File verification job completed successfullyfile.failed- File verification job failed
valid- Email exists and can receive messagesinvalid- Email doesn't exist or can't receive messagesunknown- Could not determine validity with certaintycatchall- Domain accepts all emails (catch-all server)risky- Email is deliverable but may have issuesdisposable- Temporary/disposable email addressrole- Role-based email (info@, support@, etc.)
invalidemails: 0 credits (not charged)unknownstatus: 0 credits (not charged)- All other statuses (
valid,risky,disposable,catchall,role): 1 credit each
MIT