Integration · Gravity Forms

Gravity Forms email validation

The Email field collects an address. With one filter, Gravity Forms can also make sure the address works, before the entry is saved and your notifications go out.

Updated October 10, 2026 · 5 min read

Gravity Forms email validation can go further than the address format. Whether jane@northwind-tradres.example 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

Gravity Forms email validation filter: setup in steps

  1. Create an API key in your emailvalidation.io account.

  2. 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' );
    
  3. Save the code below as wp-content/plugins/evio-gravity-forms-email/evio-gravity-forms-email.php. Gravity Forms’ documentation also lists the theme’s functions.php and code snippets plugins as places for filters; a small plugin survives theme updates.

  4. Go to Plugins and activate “Gravity Forms email check (emailvalidation.io)”.

  5. 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_field_validation_{form_id} or gform_field_validation_{form_id}_{field_id} 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:

  1. A visitor enters max@northwind-tradres.example twice and submits.
  2. Gravity Forms validates the fields. For the Email field, $value is an array with both inputs; the filter reads the first.
  3. The API answers undeliverable because the domain doesn’t exist. The field shows “We can’t deliver email to this address. Please check it for typos.”
  4. 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.

Email validation in other apps

Frequently asked questions

How do I validate emails in Gravity Forms?

Use the gform_field_validation filter. It receives each field’s value and a result array; set is_valid to false and add a message to reject the value. For a mailbox check, call an email validation API from the filter, as in the plugin on this page.

How do I apply the check to one form only?

Gravity Forms has form- and field-specific versions of the filter: gform_field_validation_6 runs for every field of form 6, and gform_field_validation_6_1 only for field 1 of form 6. Change the add_filter line to one of those names.

Why is the email value an array?

When Enable Email Confirmation is turned on for the Email field, Gravity Forms passes both inputs as an array. The filter then reads the first one with rgar( $value, 0 ), which the plugin on this page already does.

Can I use Zapier instead of code?

Zapier can check the address after the entry is saved, but it can’t reject the submission. The Gravity Forms Zapier Add-On needs a Pro, Elite or Nonprofit license; the Emailvalidation app’s Verify E-Mail Address action then checks the address.

Email validation API

Validate emails in your app

emailvalidation.io checks syntax, MX records and the mailbox over SMTP, flags disposable, role and free addresses and returns a quality score, in one request.

/v1/info Email validation API Read the documentation

100 free validations every month. No credit card required.

GET https://api.emailvalidation.io/v1/info?email=support@emailvalidation.io

{
  "email": "support@emailvalidation.io",
  "user": "support",
  "tag": "",
  "domain": "emailvalidation.io",
  "format_valid": true,
  "mx_found": true,
  "smtp_check": true,
  "catch_all": null,
  "role": true,
  "disposable": false,
  "free": false,
  "score": 0.64,
  "state": "deliverable",
  "reason": "valid_mailbox",
  "did_you_mean": ""
}

Keep reading

Start using our email validation software today!

Get 100 validations per month for free