GoHighLevel webhooks move data in and out of a HighLevel workflow over HTTP. An inbound webhook is a workflow trigger that gives you a unique URL: any outside system can post data to it and start the workflow. An outbound webhook is a workflow action that sends contact and event data from HighLevel to another URL, such as a Make scenario, an n8n workflow or your own server. The Custom Webhook action is the more configurable outbound version, with your choice of method, headers, auth and body.
Webhooks are the glue in almost every serious HighLevel build I do for agencies. This guide covers which webhook to use when, how to set each one up, how to test it, and the mistakes that cause silent failures.
The three kinds of GoHighLevel webhooks
Inbound webhook (trigger)
The inbound webhook trigger starts a workflow when HighLevel receives a request at its URL. You use it when data originates outside HighLevel: a form on a site HighLevel does not host, a lead from a marketplace, an event from your billing system, or a signal from a Make or n8n scenario.
HighLevel treats the inbound webhook as a premium trigger. Premium triggers and actions can carry usage-based charges per execution, so check your agency settings and current pricing before you route high volume through it.
Outbound webhook (action)
The basic Webhook action sends a request to a URL you enter when a contact reaches that step. It is the quickest way to hand a contact to an external tool. Most agencies first meet it when connecting HighLevel to Zapier or Make.
Custom Webhook (action)
The Custom Webhook action is the configurable outbound option. According to HighLevel's help article on the Custom Webhook action, you can choose the HTTP method (GET, POST, PUT or DELETE), add headers and query parameters, pick an auth method and send a JSON or form body. This is the one to use when the receiving system expects a specific format, like an API that needs a bearer token and a particular JSON shape.
When to use which webhook
A simple rule I use:
- Data coming in from outside: inbound webhook trigger.
- Data going out to a no-code tool like Make or n8n: the basic Webhook action is usually enough, since those tools accept whatever arrives and let you map it.
- Data going out to a real API: Custom Webhook, so you control method, auth and body.
- Data you need to fetch back: a webhook action cannot easily use the response inside HighLevel. If you need to call an API and then act on its answer, send the work to Make or n8n and let it write back to HighLevel through the API.
How to set up a GoHighLevel inbound webhook
- Create a new workflow and choose the Inbound Webhook trigger.
- Copy the webhook URL HighLevel generates.
- Send a sample request from the source system. If the source cannot send a test, use any HTTP client to post a JSON body with realistic fields: first name, last name, email, phone, source and any custom fields.
- Back in the trigger, fetch the sample so HighLevel can see the field names.
- Add a Create or Update Contact action and map the incoming fields to contact fields. Map email and phone so HighLevel can match existing contacts instead of creating duplicates.
- Add the rest of your steps: tags, opportunity creation, notifications, follow-up messages.
- Publish the workflow and send a second real request to confirm it runs end to end.
A tip: always include a source field in the payload, even if it is a fixed string like "partner-site". Six months later, someone will ask where those contacts came from.
How to set up a GoHighLevel outbound webhook
- In the workflow, add the Webhook or Custom Webhook action at the point where the data should leave.
- Paste the receiving URL. For Make, that is the address from a Custom Webhook module. For n8n, the Production URL from a Webhook node.
- For Custom Webhook, set the method, headers and body. Use custom values or contact fields for dynamic data.
- If the receiver needs auth, set it in the action rather than putting a secret in the URL.
- Run the workflow on a test contact and check that the receiver got the request with every field you expected.
On the receiving side in Make, the first request is what Make uses to learn the data structure. Send a test with every field populated, not a half-empty contact, or you will be missing fields in the mapping panel. My Make.com webhooks guide goes deeper on that side.
Example: HighLevel to Slack and ClickUp via Make
Here is a pattern I build often. When an opportunity moves to Won in HighLevel:
- The workflow trigger is the pipeline stage change to Won.
- A Custom Webhook action posts the contact name, opportunity value, owner and pipeline to a Make webhook.
- Make posts a formatted message to the team Slack channel.
- Make creates a ClickUp task for onboarding with the client details.
- Make adds a row to a Google Sheet that tracks new clients.
This is close to the positive-reply sales alert I run in production: a webhook fires, the team is pinged in Slack, the lead is logged to a sheet and ClickUp is updated. Same shape, different trigger.
GoHighLevel custom webhook payload tips
- Send IDs, not just names. Include the contact ID and opportunity ID so the receiver can call the HighLevel API later to fetch or update the record.
- Keep a stable shape. If a field is sometimes missing, send an empty string rather than leaving the key out. Downstream tools handle empty values better than missing keys.
- Format phone numbers consistently. E.164 format avoids matching problems in other systems.
- Version your payload. Adding a field like "payload_version" makes changes painless when you have several receivers.
Testing and debugging
Most webhook problems are invisible. The workflow says it ran, the receiver says it got nothing. Here is how I debug:
- Check the workflow execution log in HighLevel for the contact. It shows whether the action ran and, often, the response status.
- Check the receiver's history. In Make, look at the webhook queue and scenario history. In n8n, check executions.
- Use a request bin while building. Point the action at a temporary inspection URL to see exactly what HighLevel sends.
- Watch for test vs production URLs. In n8n, the test URL only listens while you are in the editor. Use the production URL in HighLevel.
- Confirm the scenario is on. A Make scenario that is switched off will not process the webhook.
Common mistakes
- No error path. If the receiver is down, the request is lost. Add a fallback, like a Slack alert from the receiver when it fails, or a tag in HighLevel when an action errors.
- Duplicate contacts from inbound webhooks. Always map email and phone so HighLevel can match.
- Secrets in URLs. Put tokens in headers, not query strings that end up in logs.
- Firing on every update. A webhook on "contact changed" can fire far more than you expect. Use filters so it only fires on the change you care about.
- Assuming instant processing. Network hiccups happen. Design receivers to be safe if the same request arrives twice.
How I build this
I connect HighLevel to Slack, ClickUp, Google Sheets and other tools for agencies using webhooks and the HighLevel API, with error handling built in from the start. If you have a webhook setup that fails quietly, the Automation Rescue is a fixed-price fix in 48 hours. For new builds, see my API integrations service, or request a free 15-minute Loom teardown and I will look at your current flow.
FAQ
What is an inbound webhook in GoHighLevel?
It is a workflow trigger with a unique URL. When an outside system sends data to that URL, the workflow starts and you can map the data to contact fields and actions.
Is the GoHighLevel inbound webhook free?
HighLevel lists it as a premium trigger, and premium triggers and actions can be billed per execution. Check your agency settings and HighLevel's current pricing for the rate.
What is the difference between Webhook and Custom Webhook in GoHighLevel?
Both send data out of a workflow. Custom Webhook gives you control over the method, headers, auth and body, which you need when the receiver is a specific API rather than a no-code tool.
How do I send GoHighLevel data to Make.com?
Create a Custom Webhook module in Make, copy its URL into a Webhook or Custom Webhook action in your HighLevel workflow, and send a test contact so Make learns the data structure.