Skip to content
Start with 100 free verification credits
Qualisend
All articles
Guides / May 13, 2026

Verify emails from Gravity Forms

9 minutes read

Qualisend team
Flow diagram showing a Gravity Forms submission passing through a gform_field_validation hook to the Qualisend verify API, which routes each address to deliverable (save), risky (tag), or undeliverable (reject).

Gravity Forms is the workhorse of serious WordPress sites — multi-page applications, registration flows, quote requests — and every one of them has an email field that checks the format and nothing else. To verify emails from Gravity Forms you don't install a branded plugin; you hook into the submission, call a verification API, and either reject a bad address inline or tag it after the fact. This guide covers the three supported paths: a PHP validation filter that blocks undeliverable and disposable addresses before the entry saves, the Webhooks Add-On for asynchronous tag-and-suppress, and a CSV export for cleaning your entry table in bulk.

The short answer#

Gravity Forms gives you two integration points, and which one you reach for depends on whether you want to stop a bad address or just react to it:

  1. Real time, inline — a small PHP snippet on the gform_field_validation filter calls the Qualisend API while the form is validating and returns a field error the visitor sees. This is the only place you can reject an address before it becomes an entry.
  2. Real time, async — the Webhooks Add-On POSTs each entry to a URL you control after it saves. It can't show an inline error, but it's perfect for tagging, routing, or suppressing undeliverable addresses before they reach your email tool.
  3. Bulk — export stored entries to CSV and run them through Qualisend's bulk verifier on a schedule. No code, works on any license that stores entries.

This article is the Gravity Forms-specific companion to the broader verify emails in WordPress forms guide, which covers Contact Form 7 and WPForms with the same patterns. If you run more than one form plugin, start there; if you're all-in on Gravity Forms, everything you need is below.

Why the Gravity Forms email field isn't enough#

The email field type validates that what someone typed looks like an address — an @, a domain, no stray spaces. That's a format check, and format is not deliverability. jane@gmial.com passes it. So does throwaway@mailinator.com, and so does a real-looking mailbox at a domain that lapsed six months ago. None of those are caught until you send, and by then a dead address is a hard bounce chipping at your bounce rate and sender reputation.

Real verification adds the layers Gravity Forms can't: a DNS/MX lookup, an SMTP mailbox probe, and flags for disposable, role, free, and catch-all addresses. If the pipeline is new to you, how email verification works breaks down each check and why it matters.

Verify emails from Gravity Forms at submit#

Gravity Forms exposes a field-level validation filter that fires during validation, before the entry is saved — which means you can invalidate the email field and hand the visitor an error message to fix. That's the gform_field_validation filter, and it's the right hook when you want an inline gate rather than after-the-fact cleanup.

The callback receives the field's current $result (with an is_valid flag and a message), the submitted $value, the $form, and the $field. You call the API, and if the verdict is bad you flip is_valid to false and set the message. Keep the API key in a wp-config.php constant — never in a form setting, theme file, or any front-end JavaScript:

// In a code-snippet plugin, or your theme's functions.php.
// In wp-config.php:  define( 'QUALISEND_API_KEY', 'YOUR_API_KEY' );

add_filter( 'gform_field_validation', 'qs_gf_verify_email', 10, 4 );

function qs_gf_verify_email( $result, $value, $form, $field ) {
    // Only run on email fields that already passed Gravity Forms' own checks.
    if ( $field->type !== 'email' || ! $result['is_valid'] ) {
        return $result;
    }

    // An email field with "confirm" enabled hands back an array.
    $email = is_array( $value ) ? rgar( $value, 0 ) : $value;
    $email = trim( (string) $email );
    if ( $email === '' ) {
        return $result; // let the field's own required-field check handle empties
    }

    // Confirm the exact endpoint and request body in /developers.
    $response = wp_remote_post( 'https://api.qualisend.com/v1/verify', array(
        'timeout' => 4, // cap it so a slow probe can't stall the form
        'headers' => array(
            'Authorization' => 'Bearer ' . QUALISEND_API_KEY,
            'Content-Type'  => 'application/json',
        ),
        'body' => wp_json_encode( array( 'email' => $email ) ),
    ) );

    // Fail open: a transient error must never block a real applicant.
    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
        return $result;
    }

    $verdict = json_decode( wp_remote_retrieve_body( $response ), true )['result'] ?? array();

    if ( ( $verdict['status'] ?? '' ) === 'undeliverable' ) {
        $result['is_valid'] = false;
        $result['message']  = "That address doesn't look deliverable — please check it.";
    } elseif ( ! empty( $verdict['sub_flags']['disposable'] ) ) {
        $result['is_valid'] = false;
        $result['message']  = 'Please use a permanent email address.';
    }

    return $result;
}

Three things carry this snippet, and they're the same three in every language: keep the key server-side, cap the request with a short timeout, and fail open — if the call errors, times out, or returns a non-200, let the submission through. A verification API is a quality filter, not an authentication gate, and losing a real lead to a momentary outage is the worse outcome. For the mechanics of the request itself — headers, error handling, the result response shape — the PHP email validation guide walks the same call end to end.

A note on scope: leaving the filter global (as above) verifies the email field on every form. To target one form, hook the form-and-field-specific variant gform_field_validation_{form_id}_{field_id} instead, or add an early if ( $form['id'] !== 5 ) return $result; guard. And if you need to validate across fields at once — say, only verify when another field is set — the form-level gform_validation filter gives you the whole $form and lets you mark individual fields as failed; the field filter above is simpler and enough for a single email gate.

Acting on the verdict#

The API returns a result object with a status of deliverable, risky, undeliverable, or unknown, plus a 0-100 score, a reason code, and sub-flags for disposable, role, free, and catch_all — the same $verdict the snippet reads. Map each to a form action:

VerdictForm action
undeliverableReject inline (validation filter) or drop before send (webhook).
disposable flagReject or flag, depending on how strict your form is — see role, disposable & free addresses.
risky / catch-allAccept, but tag it — route to the catch-all segment and send carefully.
unknownAccept. The mail server didn't answer — never lose a real submission over it.
deliverableAccept.

On a live form, lean on the fast local checks — syntax, domain, disposable, role — because they come back quickly and catch the bulk of junk without making the visitor wait. The heavier SMTP mailbox probe is better suited to the bulk path below, where a couple of seconds of latency doesn't matter to anyone.

The Webhooks Add-On route#

If custom PHP isn't an option — or you only need to keep dead addresses out of your downstream tool, not block the form — Gravity Forms' Webhooks Add-On does it with no code. It's a licensed add-on (bundled with higher-tier Gravity Forms licenses, so check your plan), and it fires a configurable HTTP request as a feed after each submission.

In the form's Settings → Webhooks, add a feed: set the request type to POST, the format to JSON, point the URL at an endpoint you control, and map the email field into the request body. Because you can't safely put an API key in the webhook's own headers and then call Qualisend from a third party, the clean pattern is to point the webhook at a small serverless function of your own — the exact setup in the verify-at-signup serverless guide. That function holds the key, receives the Gravity Forms payload, pulls the email, calls the API, and acts on the verdict.

The catch is timing. The Webhooks Add-On fires after the entry is already saved, so it runs asynchronously and cannot show the visitor a validation error — there is no inline rejection on this path. What it can do is verify within seconds and route on the result: add a tag in your CRM, skip the autoresponder for an undeliverable address, or suppress it before it ever reaches your email platform. If you need the visitor to see and fix a bad address, use the validation filter above; if downstream hygiene is all you're after, the webhook is enough.

Bulk-verify a Gravity Forms CSV export#

Not every form needs a real-time gate, and you'll also have a back catalogue of entries collected before you added one. For both, the zero-code route is to clean in batches:

  1. Export entries to CSV. In the Gravity Forms admin, open Forms → Import/Export → Export Entries, pick the form, include the email column, and download the file. You get one row per entry with the address in its own column.
  2. Bulk-verify the CSV. Upload it to Qualisend's bulk verifier, which runs the full pipeline — MX, the SMTP probe, and the disposable/role/catch-all flags — across every row and hands back a scored file with a status and reason per address.
  3. Filter and sync. Keep deliverable, review risky, and drop undeliverable before you import the survivors into your email platform.

This is the same export-verify-reimport loop as any list clean, just sourced from your Gravity Forms entry table — the guide to cleaning an email list covers it in full. Run the back catalogue once, then let a submit-time hook keep the list clean from there on.

Real time, bulk, or both#

They solve different problems, so most sites end up wanting both:

  • Real time is prevention. A typo caught at submit is a lead saved with a one-line correction; a dead domain rejected there never becomes a hard bounce.
  • Bulk is cleanup. Addresses decay — people change jobs, domains lapse — so even a perfectly gated list needs periodic re-verification.

Which real-time route you can use comes down to your license and your comfort with code: the validation filter needs a PHP snippet but gives you an inline block, while the Webhooks Add-On needs a paid tier but no code and handles async tagging. Pairing whichever you choose with an occasional bulk pass is the whole strategy.

Frequently asked questions#

Can Gravity Forms verify email addresses on its own?#

Only the format. The email field type confirms an address is well-formed — it has an @ and a domain — but it doesn't resolve MX records or probe the mailbox, so a typo'd, disposable, or long-dead address that looks valid still gets through. Real verification needs the DNS and SMTP layers a service like Qualisend adds on top, called from a validation filter, a webhook, or a bulk CSV job.

Can a Gravity Forms webhook reject a bad address inline?#

No. The Webhooks Add-On fires after the entry is saved, so it runs asynchronously and can't show the visitor a validation error. It's ideal for tagging, routing, or suppressing undeliverable addresses before they reach your email tool. For an inline rejection the visitor sees and can fix, use the gform_field_validation filter with the PHP snippet in this guide instead.

Which Gravity Forms hook should I use to verify at submit?#

Use gform_field_validation for a single email field — it fires during validation, receives the field value, and lets you return an error inline. If you need to validate across several fields or run the check conditionally on the whole form, use the form-level gform_validation filter and mark individual fields as failed. Both run server-side before the entry saves, so both can block.

Is there a native Qualisend add-on for Gravity Forms?#

Not right now — our native platform integrations are being rebuilt, and a Gravity Forms connector is on the roadmap. Until it ships, the supported approaches are the three in this guide: call the REST API from the validation filter, from a serverless function behind the Webhooks Add-On, or export entries to CSV and bulk-verify. All use the documented API directly.


Ready to wire it up? The free plan includes credits to test every path, the API reference has the exact /verify request for your validation filter or serverless function, and the free email checker lets you spot-test a single address before you write a line of PHP.

Your reputation, protected.

Clean your first list in minutes. 100 free credits, no card required.

Get started