WP Webhooks / Blog / Gravity Forms
Article · Gravity Forms

gform_after_update_entry: Gravity Forms Update Webhook

gform_after_update_entry fires when a Gravity Forms entry is edited in wp-admin or via API. Parameters, accessing original vs updated values, webhook dispatch, and deduplication.

7 min 2026-06-02
#gravity-forms#wordpress#webhooks

TL;DR

  • gform_after_update_entry fires after an existing entry is edited in wp-admin or updated via GFAPI::update_entry()
  • Three parameters: $form, $entry_id, $original_entry (pre-update state, GF 2.4+)
  • Retrieve the current entry with GFAPI::get_entry($entry_id) — the hook does not pass the updated entry directly
  • Webhook Actions handles update-triggered delivery natively — no custom PHP needed

/ What is gform_after_update_entry

What is gform_after_update_entry and when does it fire?

gform_after_update_entry is a Gravity Forms action hook that fires immediately after an existing form entry has been saved with new values. It covers three update paths: editing an entry in the wp-admin entry editor, updating via the GFAPI::update_entry() method from custom code, and updates triggered by Gravity Forms add-ons (such as User Registration or Feed add-ons that update entry data post-submission).

What it does not cover: new submissions. An entry created by a visitor submitting a form triggers gform_after_submission, not gform_after_update_entry. The two hooks are complementary — one fires on create, the other on update. Use both if you need to keep a downstream system fully in sync with all Gravity Forms entry state changes.

Visitor submits form
      │
      ▼
 Entry created in DB
      │
      ▼
 gform_after_submission ◄─ new-entry webhook here
      │
      │ (later — admin edits entry or GFAPI::update_entry)
      ▼
 Entry saved with new values in DB
      │
      ▼
 gform_after_update_entry ◄─ update webhook here
      │  params: $form, $entry_id, $original_entry
      ▼
 Downstream system receives update payload
FIG 01 — Gravity Forms entry lifecycle and webhook hooks

/ Submission vs update

How does gform_after_update_entry differ from gform_after_submission?

gform_after_submission fires once, when a visitor submits the form and a new entry row is created. gform_after_update_entry fires every time an existing entry is subsequently modified — which means it can fire many times for the same entry ID over its lifetime.

The distinction matters for downstream integrations. A CRM contact created from gform_after_submission might need to be updated when an entry is later edited: the order status changes, a support agent adds a note, or an admin corrects a typo in the email field. Those updates arrive via gform_after_update_entry. Without a webhook on this hook, your CRM retains the original submission data even when the Gravity Forms entry has changed.

A third hook, gform_post_update_entry, is an alias used by GFAPI internals — prefer gform_after_update_entry for external integrations, as it is the documented public hook.

/ Parameters

What parameters does gform_after_update_entry pass?

The hook passes three arguments to your callback. Register with add_action( 'gform_after_update_entry', $callback, 10, 3 ) to receive all three:

  • $form — the full Gravity Forms form array, including field definitions, confirmations, notifications, and settings. Use $form['id'] for the form ID and $form['fields'] to iterate over field metadata.
  • $entry_id — the integer ID of the entry that was just updated. The entry itself is not passed directly; retrieve it with GFAPI::get_entry($entry_id).
  • $original_entry — the entry array as it existed before the update, available since Gravity Forms 2.4. Use this to build diff payloads or to skip the webhook when only irrelevant fields changed.

PHP — hook registration with all three parameters

add_action( 'gform_after_update_entry', function( $form, $entry_id, $original_entry ) {
    // $form          — full form array
    // $entry_id      — integer entry ID
    // $original_entry — entry values before the update
}, 10, 3 ); // ← priority, accepted_args — must pass 3

/ Reading updated values

How do you read the original and updated entry values?

The hook gives you the pre-update state via $original_entry. To read the post-update state, call GFAPI::get_entry($entry_id). Field values are keyed by field ID as a string — $entry['1'] for field ID 1, $entry['2'] for field ID 2. Use $form['fields'] to find field IDs and labels.

PHP — reading original vs updated entry values

add_action( 'gform_after_update_entry', function( $form, $entry_id, $original_entry ) {
    // Retrieve the current (updated) entry
    $updated_entry = GFAPI::get_entry( $entry_id );

    if ( is_wp_error( $updated_entry ) ) {
        return;
    }

    // Compare a specific field (field ID 3 = status in this example)
    $old_status = $original_entry['3'] ?? '';
    $new_status = $updated_entry['3'] ?? '';

    // Skip webhook if the status field did not change
    if ( $old_status === $new_status ) {
        return;
    }

    $payload = [
        'form_id'    => $form['id'],
        'entry_id'   => $entry_id,
        'old_status' => $old_status,
        'new_status' => $new_status,
        'entry'      => $updated_entry,
    ];

    wp_remote_post( 'https://your-endpoint.com/webhook', [
        'headers'     => [ 'Content-Type' => 'application/json' ],
        'body'        => wp_json_encode( $payload ),
        'timeout'     => 5,
        'data_format' => 'body',
    ] );
}, 10, 3 );

/ Use cases

What are the common use cases for entry-update webhooks?

Entry-update webhooks enable a class of integrations that new-submission webhooks cannot cover on their own. The most frequent patterns in production:

  • CRM status sync. A sales team updates the entry status field (e.g. "Qualified" → "Closed") in wp-admin. The update webhook fires and pushes the new deal stage to HubSpot, Salesforce, or Pipedrive without the team needing access to the CRM directly.
  • Order or ticket lifecycle tracking. Service businesses use Gravity Forms as a lightweight order management tool. Status changes to "In Progress", "Awaiting Parts", or "Completed" trigger webhooks that update job boards or send notifications to n8n workflows.
  • Data correction propagation. When an admin corrects a typo — wrong email, misspelled name, incorrect address — the update webhook propagates the fix to downstream systems without a manual re-sync.
  • Add-on triggered updates. Gravity Forms add-ons (User Registration, Stripe, GravityView) can update entry values programmatically via GFAPI. gform_after_update_entry fires on these programmatic updates too, enabling event-driven automation even for machine-generated changes.

/ Webhook Actions

How does Webhook Actions handle update-triggered delivery?

The Webhook Actions plugin listens for Gravity Forms entry updates as a native trigger. Select "Gravity Forms — Entry Updated" from the trigger picker, choose the form, and configure the webhook endpoint — no PHP required. The plugin dispatches deliveries asynchronously: the update response in wp-admin returns immediately while delivery happens in a background queue cycle.

Delivery logs track every attempt: HTTP status code, response body, timestamp, and retry count. Failed deliveries retry automatically with exponential backoff (1 min → 2 min → 4 min → 8 min, capped at 1 hour, default 5 attempts). You can replay any failed delivery from the Logs screen.

Entry-update webhooks close the sync gap that new-submission webhooks leave open — they're the difference between a CRM snapshot and a CRM mirror.
CapabilityRaw gform_after_update_entry + wp_remote_postWebhook Actions
SetupCustom PHP — hook registration, payload constructionAdmin UI trigger picker — no code
DeliverySynchronous — blocks admin save responseAsync queue — admin save returns immediately
RetryNoneExponential backoff, up to 5 attempts
LogsNone — failures are invisiblePer-attempt log with HTTP status and response body
ReplayNot possible without custom toolingOne-click replay from the Logs screen
DeduplicationManual — requires field-diff logic in PHPQueue deduplication handled by the plugin

/ Deduplication

How do you prevent duplicate webhooks on rapid successive updates?

Rapid successive updates are a real pattern: an automated workflow may update the same entry four times in a loop, or two admin users may save the same entry within seconds of each other. Without deduplication, your downstream system receives multiple payloads for a single logical change.

The field-diff approach shown in the code example above — comparing $original_entry['3'] to $updated_entry['3'] and returning early if unchanged — is the most common manual solution. Only send the webhook when a field that matters to your integration actually changed. For updates that involve multiple fields, compare a hash of the relevant subset: md5(serialize(array_intersect_key($updated_entry, $watched_fields))) against the same hash from $original_entry.

At the delivery level, include the entry ID and a hash of the payload in a transient with a short TTL (30–60 seconds). If an identical delivery arrives within the TTL, skip it. This catches duplicate hook invocations that would produce identical payloads even with field diffing. The gform_after_submission webhook guide covers additional Gravity Forms webhook patterns that complement the update flow.

/Footnotes
² GFAPI referenceget_entry, update_entry, and all public API methods.
³ Action Scheduler — persistent background job queue used by Webhook Actions for async delivery.
FAQ

Common questions always ask.

Don't see yours? Open an issue on GitHub or check the full reference in the API docs.

What is the difference between gform_after_update_entry and gform_after_submission? +
gform_after_submission fires when a new Gravity Forms entry is created via a form submit. gform_after_update_entry fires when an existing entry is updated — from the wp-admin entry editor or via GFAPI::update_entry(). Use gform_after_update_entry to sync CRM records when entry data is corrected after the original submission.
What parameters does gform_after_update_entry pass? +
Three parameters: $form (the full form array), $entry_id (integer ID of the updated entry), and $original_entry (the entry array as it was before the update, available since Gravity Forms 2.4). To get the current entry after the update, call GFAPI::get_entry($entry_id).
How do you access the updated field values inside gform_after_update_entry? +
Call GFAPI::get_entry($entry_id) to retrieve the current entry. Field values are keyed by field ID as a string (e.g. $entry["1"] for field ID 1). Use $form["fields"] to find field IDs. The $original_entry parameter gives you the pre-update state for building a diff payload.
Can gform_after_update_entry fire multiple times on rapid updates? +
Yes. If a workflow updates the same entry programmatically in a loop, or if two users edit the same entry in quick succession, the hook can fire multiple times within seconds. To prevent duplicate webhooks, compare key fields between $original_entry and GFAPI::get_entry($entry_id), or use a plugin that handles deduplication at the queue level.
Does Webhook Actions trigger on Gravity Forms entry updates? +
Yes. Webhook Actions listens for Gravity Forms entry updates as a native trigger type. When an entry changes, a delivery is queued with the current field values and entry metadata. Configure the trigger in the plugin admin and select the form — no custom PHP required.
Ready

Stop losing webhooks.
Start logging them.

$ wp plugin install flowsystems-webhook-actions --activate