Gravity Forms email validation can go further than the address format. Whether jane@ can receive mail is something only the receiving server knows. The gform_field_validation filter lets you ask it: the plugin below sends each Email field’s value to our email validation API and shows an error on the field if the mailbox can’t receive mail or the address is disposable.
What you get
- An inline error on the Email field, in Gravity Forms’ own style, before the entry is saved and before any notification or feed runs.
- A suggested correction in the message when the API returns one in
did_you_mean. - Disposable addresses rejected with their own message. Delete the
elseifblock if your form should accept them. unknownand catch-all results accepted.unknownmeans the mail server gave no clear answer; catch-all domains come back asdeliverablewith the reasonlow_deliverability, because they accept every address (see the catch-all email guide).- Fail-open: if the API can’t be reached, the key is missing or your quota is used up, the entry goes through as before.
Gravity Forms email validation filter: setup in steps
Create an API key in your emailvalidation.io account.
Put the key in
wp-config.php, not in the code, so it stays out of your theme, your database and version control:define( 'EMAILVALIDATION_API_KEY', 'your-api-key' );Save the code below as
wp-content/. Gravity Forms’ documentation also lists the theme’splugins/ evio-gravity-forms-email/ evio-gravity-forms-email.php functions.phpand code snippets plugins as places for filters; a small plugin survives theme updates.Go to Plugins and activate “Gravity Forms email check (emailvalidation.io)”.
Submit a test entry with an address on a domain that doesn’t exist. The Email field should show the error.
<?php
/**
* Plugin Name: Gravity Forms email check (emailvalidation.io)
* Description: Rejects undeliverable and disposable addresses in Email fields.
*/
defined( 'ABSPATH' ) || exit;
/**
* Checks one address with GET /v1/info. Returns the API result, or null when
* there is no usable answer (no key, network error, quota, timeout).
*/
function evio_gf_check_email( string $email ): ?array {
if ( ! defined( 'EMAILVALIDATION_API_KEY' ) ) {
return null;
}
// Validation runs again on every submit attempt; reuse the first answer.
$cache_key = 'evio_' . md5( strtolower( $email ) );
$cached = get_transient( $cache_key );
if ( is_array( $cached ) ) {
return $cached;
}
$response = wp_remote_get(
add_query_arg( 'email', rawurlencode( $email ), 'https://api.emailvalidation.io/v1/info' ),
array(
'timeout' => 10,
'headers' => array( 'apikey' => EMAILVALIDATION_API_KEY ),
)
);
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return null;
}
$result = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! is_array( $result ) ) {
return null;
}
set_transient( $cache_key, $result, DAY_IN_SECONDS );
return $result;
}
add_filter( 'gform_field_validation', 'evio_gf_validate_email', 10, 4 );
function evio_gf_validate_email( $result, $value, $form, $field ) {
// Only Email fields that passed Gravity Forms' own checks.
if ( 'email' !== $field->get_input_type() || ! $result['is_valid'] ) {
return $result;
}
// With "Enable Email Confirmation", $value holds both inputs.
$email = trim( (string) ( is_array( $value ) ? rgar( $value, 0 ) : $value ) );
if ( '' === $email ) {
return $result;
}
$check = evio_gf_check_email( $email );
if ( null === $check ) {
return $result; // No answer from the API: accept the entry.
}
if ( 'undeliverable' === ( $check['state'] ?? '' ) ) {
$result['is_valid'] = false;
$result['message'] = empty( $check['did_you_mean'] )
? 'We can’t deliver email to this address. Please check it for typos.'
: sprintf( 'We can’t deliver email to this address. Did you mean %s?', esc_html( $check['did_you_mean'] ) );
} elseif ( ! empty( $check['disposable'] ) ) {
$result['is_valid'] = false;
$result['message'] = 'Please use a permanent email address, not a disposable one.';
}
return $result;
}
The filter runs for every field of every form and returns early for anything that isn’t an Email field or already failed Gravity Forms’ own checks for that field, so other fields cost nothing. To check one form only, register the callback on gform_ or gform_ instead; with five accepted arguments, the filter also receives $context (Gravity Forms 2.6.3.2 and later).
Gravity Forms’ own documentation has a similar example for a third-party verification API. The version here adds what a production form needs: the API key from wp-config.php, a timeout, a fail-open path when the API doesn’t answer, and a one-day cache so a visitor who fixes another field and submits again doesn’t trigger a second check.
Example workflow
A webinar registration form with Name, Email (with Enable Email Confirmation) and Company:
- A visitor enters
max@twice and submits.northwind-tradres .example - Gravity Forms validates the fields. For the Email field,
$valueis an array with both inputs; the filter reads the first. - The API answers
undeliverablebecause the domain doesn’t exist. The field shows “We can’t deliver email to this address. Please check it for typos.” - The visitor corrects the domain. The new address is
deliverable, the entry is saved, and the confirmation email with the webinar link arrives.
Without the check, the entry would have been saved, the confirmation would have bounced (a hard bounce), and the visitor would never have joined. If entries already contain bad addresses, export them to CSV and check them with the bulk email verifier (up to 50 per run) or the bulk endpoint of the API.
For other PHP forms, the PHP email validation guide shows the same API call with cURL and as a Laravel rule.
Pricing note
Each check costs 1 credit, and only successful calls count. The filter calls the API once per distinct address per day and only for Email fields. The free plan includes 100 credits a month and allows 10 requests a minute; paid plans have no per-minute limit and start at $9.99 a month for 5,000 credits (email validation API pricing).
Sources
Checked October 10, 2026: Gravity Forms Documentation, gform_field_validation (parameters, form- and field-specific variants, email confirmation array, placement, third-party API example); Gravity Forms, Zapier Add-On (license); WordPress Developer Reference, wp_remote_get(), add_query_arg() and set_transient(); Zapier, Emailvalidation integrations.