WordPress + MailOdds
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.
Prerequisites
- MailOdds account with API key
- WordPress 5.9+ with admin access
MailOdds WordPress Plugin
Install the plugin for automatic email validation with zero code. Includes settings page, form integrations, bulk validation, dashboard widget, and WP-CLI commands.
Setup in 3 Steps
Install Plugin
Upload the ZIP from GitHub and activate via Plugins menu. No dependencies required.
Add API Key
Go to Settings > MailOdds, paste your API key, and enable the form integrations you need.
Emails Protected
Registrations, checkouts, and contact forms are now validated automatically.
This email address could not be verified. Please use a different email.
Plugin Features
Form Validation
- - WordPress core registration
- - WooCommerce registration + checkout
- - WPForms, Gravity Forms, Contact Form 7
- - Configurable block threshold
- - Fail-open on API timeout
Admin Tools
- - Settings page (API key, depth, threshold)
- - Dashboard widget with 7-day stats
- - Bulk user validation tool
- - Test mode with badge indicator
- - Policy support
Performance
- - 24h transient cache per email
- - Batch API calls for bulk operations
- - Lightweight (no external dependencies)
- - Assets loaded only on plugin pages
Automation
- - WP-CLI: validate, bulk, status
- - Weekly cron for unvalidated users
- - Per-user validation metadata
- - Clean uninstall (removes all data)
How It Works
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.
For Developers
WP-CLI Commands
Validate emails and manage users from the command line.
WP-CLI: MailOdds Commands
BASH# 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 Manual PHP Integration
Skip the plugin and add validation directly to functions.php.
▶
Manual PHP Integration
Skip the plugin and add validation directly to functions.php.
PHP: Registration Validation (with caching)
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); PHP: WooCommerce Checkout Validation
PHP// 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); Webhook Event Handling
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.
WP REST API: Webhook Endpoint
PHP// 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);
} WooCommerce Conversion Tracking
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.
Suppression Sync
Schedule a daily wp_cron job to sync your suppression list from MailOdds. This keeps your local suppression data current without manual exports.
wp_cron: Daily Suppression Sync
PHP// 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']);
}
} Understanding is_bot and is_mpp in Webhook Events
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.
Frequently Asked Questions
Troubleshooting
Need more help?
Can't find what you're looking for? We're here to help you get WordPress working.
Related Integrations
Block Fake Signups on WordPress
Free plugin with 1,000 validations included. Protect registrations and checkout in minutes.