GoHighLevel has several webhook mechanisms, and choosing the right one depends mainly on where the request starts and where the data needs to go.
The four practical paths are:
1. Marketplace / App Webhook
HighLevel event → Your application
2. Workflow Inbound Webhook
External system → HighLevel workflow
3. Workflow Webhook (Outbound)
HighLevel workflow → External URL
4. Workflow Custom Webhook
HighLevel workflow → External API with more request control
If your application needs to listen for events happening inside HighLevel, use Marketplace/App webhooks.
If an external service needs to start a HighLevel workflow, use the Inbound Webhook Trigger.
If a workflow simply needs to send its available data to another URL, the standard Webhook action may be enough.
If the receiving API requires authentication, custom headers, query parameters, a controlled JSON body, or more control over the HTTP request, Custom Webhook is usually the better fit. HighLevel itself currently recommends Custom Webhook for advanced authentication and flexible request construction, while positioning Webhook (Outbound) for simpler patterns.
The important first question is therefore not:
“How do I create a GoHighLevel webhook?”
It is:
“Which GoHighLevel webhook surface matches the integration I am building?”
The Four GoHighLevel Webhook Paths
Several HighLevel features exchange data through HTTP, but they belong to different parts of the platform and do not share exactly the same payload, security, retry, or debugging behavior.
HighLevel feature
Direction
Main job
Typical use
Marketplace / App Webhook
HighLevel → your app
Notify an installed application when supported HighLevel events occur
SaaS apps, custom backends, developer integrations
Workflow Inbound Webhook
External system → HighLevel workflow
Start a workflow with external data
Third-party apps, custom integrations, external systems
Workflow Webhook (Outbound)
HighLevel workflow → external URL
Send workflow and trigger data outward
n8n, Make, internal services, simple receivers
Workflow Custom Webhook
HighLevel workflow → external API
Build a more controlled outbound API request
APIs requiring auth, headers, query parameters or custom payloads
A simple way to visualize the difference is:
HIGHLEVEL WEBHOOK PATHS
┌────────────────────────────┐
│ Marketplace / App Webhook │
│ HighLevel → Your App │
└─────────────┬──────────────┘
│
▼
Backend / SaaS App
External System
│
▼
┌─────────────────────────────┐
│ Workflow Inbound Webhook │
│ External → HighLevel │
└─────────────────────────────┘
HighLevel Workflow
│
├──────────────► Webhook (Outbound)
│ Simpler outbound request
│
└──────────────► Custom Webhook
Controlled API request
Caption: HighLevel webhook options differ mainly by data direction, where the request originates, and how much control the receiving integration requires.

For external systems that need to start a HighLevel workflow, see the full GoHighLevel Inbound Webhook guide
When a workflow needs control over the HTTP method, authentication, headers, or request body, see GoHighLevel Custom Webhook
Marketplace/App Webhooks: When HighLevel Needs to Notify Your Application
Marketplace/App webhooks are the developer-facing event model.
They are appropriate when your own application or backend needs to react when something happens inside HighLevel.
For example:
Contact changes in HighLevel
↓
Marketplace webhook
↓
Your backend
↓
Application logic
A Marketplace application can configure a webhook endpoint and subscribe to supported HighLevel event types. The app also needs the appropriate scopes for the events and data it uses. HighLevel's current developer documentation exposes webhook event families across contacts, opportunities, calendars and appointments, messaging, payments, locations, records, and other platform resources.
This is different from adding a Webhook action to a Workflow.
A Marketplace webhook is tied to the application's event subscription model. A Workflow Webhook is an action that only executes when a specific workflow run reaches that step.
Marketplace webhook security
Marketplace webhooks have a documented signature-verification model.
As of August 27, 2026, HighLevel documents two signature headers:
X-GHL-Signature— Ed25519, the current mechanism;X-WH-Signature— RSA-SHA256, the legacy mechanism.
HighLevel currently says the legacy X-WH-Signature header will be deprecated on September 1, 2026, after which Marketplace webhook delivery will rely on X-GHL-Signature. The current documentation recommends preferring X-GHL-Signature whenever it is present.
A receiving application should verify the webhook before trusting or processing the event.
Because the documented deprecation date is very close, the legacy-header wording should be checked again against the official documentation immediately before publication.
If the webhook hands work to a custom application, see the production GoHighLevel API integration guide
Marketplace webhook retries
HighLevel also documents a retry policy specifically for Marketplace webhook delivery.
When the receiving endpoint returns a non-2xx HTTP response, or HighLevel cannot obtain an HTTP response because of a timeout or transport problem, HighLevel currently retries delivery using exponential backoff with random jitter.
The documented policy allows up to 12 retries after the original delivery attempt. Retries stop once HighLevel receives a 2xx response.
That is an important distinction:
Marketplace webhook delivery retries are not the same thing as retrying your entire business process.
For example:
HighLevel
↓
Webhook delivered
↓
Your endpoint returns 200
↓
Background processing starts
↓
External API fails
From HighLevel's perspective, the webhook was delivered successfully.
From the business perspective, the integration may still have failed.
A successful delivery therefore tells you that the receiving boundary accepted the event. It does not prove every downstream operation completed successfully.
Marketplace Webhook Logs
HighLevel's Webhook Logs Dashboard helps developers inspect this delivery boundary.
The current dashboard exposes information such as:
- event name;
- Webhook ID;
- attempted time;
- HTTP status;
- attempt number;
- payload details;
- automatic retry activity.
It also supports manual resend for eligible failed deliveries.
This makes it possible to answer an important debugging question:
Did HighLevel actually send the Marketplace webhook, and what response did the receiving endpoint return?
That is different from asking whether everything your application did afterward succeeded.
For one integration I subscribed the app to HighLevel's contact update events at the Marketplace level rather than adding a Webhook action inside each client's workflow. When a contact changed in any installed location, HighLevel delivered the event to the app's endpoint. The endpoint verified the signature, identified the location from the payload, deduplicated the delivery, acknowledged with a 200, and handed the event to async processing that reconciled the change into an external system.
Marketplace/App webhooks were the correct choice here, not a Workflow Webhook, for one concrete reason: the app needed to react to the event across every installed sub-account without depending on each client building and maintaining a workflow. A Workflow Webhook only fires when a specific workflow run reaches that step, so it would have meant configuring and policing the same action in dozens of separate workflows, and any client who edited or removed it would silently break the integration. Subscribing once at the app level meant the event model was owned by the application, applied uniformly across locations, and arrived with a verifiable signature the backend could trust.

Workflow Inbound Webhook: When an External System Should Start HighLevel
The Inbound Webhook Trigger moves data in the opposite direction.
An external system sends a request to a webhook URL generated by a HighLevel workflow.
External application
↓
Inbound Webhook URL
↓
HighLevel Workflow
↓
Workflow actions
HighLevel currently documents POST, GET, and PUT as supported request methods for this trigger. The incoming request is used as a mapping reference so its values can be used later in the workflow.
A simple use case could look like:
External checkout
↓
Inbound Webhook
↓
HighLevel Workflow
↓
Process incoming data
↓
Notify team / update system
The key difference from a Marketplace webhook is ownership of the event.
With Marketplace webhooks:
HighLevel event → your system
With an Inbound Webhook:
your external system → HighLevel workflow
Does an Inbound Webhook require a contact?
Not always.
HighLevel's current documentation says an Inbound Webhook workflow can continue contactless when its downstream actions do not depend on contact data.
For example, current documentation lists actions such as Custom Webhook, Google Sheets, Slack, ChatGPT, and internal tools as actions that can run without a contact.
If the workflow needs to create, update, or find a contact, however, the necessary contact data must be available. HighLevel specifically notes that email or phone is required when creating or matching a contact through the relevant contact actions.
That is why the accurate question is not:
“Does every inbound webhook need a contact?”
It is:
“Do the actions this workflow is going to execute require contact context?”
The full Inbound Webhook guide should handle setup, testing, mapping, payload structure, URL security, and troubleshooting in more detail.

Workflow Webhook: The Simpler Outbound Option
The standard Webhook action sends data from a HighLevel workflow to an external URL.
HighLevel Workflow
↓
Webhook action
↓
External receiver
HighLevel currently describes this feature as a Workflow Action Webhook. When a contact reaches the action, HighLevel sends relevant workflow data to the configured destination. The action lets you select an HTTP method and destination URL and add additional custom key/value data to the payload.
Typical uses include:
- sending a lead to an n8n webhook;
- notifying an internal application;
- passing workflow data to Make or another automation system;
- handing a workflow event to a custom endpoint.
The payload depends on workflow context
The payload is not identical in every workflow.
HighLevel documents standard contact and location data, while additional trigger-specific objects can be included when the workflow was started with that context.
For example, an appointment-related trigger can provide appointment information, while an opportunity-related trigger can provide opportunity context.
That means a workflow triggered by something unrelated to appointments should not be expected to automatically contain appointment data.
The practical rule is:
Use the standard Webhook action when the workflow's normal outbound payload and simple custom fields are enough for the receiving service.
Custom Webhook: When You Need More Control Over the Request
Custom Webhook is also an outbound Workflow action, but it is designed for cases where the receiving service expects a more specific API request.
HighLevel currently documents support for:
GET;POST;PUT;DELETE;- Bearer Token authentication;
- API Key authentication;
- Basic Auth;
- OAuth2;
- custom headers;
- query parameters;
- JSON and form payloads;
- mapped dynamic workflow values;
- optional response capture where available.
Conceptually:
HighLevel Workflow
↓
Custom Webhook
↓
POST /api/orders
Authorization: Bearer ...
Content-Type: application/json
Custom request body
↓
External API
This is useful when you are integrating directly with an API whose documentation says:
Send this HTTP method, with these headers, using this authentication scheme and this JSON structure.
Webhook vs Custom Webhook
The two actions overlap, but they are not interchangeable in every use case.
Requirement
Webhook (Outbound)
Custom Webhook
Send workflow/contact data to an external URL
Yes
Yes
Choose an HTTP method
Yes
Yes, with more request controls
Add simple custom key/value data
Yes
Yes
Dedicated authentication configuration
Not documented as a core standard-WebHook control
Yes
Custom headers
Not documented as a standard action control
Yes
Dedicated query-parameter controls
Not documented as a standard action control
Yes
Raw/controlled JSON body
More limited
Yes
Nested API payloads
Not the main use case
Yes
Response capture
Not documented in the standard action
Available in Custom Webhook where supported
Simple workflow → URL handoff
Good fit
Often unnecessary
External REST API with specific request contract
Sometimes
Usually the better fit
HighLevel's current documentation summarizes the choice directly: use Custom Webhook when advanced authentication or flexible request construction is required, and use Webhook (Outbound) for simpler, predefined patterns.
Custom Webhook is therefore not automatically “better.”
It simply solves a more controlled HTTP-request problem.
Security and Reliability Depend on the Webhook Surface
A common mistake is to learn one HighLevel webhook behavior and apply it to every webhook-related feature.
For example:
X-GHL-Signature verifies GoHighLevel webhooks.That statement is too broad without context.
X-GHL-Signature is part of the current Marketplace/App webhook signing model documented in HighLevel's developer platform.
You should not assume that every HTTP request produced by every HighLevel workflow feature uses that same Marketplace signing model.
The same caution applies to retries.
HighLevel documents up to 12 retries for failed Marketplace/App webhook delivery. That does not by itself prove that Workflow Webhook and Custom Webhook actions use an identical delivery policy.
A safer comparison is:
Surface
Important things to verify
Marketplace/App Webhook
Event subscription, app scopes, signature verification, delivery retries, Webhook Logs
Workflow Inbound Webhook
Generated endpoint, accepted payload, mapping, contact dependencies, URL exposure
Workflow Webhook
Workflow trigger/context, destination URL, method, payload, Execution Logs
Custom Webhook
Auth, method, headers, parameters, body, external API response, Execution Logs
The general rule is:
Use the documentation for the exact HighLevel feature you are implementing rather than assuming every “webhook” in HighLevel behaves the same way.
Webhook vs API vs n8n: Which One Should Handle the Integration?
Webhooks and APIs solve related but different problems.
A webhook is normally useful when another system needs to react because an event occurred.
An API request is normally useful when your system needs to read or change state explicitly.
They are often used together.
For example:
Opportunity changes in HighLevel
↓
Marketplace webhook
↓
Backend
↓
Business logic
↓
HighLevel API + external API
↓
State updated
The webhook tells your application:
Something happened.
The API lets your application ask or instruct:
What is the current state?
or:
Make this change.
n8n, Make, or Zapier can also be appropriate when the main job is coordinating SaaS applications rather than building a custom application.
n8n currently exposes supported HighLevel operations and also allows raw REST calls through its HTTP Request node when a built-in HighLevel operation does not cover the required API call.
A useful starting-point decision looks like this:
Requirement
Likely starting point
Your app must react to a HighLevel platform event
Marketplace/App Webhook
External system must start a HighLevel workflow
Inbound Webhook
HighLevel workflow should send simple data outward
Workflow Webhook
Workflow must call an API requiring custom auth/request structure
Custom Webhook
Application must read or update HighLevel state on demand
HighLevel API
Several SaaS tools need visual orchestration
n8n / Make / Zapier
You need your own state, API, database or business logic
Custom backend
Where does Temporal fit?
Temporal is not required for most webhook integrations.
A webhook can trigger an n8n workflow, a normal backend, a queue consumer, or another worker without adding a durable orchestration layer.
Temporal becomes relevant only when the downstream business process itself becomes difficult to manage—for example, when it is long-running, spans several independently failing systems, contains waits or callbacks, and must reliably resume from persisted process state after failures.
In that situation, the webhook remains the event boundary:
HighLevel event
↓
Webhook
↓
Application
↓
Long-running business process
↓
Durable orchestration if genuinely needed
The existence of a webhook alone is not a reason to introduce Temporal.
A Simple GoHighLevel Webhook Debugging Model
When someone says:
“My GoHighLevel webhook is not working.”
that still does not tell you where the failure occurred.
A useful debugging sequence is:
1. Did the event or workflow trigger actually happen?
↓
2. Did HighLevel send or receive the HTTP request?
↓
3. Did the other endpoint accept the request?
↓
4. Did the downstream process complete?
Each layer can fail independently.
1. Did the event or workflow trigger happen?
For a Marketplace integration, confirm:
- the expected event actually occurred;
- your application is subscribed to the event;
- the installed app has the relevant scope.
For a Workflow Webhook, confirm that the workflow run actually reached the Webhook step.
2. Did HighLevel handle the HTTP boundary?
For Marketplace webhooks, check Webhook Logs.
They can tell you whether HighLevel attempted delivery and what HTTP status the receiver returned.
For Workflow Webhook actions, current HighLevel documentation points users to Workflow Execution Logs to confirm the action executed.
For Custom Webhook, HighLevel likewise recommends checking Execution Logs and the receiving provider's logs while testing request method, headers, authentication, payload and response status.
3. Did the receiver accept the request?
If HighLevel did send the request but the external system returned:
401;403;404;422;- or another failure code,
the next investigation belongs at the receiving API or endpoint.
Check:
- endpoint URL;
- credentials;
- method;
- required headers;
- payload format;
- permissions.
4. Did downstream processing finish?
This is where delivery and business processing separate.
Imagine:
HighLevel
↓
Webhook
↓
n8n receives request
↓
HTTP receiver returns success
↓
Later n8n step fails
HighLevel successfully delivered the request.
The automation as a whole did not successfully complete.
That is why a 200 response from the receiver should not automatically be interpreted as:
“The entire integration worked.”
It only proves that the receiving boundary accepted the request.
I needed a HighLevel workflow to push a lead into an external service the moment a contact reached a certain stage. The receiving API required a Bearer token in the Authorization header and a specific JSON body shape, not just HighLevel's default payload. The standard Webhook action couldn't satisfy that: it sends a predefined payload to a URL and doesn't give you dedicated controls for authentication or a custom request body. So I used the Custom Webhook action, which let me set the method, add the Authorization header, and map workflow values into the exact JSON structure the endpoint expected. Plain Webhook would have been the right call for a simple hand-off to something like an n8n catch webhook with no auth, but here the destination's request contract is what made Custom Webhook the correct choice.
See GoHighLevel workflow not triggering
Which GoHighLevel Webhook Should You Use?
The decision can be reduced to four practical questions.
Your application needs to listen for HighLevel events
Use Marketplace/App Webhooks.
HighLevel event
↓
Your application
An external application should start a HighLevel workflow
Use the Inbound Webhook Trigger.
External system
↓
HighLevel workflow
A HighLevel workflow only needs to send straightforward data outward
Start with Webhook (Outbound).
HighLevel workflow
↓
External URL
The receiving API requires authentication or a controlled HTTP request
Use Custom Webhook.
HighLevel workflow
↓
Custom API request
↓
External API
The right webhook is determined by direction, product context, and request requirements.
If the difficult part is no longer sending the webhook but managing persistence, retries, reconciliation, multiple external APIs, and recovery after partial failures, the problem has moved beyond webhook configuration into production integration architecture.
For integrations that have reached that level of complexity, an architecture review is usually more useful than adding another automation step.
For custom webhook and integration work, work with a GoHighLevel developer
Need Help With a Custom GoHighLevel Integration?
If you are trying to decide between HighLevel webhooks, the API, n8n, a custom backend, or a more durable orchestration architecture, Hamza can help review the actual integration requirements and choose the simplest architecture that safely handles the process.
The goal is not to add more infrastructure than necessary.
It is to identify:
- where the event should originate;
- which system owns the business logic;
- what needs to happen after delivery;
- how failures should be handled;
- and which execution layer is appropriate for the real process.
