How to Route Website Form Leads Automatically in GoHighLevel


A contact form is not a lead system. It is a notification. Someone fills it in, an email lands in a shared inbox, and whoever opens that inbox first decides what happens next. That is the setup in most of the businesses we audit, and it is why leads sit overnight.
The research on this is old and worth reading anyway. When Oldroyd, McElheran and Elkington audited 2,241 US companies for Harvard Business Review in 2011, average first response time was 42 hours, only 37 percent replied within an hour, and 23 percent never replied at all. The often quoted 21x qualification advantage for a five minute response comes from an earlier 2007 MIT and InsideSales dataset, so treat that number as directional rather than a law. The direction has never been in dispute.
One of our clients, a fitness coach, was handling intake by hand. Inquiries arrived, someone saw them eventually, and often that was after the person had already moved on and booked elsewhere. We rebuilt the form inside GoHighLevel, wired an internal notification to the person who should actually be answering, and set an automated first reply to fire the moment someone submitted. Their client acquisition went up after that. We cannot publish the numbers, since most of our agreements do not allow it, but what they noticed first was not a metric at all. It was that inquiries stopped disappearing.
Here is the build. It runs in GoHighLevel, but the logic transfers to any CRM with conditional workflows. Before you build, it is worth asking whether GoHighLevel is worth the switch in the first place. We use this same pattern to connect your tools and cut repetitive work across every client we take on.
By the end, a submission on your site will do all of this without anyone touching it:
Setup time is about 45 minutes for the first service, then roughly 10 minutes per additional branch.
A GoHighLevel sub-account with Automation access. Build in a test sub-account first, then rebuild or clone into the live account once every branch is verified.
Owners who exist as users in that sub-account. Assigning to a person who is not a user fails quietly.
If your form lives outside GHL, on Elementor, Gravity Forms, Webflow or a custom build, you will need the Inbound Webhook trigger. It is a premium trigger, so confirm premium actions and triggers are enabled on the sub-account before you plan the build around it.
A decision about who owns what. People skip this and then try to make the builder produce the decision for them. It will not.

Open a sheet. Four columns, one row per path a lead can take. This takes ten minutes and it removes most of the rework later.
| Service selected | Routing tag | Owner | First reply angle |
|---|---|---|---|
| SEO | route-seo | Owner A | Ask for the domain and current traffic source |
| CRM or automation | route-crm | Owner B | Ask which tools they are trying to connect |
| Website build | route-web | Owner A | Ask for the current site and the deadline |
| Not sure | route-triage | Default owner | Send the calendar link, no qualifying question |
One rule that saves pain: a tag used for routing should never double as a campaign tag or a reporting tag. Prefix them, route-seo, route-crm, route-web. When routing tags and campaign tags share a namespace, a contact ends up in three workflows and nobody can work out which one sent the message.
The workflow needs something to branch on, and it needs to be a field, not a sentence buried in a message box. Two options that both work:
A required dropdown asking what they need help with, where the values match your routing table character for character. Copy and paste them across, do not retype. A trailing space in a condition is a real thing and it is miserable to debug.
Or a hidden field set per page, so the form on your SEO service page submits service equals seo without asking anyone anything. This converts better because it removes a question, and it is more accurate because visitors are bad at self categorising.
Map the field to a proper custom field in the CRM. A value sitting inside a free text message cannot be branched on cleanly.
Use the Form Submitted trigger. It fires on GHL hosted and embedded forms. Add a trigger filter for the specific form so unrelated submissions do not enrol, and set your re-entry rule on purpose rather than leaving the default.
Use the Inbound Webhook trigger. GoHighLevel generates a unique URL for that trigger and accepts POST, GET or PUT requests, so your form or middleware can post JSON to it. See the Inbound Webhook trigger documentation and the premium trigger guide for details.
POST https://services.leadconnectorhq.com/hooks/YOUR_HOOK_ID/webhook-trigger
{
"first_name": "Ana",
"email": "ana@example.com",
"phone": "+639171234567",
"service": "seo"
}Send one real test submission before you try to map anything. The mapping panel reads from requests it has actually received, so you need a request in the log to map against. One constraint to plan around: the Create or Update Contact action needs an email or a phone in the payload. Without one, the workflow still runs, but it runs contactless and there is no record to tag.

Order matters here. Three actions, in this sequence:
Inside If/Else, each branch is a condition group and you add more with Add Branch. GoHighLevel creates a None branch automatically. It runs when nothing else matches, it cannot be deleted, and that is a feature rather than clutter. It is the branch that catches the day someone edits the website dropdown and renames a value. See the If/Else action documentation for branch and None branch behavior.
Branch on the custom field rather than on the tag you just applied. The tag is for segmentation and reporting later. Branching on the field you already captured is one less dependency in the chain. This is also why we insist on a CRM that stays clean: routing logic built on a messy custom field set is a debugging nightmare.
Inside each branch: Assign to User first, then the internal notification. That order matters because the alert can then reference the assigned owner, and because an unassigned contact is an orphaned contact even when the notification lands.
If two people share a service, round robin distribution works. Use it only when both people genuinely cover that service. Round robin across mismatched skills does not remove the delay, it just moves it from the queue to the handoff.
Each branch gets its own first message referencing the specific service. Thanks for reaching out about SEO for your clinic performs better than Thanks for your inquiry, because the second one reads like it was sent by a machine that did not read the form.
Add a wait of 30 to 60 seconds before it sends. A reply that arrives in the same second as the form submission announces itself as automated, and reply rates drop.
Give the message one job. One question, or one calendar link. Not both, and definitely not a newsletter signup.
Five failure points, in the order we hit them most often.

Submit five test entries: one per service, plus one with the routing field left blank or filled with junk. For each, check five things.
Then open the workflow execution log for each test. The log is the source of truth. Receiving the email only proves the message step ran, not that the routing was correct.
Two extensions worth adding once this is stable. First, a reassignment step: if the owner has not logged an action within a set window, reassign and alert a manager. Speed to first reply is solved by automation, speed to first human contact is not. Second, a dashboard tracking time to first human touch, split by owner. That number is usually worse than everyone assumes, and it is the one that predicts close rate.
If you are connecting more than one lead source, the same If/Else pattern handles Facebook lead ads, Google Ads lead form extensions and phone inquiries. The routing table gets longer, the logic does not change. Once routing is working, the next layer is deciding which system owns which field so the sync does not overwrite your attribution data. This is the foundation of most lead generation systems we build.
Yes. Use the Inbound Webhook trigger instead of Form Submitted. It generates a unique URL that accepts POST, GET or PUT requests, so an Elementor, Gravity Forms or custom form can post JSON to it. Include an email or phone in the payload, otherwise the Create or Update Contact action has nothing to match on.
Branch on the custom field the form submitted. The tag is for segmentation and reporting later. Branching on the field you captured directly removes one dependency, because you are not relying on a tag being written before the condition is evaluated.
The contact falls into the None branch, which GoHighLevel creates automatically and which cannot be removed. Put a default owner and a generic first reply there. Without it, a renamed dropdown value on the website silently sends leads nowhere.
Under two minutes is a reasonable target, with a short delay of 30 to 60 seconds before it sends. An instant reply reads as automated and gets fewer responses. The point is not the speed record, it is that the lead gets a relevant reply before they contact someone else.
No. One workflow with If/Else branches is easier to maintain than four near identical workflows. Separate workflows are worth it only when the follow up sequences diverge heavily after the first few days, for example when one service has a long nurture and another books immediately.
If you have built this and it broke somewhere we did not mention, we want to hear where. Our version broke at the handoff every time, until we stopped treating the internal notification as the end of the automation and started treating it as the start of a timer.
If your CRM, forms and follow up are supposed to be one system and they keep breaking at the seams, book a strategy call. We will map what you have now and where it is leaking.
Want to try GoHighLevel for yourself? You can get started with GoHighLevel here.

Written by
Benison David Sanchez is the CEO and AI Digital Marketing Strategist of BDGS Digital, a technology, CRM, automation and growth company based in the Philippines and serving clients globally. He leads digital marketing and client acquisition for the company, and over five years has worked with more than 100 businesses across ecommerce, service, coaching, accounting and technology, building connected growth systems where every campaign ties back to a larger system rather than running in isolation. He writes up these builds as they happen, including the parts that break.
View all articles by BenisonWant help building this?
BDGS Digital builds connected growth systems across CRM, automation, marketing, and technology. Explore our services or book a strategy call.
Book a Strategy CallLET'S TALK
Book a strategy call and we'll map how your CRM, automation, marketing, and technology can work together as one connected system.