Official WordPress plugin for email validation on registration, WooCommerce checkout, WPForms, Gravity Forms, and Contact Form 7. Includes admin dashboard, bulk validation, and WP-CLI.
Install the plugin for automatic email validation with zero code. Includes settings page, form integrations, bulk validation, dashboard widget, and WP-CLI commands.
Upload the ZIP from GitHub and activate via Plugins menu. No dependencies required.
Go to Settings > MailOdds, paste your API key, and enable the form integrations you need.
Registrations, checkouts, and contact forms are now validated automatically.
This email address could not be verified. Please use a different email.
The MailOdds WordPress plugin validates email addresses in real time by calling the MailOdds API whenever a user submits a form. When someone registers on your site, checks out on WooCommerce, or fills in a contact form, the plugin sends the email to the MailOdds validation service before the form is accepted. Invalid, disposable, and risky emails are blocked immediately, preventing fake accounts, failed deliveries, and wasted resources.
The plugin uses a fail-open design: if the MailOdds API is temporarily unreachable, form submissions proceed normally. No legitimate user is ever blocked because of an API timeout. Results are cached for 24 hours using WordPress transients, so repeat submissions of the same email do not consume additional API credits.
You configure the block threshold in Settings. The "Reject" threshold blocks only clearly invalid and disposable emails. The "Caution" threshold also blocks risky addresses like catch-all domains and role accounts. Every validation is logged, and a dashboard widget shows your 7-day validation stats at a glance.
Validate emails and manage users from the command line.
# WP-CLI commands (included in the plugin)
# Validate a single email
wp mailodds validate user@example.com
# Validate with JSON output
wp mailodds validate user@example.com --format=json
# Bulk validate all unvalidated WordPress users
wp mailodds bulk
# Bulk validate with batch size and limit
wp mailodds bulk --batch=100 --limit=500
# Show plugin status and stats
wp mailodds status Skip the plugin and add validation directly to functions.php.
// functions.php - Manual integration (if not using the plugin)
// Validates email on registration with caching and fail-open timeout
add_action('registration_errors', function($errors, $sanitized_user_login, $user_email) {
// Skip if API key not defined
if (!defined('MAILODDS_API_KEY')) {
return $errors;
}
// Check transient cache (24h TTL)
$cache_key = 'mailodds_' . substr(hash('sha256', strtolower($user_email)), 0, 16);
$cached = get_transient($cache_key);
if (false === $cached) {
$response = wp_remote_post('https://api.mailodds.com/v1/validate', [
'headers' => [
'Authorization' => 'Bearer ' . MAILODDS_API_KEY,
'Content-Type' => 'application/json',
],
'body' => json_encode(['email' => $user_email]),
'timeout' => 5,
]);
// Fail-open: if API unreachable, allow registration
if (is_wp_error($response)) {
return $errors;
}
$cached = json_decode(wp_remote_retrieve_body($response), true);
// Cache for 24 hours
set_transient($cache_key, $cached, DAY_IN_SECONDS);
}
$action = isset($cached['action']) ? $cached['action'] : '';
if ('reject' === $action) {
$errors->add('invalid_email',
'<strong>Error:</strong> This email address could not be verified.');
}
return $errors;
}, 10, 3); // WooCommerce checkout validation (included in the plugin)
// Also validates on WooCommerce My Account registration
add_action('woocommerce_after_checkout_validation', function($data, $errors) {
$email = isset($data['billing_email']) ? $data['billing_email'] : '';
if (empty($email) || !defined('MAILODDS_API_KEY')) {
return;
}
$response = wp_remote_post('https://api.mailodds.com/v1/validate', [
'headers' => [
'Authorization' => 'Bearer ' . MAILODDS_API_KEY,
'Content-Type' => 'application/json',
],
'body' => json_encode(['email' => $email]),
'timeout' => 5,
]);
if (is_wp_error($response)) {
return; // Fail-open
}
$result = json_decode(wp_remote_retrieve_body($response), true);
if (isset($result['action']) && 'reject' === $result['action']) {
$errors->add('validation',
'This email address could not be verified. Please use a different email.');
}
}, 10, 2); Receive MailOdds webhook events (bounces, opens, clicks) via a WP REST API endpoint. The handler verifies the HMAC-SHA256 signature and routes events by type.
// functions.php or custom plugin
add_action('rest_api_init', function() {
register_rest_route('mailodds/v1', '/webhook', [
'methods' => 'POST',
'callback' => 'handle_mailodds_webhook',
'permission_callback' => 'verify_mailodds_signature',
]);
});
function verify_mailodds_signature($request) {
$signature = $request->get_header('X-MailOdds-Signature');
$secret = get_option('mailodds_webhook_secret');
$expected = hash_hmac('sha256', $request->get_body(), $secret);
return hash_equals($expected, $signature);
}
function handle_mailodds_webhook($request) {
$payload = $request->get_json_params();
$event = $payload['event'];
switch ($event) {
case 'message.bounced':
// Auto-suppress bounced email
break;
case 'message.opened':
if (!($payload['is_bot'] ?? false)) {
// Track human open
}
break;
case 'message.clicked':
if (!($payload['is_bot'] ?? false)) {
// Track human click
}
break;
}
return new WP_REST_Response(['status' => 'ok'], 200);
} MailOdds appends a mid parameter to links in your transactional emails. Capture this in your WooCommerce order flow to attribute purchases back to specific email campaigns.
Store the mid value in order metadata when a purchase completes. Combine with message.clicked webhook events to build a complete email-to-purchase attribution pipeline.
Schedule a daily wp_cron job to sync your suppression list from MailOdds. This keeps your local suppression data current without manual exports.
// Schedule daily suppression sync
add_action('mailodds_suppression_sync', 'sync_suppression_list');
if (!wp_next_scheduled('mailodds_suppression_sync')) {
wp_schedule_event(time(), 'daily', 'mailodds_suppression_sync');
}
function sync_suppression_list() {
$response = wp_remote_get('https://api.mailodds.com/v1/suppression', [
'headers' => [
'Authorization' => 'Bearer ' . MAILODDS_API_KEY,
],
'timeout' => 15,
]);
if (is_wp_error($response)) {
return;
}
$data = json_decode(wp_remote_retrieve_body($response), true);
if (!empty($data['suppressions'])) {
update_option('mailodds_suppression_list', $data['suppressions']);
}
} is_bot = true when the event came from a security scanner, link prefetcher, or corporate email gateway (not a human). Common with Barracuda, Proofpoint, and Mimecast.
is_mpp = true when the event came from Apple Mail Privacy Protection, which pre-fetches all images and inflates open counts. Affects roughly 50% of iOS/macOS mail users.
Both fields are Booleans on engagement events (opened, clicked). Always guard with == true since they may be absent on non-engagement events.
Beyond form validation, MailOdds connects to your WooCommerce store for product sync, transactional email, and revenue attribution.
Connect your WooCommerce store to MailOdds using the PHP SDK. Once connected, you can sync your product catalog, track orders, and attribute revenue to email campaigns.
// Connect WooCommerce store to MailOdds (PHP SDK)
use MailOdds\Client;
$client = new Client('YOUR_API_KEY');
// Connect your WooCommerce store
$store = $client->stores->connect([
'platform' => 'woocommerce',
'shop_domain' => 'your-store.com',
'consumer_key' => 'ck_...',
'consumer_secret' => 'cs_...'
]);
echo $store->id; // Store ID for sync operations
echo $store->status; // "connected" when ready
// Trigger product catalog sync
$client->stores->sync($store->id); Send WooCommerce order confirmations, shipping notifications, and other transactional emails through MailOdds. Each message gets DKIM signing, open/click tracking, and deliverability optimization.
// Send WooCommerce order confirmation via MailOdds (PHP SDK)
use MailOdds\Client;
$client = new Client('YOUR_API_KEY');
// Send order confirmation email
$result = $client->deliver([
'from' => 'orders@your-store.com',
'to' => $order->get_billing_email(),
'subject' => 'Order #' . $order->get_order_number() . ' confirmed',
'html' => $orderConfirmationHtml,
'tags' => ['order-confirmation', 'woocommerce'],
'metadata' => [
'order_id' => $order->get_id(),
'order_total' => $order->get_total()
]
]);
// $result->message_id for tracking
// Webhook events: delivered, opened, clicked After connecting your store, MailOdds syncs your WooCommerce product catalog. Query synced products to build dynamic email campaigns with product images, prices, and links.
// Query synced WooCommerce products for campaigns
$products = $client->storeProducts->list([
'store_id' => $storeId,
'limit' => 20,
'sort' => 'created_at'
]);
// Use in campaign templates
foreach ($products->data as $product) {
echo $product->title; // Product name
echo $product->price; // Current price
echo $product->image_url; // Product image
echo $product->url; // Product page URL
} Can't find what you're looking for? We're here to help you get WordPress working.
Free plugin with 1,000 validations included. Protect registrations and checkout in minutes.