Which n8n GoHighLevel Integration Fits? Three Ways Compared
The three ways to build an n8n GoHighLevel integration (workflow webhook, private token, marketplace app), which to pick when, setup steps and traps from real builds.
By Carlos Familia, CRM & AI automation expert. Updated . 12 min.
A test message for an online English academy's DM filter ran through n8n twice. I had built a small marketplace app that pushes every incoming DM to n8n, where a local AI model sorts it into one of eight groups and then switches the GoHighLevel bot on or off for that contact. An older workflow in the same account, "message received, send to n8n", was still active. GoHighLevel fired both for the same message. Two connections, one event, two runs.
Can you connect GoHighLevel to n8n? Yes, in three main ways. A webhook step inside a GoHighLevel workflow sends events to n8n. A private integration token lets n8n read and write GoHighLevel. A marketplace app's webhooks send account events that no workflow sees, like a new DM. Two variations sit beside them: n8n's own HighLevel node, which uses an OAuth app instead of a token, and the Inbound Webhook trigger, which lets n8n start a GoHighLevel workflow.
Pick by two questions: which side knows about the event first, and does the event happen inside a workflow? Then give each event exactly one door. That is the lesson the academy build taught me.
Which connections exist, and what does each one cost?
| Connection | Direction | What it carries | Cost driver | Setup effort | What breaks |
|---|---|---|---|---|---|
| Webhook action in a workflow | GoHighLevel to n8n | The contact, location details and your custom keys | HighLevel's article on this action mentions no fee | Minutes | Custom keys arrive nested; the log hides the payload |
| Custom Webhook action | GoHighLevel to n8n | Any method, auth header and raw body | Premium: $0.01 per execution after 100 free | Minutes | Skipped with no alert when the wallet is empty |
| Inbound Webhook trigger | n8n to GoHighLevel | A JSON body that starts a workflow | Premium, same rate | Minutes | Keys with spaces, no email or phone, old mapping |
| Private integration token | n8n to GoHighLevel | Whatever the token's scopes allow | API rate limits | About an hour | Missing scopes, 429 errors, rotation |
| n8n HighLevel node | n8n to GoHighLevel | Contacts, opportunities, tasks, free slots, bookings | Same rate limits | An hour plus an OAuth app | Operations the node lacks |
| Marketplace app webhooks | GoHighLevel to n8n | Account events like a new DM, with no workflow involved | Your build time | Half a day or more | A draft app sends nothing |
The premium rate and the 100 free lifetime executions per sub-account come from HighLevel's premium features article (updated September 28, 2026), which lists Custom Webhooks and Inbound Webhooks as premium. The setup times are my estimates for someone who has done it before.

If a GoHighLevel workflow already sees the event, then send it with a webhook step
This is the right door when a workflow trigger already catches the moment: a form submitted, a stage changed, an appointment booked, a tag added. A mortgage brokerage in Florida uses this door to hand texts to an n8n router that picks the sending provider for each message.
- In n8n, add a Webhook node, set it to POST and copy the production URL. n8n registers that URL only when you publish the workflow; the test URL works only while the editor is listening, per n8n's Webhook node docs.
- Set the node to respond immediately when GoHighLevel needs nothing back.
- In the GoHighLevel workflow, add the Webhook action, paste the URL and add custom data as key and value pairs. HighLevel's Webhook action article (updated March 16, 2026) says each call carries the contact's standard and custom fields and the location details. Appointment or opportunity data comes along only when the trigger is about those objects. Files and images cannot be sent.
- If you need an auth header, a PUT or a raw JSON body, use the Custom Webhook action instead. It supports bearer tokens, API keys, basic auth and OAuth2, per HighLevel's Custom Webhook article (updated December 11, 2025). It is the premium one.
- Publish both sides and push one test contact through.
Two things catch people here. Your custom keys arrive in n8n nested under customData inside the request body, not at the top level. And GoHighLevel's execution log tells you whether the step ran, not what it sent, so read the payload in n8n's Executions tab.
The billing trap is quieter. On one account a premium step was skipped because the agency wallet had no funds. The log said skipped, and the reason sat deep in the step's details. If a webhook step shows skipped, open the step before you debug n8n.
If n8n has to read or change GoHighLevel records, then use a private integration token
Most of my n8n jobs go this way: a nightly call digest for a real estate wholesaler, a daily call queue for the Florida brokerage, booking tools for chat bots. n8n calls HighLevel's API with a private integration token.
- In GoHighLevel settings, open Private Integrations and create one. HighLevel's private integrations docs say to select only the scopes you need and to copy the token immediately, because you cannot see it again.
- In n8n, save it as a Header Auth credential (Authorization, then "Bearer" and the token) and call the API from an HTTP Request node. Send a Version header too, as the docs' examples do.
- Throttle. HighLevel allows a burst of 100 requests per 10 seconds and 200,000 a day, counted per app per location or company, according to its API FAQ.
- Put rotation on the calendar. "Rotate and expire this token later" keeps the old and new tokens working for 7 days, and HighLevel recommends rotating every 90 days.
What happened when I did it:
- The call queue lost writes to rate limits. It scans open opportunities every morning, 1,054 of them on one run. On its first live run, 429 errors silently dropped 28 contact reads and 16 tag writes. Retries with backoff and four requests at a time fixed it: 118 of 118 reads, 43 of 43 tags, and the run went from 152 seconds to 29. The run now reports its failure counts, and I don't trust a run where they aren't zero.
- One scope was missing. Showing each lead's owner by name meant reading the user list, which needs the users scope, and the main token didn't have it. A second token with that scope is used for that single call.
- The digest timed out. It wrote nothing on a 32-contact night because n8n's Code node limit of 300 seconds covers the whole node. Splitting the contacts into batches fixed it: 32 contacts in 354 seconds.
What about n8n's HighLevel node?
It works with an OAuth app instead of a token. n8n's credential docs walk through it: in HighLevel's marketplace go to My Apps, Create App, set the distribution type to Sub-Account, add the scopes, paste n8n's OAuth redirect URL, then copy the client ID and secret into n8n. The old API key method is deprecated. The HighLevel node covers contacts, opportunities, tasks, free slots and booking an appointment. For anything else, n8n points you to the HTTP Request node with the same credential.
For one account, I use a private token. For a tool that many sub-accounts will install, an OAuth app is the right shape.
If the event happens outside any workflow, then use a marketplace app webhook
A new DM, an app install, a contact edited from someone's phone: these never pass through a workflow you control. A marketplace app can subscribe to them and post each one to n8n. That is how the academy's DM filter receives every message.
These steps follow HighLevel's webhook integration guide:
- Create the app in HighLevel's developer portal and fill in the required fields.
- Add scopes in the Auth section. The guide says scopes can only change while the app is a draft.
- In the webhook section, switch on each event and paste the n8n production URL.
- Create the client keys yourself. In my builds, an app with no client key could not be installed at all, not even through a test link.
- Publish a version and install the app on the sub-account. A draft app fired nothing for me.
- Verify the signature. The guide names X-GHL-Signature as the current header and set the legacy X-WH-Signature to be deprecated on September 1, 2026.
- Answer fast and drop repeats. Any non-2xx answer or timeout triggers retries, up to 12, so the guide says to store each webhookId, skip ones you have seen and return 200 before doing heavy work.
For the academy, the fix for the double run was in the payload. Events sent by the old workflow carried workflow details that the app's events didn't, so n8n skips anything with them, and the old workflow went off. I also learned that the app's message events had a cleaner, steadier shape than what the workflow sent.

Marketplace apps can also add custom actions to the workflow builder. For the brokerage I built one with two branches. The catch: a custom action has its own publish cycle, and a change to its module only reached installed accounts after I released it as a major version.
If n8n needs to start a GoHighLevel workflow, then use the Inbound Webhook trigger
HighLevel's Inbound Webhook article (updated September 16, 2026) gives the setup:
- Add the trigger to a workflow and copy its URL.
- From n8n, send a test request with POST, GET or PUT.
- Click Test Trigger, pick that request as the mapping reference and save.
- Map the fields in the Create/Update Contact step. Email or phone is required for contact actions.
Send a JSON object with keys that have no spaces. When your payload changes shape, pick a new mapping reference or later steps read stale fields. If the URL leaks, delete the trigger and add a new one; the old URL stops working.
A free alternative: have n8n add a tag through the API and let a normal tag trigger start the workflow. Remember that a tag trigger fires only when the tag is new. Re-adding a tag the contact already has does nothing, so remove it first.
What broke in my builds?
Some of these I covered in my letter on GoHighLevel n8n work. The ones that belong in a how-to:
- Two doors for one event. The academy's double run. One door per event, and dedupe by message ID anyway.
- A step changed type and kept a hidden flag. At the brokerage, GoHighLevel skipped converted steps, and leads who arrived in office hours got no welcome for about two days. After changing a step's type, read a real run's log.
- n8n could not reach the local model. n8n runs in Docker on my server, and 127.0.0.1 points at the container, not the host. The host answered at 172.17.0.1.
- A step was computed and never sent. The classifier worked out which tags to remove, but no HTTP call removed them. I found it by checking the contact, not the n8n run.
- Quotes broke the body. A DM with quotation marks broke a JSON body built from text. Build bodies in a Code node with JSON.stringify.
- Speed. The local model took about 22 seconds on a cold start and about 7 seconds warm, which is fine for tagging and too slow for a live reply. Bots that do reply need more guards, which I list in n8n AI agent lessons from production.
For the n8n side of those failures, see n8n workflow not working. If you host n8n yourself, my n8n self hosted setup checklist covers the server.
How do you test the connection before you trust it?
- Use a test contact you own, tagged as a test. Never a client's lead.
- Run one full round trip: the event in GoHighLevel, the run in n8n, the write back, and the change visible on the contact.
- Read both logs. In GoHighLevel, executed or skipped, and open any skipped step. In n8n, the Executions tab, because production runs don't show in the editor.
- Send the same event twice and confirm n8n acted once.
- Break it on purpose. Unpublish the n8n workflow or use a wrong token, and check that a person hears about it. An error workflow that isn't published never runs.
- After the first real batch, check the failure counts are zero.
I go through the GoHighLevel half in more depth in how I test GoHighLevel workflows.
Should you build it yourself?
A Webhook step to n8n and a token for writing back is a fair weekend project if you can read JSON. Hand off the marketplace app (keys, publishing, signatures, retries), bulk writes under rate limits, and any bot that replies to customers, because a double reply lands on a real person. My n8n developer hiring guide lists what to ask. If your stack already runs on Zaps, read the GoHighLevel Zapier integration failures first, and if a phone system is involved, the RingCentral GoHighLevel integration diary shows this pattern end to end.
Which branch are you on?
| Your situation | Connection | Check first |
|---|---|---|
| A workflow trigger already sees the event | Webhook action, or Custom Webhook if you need auth | Keys under customData, wallet balance |
| n8n reads or writes contacts, opportunities or notes | Private integration token and HTTP Request | Scopes, 429 handling, rotation date |
| You want n8n's built-in node | OAuth app and the HighLevel node | The node has the operation you need |
| The event happens outside workflows | Marketplace app webhook | Published, installed, signature, webhookId |
| n8n must start a GoHighLevel workflow | Inbound Webhook trigger, or a tag | JSON keys, email or phone, mapping reference |
Want me to build the connection for you?
Connecting GoHighLevel to n8n is a big part of my work, from a single webhook step to a published marketplace app with signature checks and retries. Tell me on a call which event should move and what should happen on the other side, and I'll pick the connection and build it in your accounts. The booking calendar sits right below this post.
About the author

Carlos Familia, CRM & AI automation expert. GoHighLevel, n8n, AI agents, servers. Full-stack developer.
I build CRM systems in GoHighLevel, n8n automations on my own servers and AI voice and chat agents for service businesses. Full-stack developer: I write the workflow, the API integration, the database and the server it runs on, and I test every build with real journeys before handoff.
Book a call with Carlos
In 30 minutes we look at how you get customers today and what to automate first. Pick a time ยท contact@bluemiraisystems.com