Home›Blog›SEO & Growth
SEO & Growth

Send WordPress Form Submissions to GoHighLevel With an Inbound Webhook (PHP Snippet)

Keep your WordPress forms and send every submission into a GoHighLevel workflow with an inbound webhook and a short, tested PHP snippet.
Saleem Akhter
Oct 30, 2026
6 min read

Many businesses run their website on WordPress and their follow-up in GoHighLevel. The weak point is usually the gap between the two: form submissions land in an inbox, someone copies them into the CRM, and the fast follow-up GoHighLevel is good at starts hours late.

This guide shows how to send a WordPress form to GoHighLevel the moment it is submitted, using GoHighLevel’s Inbound Webhook trigger and a short PHP snippet. It also covers the no-code option for Elementor Pro forms, how to map the fields, and how to test it properly.

How it works

  1. A visitor submits a form on your WordPress site.
  2. WordPress sends the submitted fields as JSON to a unique GoHighLevel webhook URL.
  3. The Inbound Webhook trigger starts a workflow, which creates or updates the contact and runs your follow-up.

The website stays exactly as it is. Only the destination of the data changes.

Step 1: create the Inbound Webhook trigger

  1. In the sub-account, create a new workflow and choose the Inbound Webhook trigger.
  2. Copy the unique webhook URL it shows. Treat it as private: anyone with the URL can send data into the workflow.
  3. Leave the trigger open — you will send a test request in a moment so GoHighLevel can see the fields.
Plan check: inbound webhooks are part of HighLevel’s premium workflow features in many accounts, which can carry a small usage charge. Check what your plan includes before you build on it.

Step 2 (Elementor Pro): no code needed

If your forms are built with Elementor Pro, you do not need any code. Edit the form, add Webhook under Actions After Submit, paste the GoHighLevel URL into the Webhook section and save. Elementor sends the field values with each submission. Give every field a clear ID (for example email, phone, message) so it is easy to map later.

Step 2 (Contact Form 7): add a PHP snippet

Contact Form 7 does not send webhooks on its own, but it fires an action after every successful submission that we can hook into. Add this to a small custom plugin or your child theme’s functions.php. Store the webhook URL in wp-config.php, not in the code.

// wp-config.php
define( 'GHL_WEBHOOK_URL', 'https://services.leadconnectorhq.com/hooks/your-unique-webhook-url' );

// functions.php (child theme) or a small plugin
add_action( 'wpcf7_mail_sent', function ( $contact_form ) {
	if ( ! defined( 'GHL_WEBHOOK_URL' ) ) {
		return;
	}
	$submission = WPCF7_Submission::get_instance();
	if ( ! $submission ) {
		return;
	}
	$data = $submission->get_posted_data();

	// Map your form's field names to clear keys for GoHighLevel.
	$payload = array(
		'first_name' => sanitize_text_field( $data['your-name'] ?? '' ),
		'email'      => sanitize_email( $data['your-email'] ?? '' ),
		'phone'      => sanitize_text_field( $data['your-phone'] ?? '' ),
		'message'    => sanitize_textarea_field( $data['your-message'] ?? '' ),
		'form_name'  => $contact_form->title(),
		'page_url'   => esc_url_raw( $submission->get_meta( 'url' ) ),
	);

	$response = wp_remote_post( GHL_WEBHOOK_URL, array(
		'timeout'  => 10,
		'headers'  => array( 'Content-Type' => 'application/json' ),
		'body'     => wp_json_encode( $payload ),
	) );

	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) >= 300 ) {
		error_log( 'GHL webhook failed for form "' . $contact_form->title() . '": ' . print_r( $response, true ) );
	}
} );

Change the keys inside $data[...] to match the field names in your form — your-name, your-email and so on are Contact Form 7’s defaults. The snippet only runs after the email notification succeeds, so it follows the same validation as the form itself.

A generic version for any form or custom code

If you have your own form handler, the same idea fits in a reusable function you can call from anywhere:

function gnx_send_to_ghl( array $fields ) {
	if ( ! defined( 'GHL_WEBHOOK_URL' ) || empty( $fields['email'] ) && empty( $fields['phone'] ) ) {
		return false; // need at least one way to identify the contact
	}
	$response = wp_remote_post( GHL_WEBHOOK_URL, array(
		'timeout' => 10,
		'headers' => array( 'Content-Type' => 'application/json' ),
		'body'    => wp_json_encode( $fields ),
	) );
	return ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) < 300;
}

// Example: inside your own form handler, after validation
gnx_send_to_ghl( array(
	'first_name' => 'Sam',
	'email'      => 'sam@example.com',
	'source'     => 'pricing-page',
) );

Step 3: send a test and map the fields

  1. Submit the form on your site with test details.
  2. Back in the workflow, the Inbound Webhook trigger should show the received fields. Select the test request so GoHighLevel knows the structure.
  3. Add a Create/Update Contact action and map email, phone and first_name to the contact fields. Map anything else — the message, the page URL, the form name — to custom fields or a note.
  4. Add your follow-up: a tag, a pipeline opportunity, an internal notification and the first message to the lead.
  5. Publish the workflow, then submit the form again and confirm the contact appears with every field filled in.

Troubleshooting

SymptomLikely causeFix
Nothing arrives in GoHighLevelThe snippet is not running, or the URL is wrongCheck the PHP error log and confirm the constant is defined
Contact created with empty fieldsField names in the snippet do not match the formCompare the keys with the form’s field names
Duplicate contactsCreate Contact used instead of Create/UpdateUse the Create/Update action, matching on email or phone
Workflow runs but no messages sendMissing SMS consent or A2P registrationSee our SMS compliance guide
Works in testing, fails laterThe workflow was unpublished or the trigger changedMonitor key workflows — see our monitoring guide

Good practice

  • Send only what you need. Do not forward passwords, card details or sensitive personal data to a webhook.
  • Collect consent on the form. If the workflow will text the lead, the form needs clear SMS consent wording.
  • Keep a copy. Leave the form’s normal email notification switched on as a backup while you test.
  • Rotate the URL if it leaks. Delete the trigger and create a new one; the old URL stops working.

Prefer to replace the WordPress forms altogether? Our GoHighLevel and WordPress guide compares embedding GoHighLevel forms with keeping your own. For two-way integrations, see the GoHighLevel API guide.

Frequently asked questions

Will this slow down my form?

The request takes a moment after submission. The 10-second timeout stops a slow response from holding the page up for long; for very busy sites, the request can be moved to a background job.

Can I send to different workflows from different forms?

Yes. Create one inbound webhook per workflow and choose the URL based on the form’s ID or title.

Is the webhook URL secret?

Treat it that way. Keep it in wp-config.php, and replace it if it is ever exposed.

Does this work with Gravity Forms or WPForms?

Yes. Both offer webhook add-ons, or you can call the generic function above from their after-submission hooks.

Ready to Implement This?

Let GHL Nexa set this up for you. Book a free 30-minute strategy call today.

SHARE THIS ARTICLE