---
title: "Gravity Forms Hooks: Developer Reference & Examples"
description: "A developer reference to the most useful Gravity Forms hooks: submission, validation, field, entry, and notification filters — with examples."
url: "https://wpwebhooks.org/blog/gravity-forms-hooks-reference/"
date: "2026-06-18"
---

# Gravity Forms Hooks: Developer Reference & Examples

**TL;DR**

-   Gravity Forms exposes its lifecycle through **actions** (do something when an event fires) and **filters** (modify a value before the plugin uses it).
-   The hooks you reach for most: `gform_pre_submission`, `gform_validation`, `gform_after_submission`, `gform_after_update_entry`, and the field filters `gform_pre_render` and `gform_field_value_*`.
-   To fire a webhook on submit, hook `gform_after_submission` — it runs once the entry is saved, so you have the entry ID and all field values.
-   The [Webhook Actions plugin](https://wpwebhooks.org/wordpress-webhook-plugin/) binds to these hooks from the admin UI, so you get async delivery, retries, and logs without writing the dispatch code yourself.

/ Overview

## What are Gravity Forms hooks?

Gravity Forms hooks are the WordPress actions and filters the plugin fires as a form moves through its lifecycle — render, validation, submission, entry storage, notification, and confirmation. You attach a callback with `add_action()` or `add_filter()` and run your own logic at exactly the right moment, without editing the plugin.

There are hundreds of them. In practice a handful cover almost every integration: validate input, modify a field before it renders, react after an entry is saved, and react when an entry is later edited. Everything below is organized by where it fires in the lifecycle, with the canonical Gravity Forms documentation linked for each¹.

FIG 01 — Gravity Forms submission hook order

/ Actions vs filters

## How do Gravity Forms actions and filters differ?

Actions let you _do_ something; filters let you _change_ something. An action callback receives data and returns nothing — `gform_after_submission` hands you the saved entry so you can send it somewhere. A filter callback receives a value and must return it (modified or not) — `gform_pre_render` hands you the form array and expects the form array back.

The practical rule: if your callback forgets to `return` inside a filter, you will blank out the value Gravity Forms was about to use. Actions have no such trap. When in doubt, the docs label each hook as an action or a filter at the top of its page².

| Hook | Type | Fires when | Use it for |
| --- | --- | --- | --- |
| gform\_pre\_render | Filter | Before the form is rendered | Inject choices, hide fields, set defaults |
| gform\_field\_validation | Filter | Per field, on submit | Reject a single field |
| gform\_validation | Filter | On submit, across all fields | Reject a submission with custom logic |
| gform\_pre\_submission | Action | After validation, before save | Mutate $\_POST values |
| gform\_after\_submission | Action | After the entry is saved | Webhooks, CRM sync, analytics |
| gform\_after\_update\_entry | Action | An existing entry is edited | Propagate edits downstream |
| gform\_confirmation | Filter | After save, before display | Change the confirmation or redirect |
| gform\_pre\_send\_email | Filter | Before a notification is sent | Rewrite or abort the email |

/ Submission

## Which hooks fire when a form is submitted?

Three matter most, in order. `gform_pre_submission` runs after validation passes but before the entry is saved — the last point you can mutate `$_POST['input_5']` values. `gform_after_submission` runs once the entry exists in the database, giving you the complete `$entry` array (including `$entry['id']`) and the `$form` definition. `gform_after_email` fires after notifications are sent.

Use `gform_after_submission` for almost all outbound integrations — CRM sync, webhook dispatch, analytics — because the entry is persisted and has a stable ID to deduplicate on.

PHP — react after a submission is saved

```
// Fires once the entry is in the database. $entry has the ID + all fields.
add_action( 'gform_after_submission', function( $entry, $form ) {
    $email = rgar( $entry, '3' );   // field ID 3
    $entry_id = $entry['id'];
    // hand off to your integration here
}, 10, 2 );
```

/ Validation

## How do you validate submissions with gform\_validation?

Use `gform_validation` to reject a submission server-side based on logic Gravity Forms cannot express in the field settings — a remote API check, a duplicate-entry lookup, a business rule across multiple fields. The filter hands you a `$validation_result` array; set `['is_valid'] = false`, mark the offending field's `failed_validation`, and return the array.

For single-field checks, `gform_field_validation` is narrower and simpler. Both run before the entry is saved, so a failed validation means no entry, no notifications, and no `gform_after_submission` — which is exactly why validation is the right place to stop bad data, not a post-submission webhook.

> Validation hooks run before the entry is saved — so rejecting bad input there means it never reaches your downstream systems in the first place.

/ Fields

## How do you change field values and choices before render?

`gform_pre_render` is the filter for modifying a form on the way to the screen — inject choices into a dropdown, hide a field, or change a default. It receives the `$form` array and must return it. For pre-populating a single field from a query string or dynamic source, the field-specific `gform_field_value_{parameter_name}` filter is more precise and avoids rebuilding the whole form array³.

Both are filters, so the cardinal rule applies: always return the value. A common mistake is calling `gform_pre_render` to read the form and forgetting to return it, which renders an empty form.

![Cyberpunk illustration titled “Gravity Forms Hooks — Developer Reference & Examples” showing a developer at a holographic console beside a glowing “Gravity Forms Hooks” database cylinder, labelled with apply_filters(), do_action(), gform_pre_render and gform_after_submission.](https://wpwebhooks.org/blog/gravity-forms-hooks-reference/og_image.jpg)

/ Entries

## Which hooks fire when an entry is created or updated?

`gform_after_submission` covers new entries. For edits, `gform_after_update_entry` fires when an existing entry is changed from the wp-admin entry editor or via the GFAPI — and it hands you both the updated entry and the `$original_entry`, so you can diff fields and only act on real changes. This pairing is what lets you keep a downstream CRM mirrored rather than just snapshotting it at submit time.

We cover both in depth: the [gform\_after\_submission webhook guide](https://wpwebhooks.org/blog/gravity-forms-gform-after-submission-webhook/) for new submissions, and the [gform\_after\_update\_entry guide](https://wpwebhooks.org/blog/gravity-forms-gform-after-update-entry-webhook/) for edits and deduplication.

/ Notifications

## How do you customize confirmations and notifications?

`gform_confirmation` filters what the user sees after submitting — swap the confirmation message, change the redirect URL conditionally, or return a different confirmation per logic branch. `gform_pre_send_email` filters the notification email immediately before it is sent, letting you rewrite recipients, subject, or body, or abort the send entirely by setting `$email['abort_email'] = true`.

Both are filters and both fire after the entry is saved, so they are safe places to read final entry values but the wrong place to do outbound integration work — use `gform_after_submission` for that.

/ Webhooks

## Which hook should you use to fire a webhook?

Use `gform_after_submission` for new submissions and `gform_after_update_entry` for edits. Both fire after the entry is persisted, so the payload has a stable entry ID and complete field values — everything a receiving system needs to deduplicate and process the event. Firing from a pre-save hook risks sending data for a submission that later fails validation.

The raw approach is a hook callback that builds a payload and calls `wp_remote_post()`. That works until the endpoint is slow (your form submit blocks on it), returns a 500 (you have no retry), or silently changes (you have no log). The [Gravity Forms to n8n guide](https://wpwebhooks.org/blog/gravity-forms-to-n8n-webhook/) walks through the full pattern.

| Capability | Raw hook + wp\_remote\_post | Webhook Actions |
| --- | --- | --- |
| Setup | Custom PHP per form and hook | Admin UI trigger picker — no code |
| Timing | Synchronous — blocks the form submit | Async queue — submit returns immediately |
| Retry | None — one attempt only | Exponential backoff, default 5 attempts |
| Logs | None — failures are invisible | Per-attempt log with status + response body |
| Replay | Not possible without custom tooling | One-click replay from the Logs screen |

→

The [Webhook Actions plugin](https://wpwebhooks.org/wordpress-webhook-plugin/) turns any `do_action` into a webhook trigger from the admin UI — pick `gform_after_submission`, `gform_after_update_entry`, or any other Gravity Forms hook (even your own custom action), point it at an endpoint, and delivery runs through a background queue with smart retry and exponential backoff (1m → 2m → 4m → 8m, capped at 1 hour; 5 attempts) and a full delivery log — no dispatch code on your side.

/Footnotes

¹ [Gravity Forms hooks index](https://docs.gravityforms.com/category/developers/hooks/) — the canonical list of actions and filters.

² Per-hook references: [gform\_after\_submission](https://docs.gravityforms.com/gform_after_submission/), [gform\_validation](https://docs.gravityforms.com/gform_validation/), [gform\_pre\_submission](https://docs.gravityforms.com/gform_pre_submission/), [gform\_confirmation](https://docs.gravityforms.com/gform_confirmation/), [gform\_pre\_send\_email](https://docs.gravityforms.com/gform_pre_send_email/).

³ Field filters: [gform\_pre\_render](https://docs.gravityforms.com/gform_pre_render/) and [gform\_field\_value\_{parameter\_name}](https://docs.gravityforms.com/gform_field_value_parameter_name/). Entry editing and the GFAPI: [GFAPI reference](https://docs.gravityforms.com/api-functions/).

## Structured data

```json
{"@context":"https://schema.org","@type":"Article","headline":"Gravity Forms Hooks: Developer Reference & Examples","description":"A developer reference to the most useful Gravity Forms hooks: submission, validation, field, entry, and notification filters — with examples.","datePublished":"2026-06-18","dateModified":"2026-06-18","author":{"@type":"Person","name":"Mateusz Skorupa","url":"https://wpwebhooks.org/about/"},"publisher":{"@type":"Organization","name":"WP Webhooks","url":"https://wpwebhooks.org"},"url":"https://wpwebhooks.org/blog/gravity-forms-hooks-reference/","image":{"@type":"ImageObject","url":"https://wpwebhooks.org/blog/gravity-forms-hooks-reference/og_image.jpg","width":1200,"height":630,"caption":"Cyberpunk illustration titled “Gravity Forms Hooks — Developer Reference & Examples” showing a developer at a holographic console beside a glowing “Gravity Forms Hooks” database cylinder, labelled with apply_filters(), do_action(), gform_pre_render and gform_after_submission."},"keywords":["gravity forms hooks","gravity forms hooks reference","gravity forms developer hooks","gravity forms action hooks","gravity forms filter hooks","gravity forms form lifecycle hooks"]}

{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"WP Webhooks","item":"https://wpwebhooks.org/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://wpwebhooks.org/blog/"},{"@type":"ListItem","position":3,"name":"Gravity Forms Hooks: Developer Reference & Examples","item":"https://wpwebhooks.org/blog/gravity-forms-hooks-reference/"}]}

{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"What are Gravity Forms hooks?","acceptedAnswer":{"@type":"Answer","text":"Gravity Forms hooks are the WordPress actions and filters the plugin fires throughout a form lifecycle — render, validation, submission, entry storage, notification, and confirmation. You attach a callback with add_action() or add_filter() to run custom logic at the right moment without editing the plugin."}},{"@type":"Question","name":"What is the difference between Gravity Forms actions and filters?","acceptedAnswer":{"@type":"Answer","text":"Actions let you do something when an event fires and return nothing — gform_after_submission hands you the saved entry. Filters let you modify a value and must return it — gform_pre_render hands you the form array and expects it back. Forgetting to return inside a filter blanks out the value Gravity Forms was about to use."}},{"@type":"Question","name":"Which Gravity Forms hook fires after a form is submitted?","acceptedAnswer":{"@type":"Answer","text":"gform_after_submission fires once the entry is written to the database, giving you the complete $entry array including the entry ID, plus the $form definition. It is the right hook for outbound integrations like CRM sync and webhook dispatch."}},{"@type":"Question","name":"How do I send a webhook from a Gravity Forms hook?","acceptedAnswer":{"@type":"Answer","text":"Hook gform_after_submission for new entries (or gform_after_update_entry for edits) and call wp_remote_post() with your payload. Both fire after the entry is saved, so the payload has a stable entry ID. The Webhook Actions plugin binds to these hooks from the admin UI and adds async delivery, retries, and logs without dispatch code."}},{"@type":"Question","name":"Where is the official Gravity Forms hooks documentation?","acceptedAnswer":{"@type":"Answer","text":"The canonical list lives at docs.gravityforms.com under the developers/hooks category. Each hook has its own reference page that labels it as an action or a filter and documents its parameters."}}]}
```
