How to connect GoHighLevel to n8n via webhook

    The definitive guide to wiring GHL events into n8n workflows — trigger configuration, payload parsing, and the gotchas nobody documents.

    Last updated 2026-06-08~5 min read
    GoHighLeveln8nWebhookHTTP Request

    Skip the setup. Download the n8n workflow JSON — webhook trigger with header auth, immediate 200 response, payload normalisation, retry dedupe, and event routing already wired. Import it and replace the four placeholder nodes.

    What this integration does

    When an event happens in GoHighLevel — new contact, form submission, pipeline stage change, appointment booked — a webhook fires to n8n. n8n receives the payload, processes it (enrich, filter, transform), and routes it to other systems: Slack notifications, Supabase database inserts, email sequences, AI agent triggers, or back to GHL via API.

    This is the foundational integration pattern for any agency running GHL + n8n. Once you have this webhook pipeline working, you can extend it to hundreds of downstream automations.

    Prerequisites

    • n8n instance (cloud or self-hosted) running and accessible via a public URL
    • GoHighLevel account with workflow access
    • Basic familiarity with n8n's Webhook node

    Step 1: Create the n8n webhook receiver

    • In n8n, create a new workflow
    • Add a Webhook node as the trigger
    • Set HTTP Method to POST
    • Copy the Test URL (you'll switch to Production URL later)
    • Set Authentication to "None" for now (we'll add header auth in step 5)
    • Save but do NOT activate yet

    Step 2: Create the GHL workflow trigger

    • In GoHighLevel, go to Automation > Workflows > Create Workflow
    • Add a trigger (e.g., "Contact Created" or "Form Submitted")
    • Add a "Webhook" action step after the trigger
    • Paste the n8n Test URL into the webhook URL field
    • Set Method to POST
    • Set Headers: Content-Type: application/json
    • In the Body, map the GHL variables you need:
    {
      "contact_name": "{{contact.name}}",
      "contact_email": "{{contact.email}}",
      "contact_phone": "{{contact.phone}}",
      "contact_id": "{{contact.id}}",
      "event_type": "contact_created"
    }

    Save the workflow but keep it in Draft.

    Step 3: Test the connection

    • In n8n, click "Listen for Test Event" on the Webhook node
    • In GHL, manually trigger the event (create a test contact, submit a test form)
    • n8n should receive the payload — inspect it to see the exact field names and structure
    • If it doesn't fire, check the GHL workflow troubleshooting guide

    Step 4: Switch to Production URL

    • In n8n, activate the workflow (toggle ON)
    • Copy the Production URL from the Webhook node — it's different from the Test URL
    • Go back to GHL, update the webhook URL to the Production URL
    • Publish the GHL workflow (toggle from Draft to Published)
    • Test again with a real event to confirm end-to-end

    Step 5: Add authentication (recommended)

    • In n8n, edit the Webhook node, set Authentication to "Header Auth"
    • Set Header Name to x-webhook-secret and generate a random value:
    openssl rand -hex 32
    • In GHL, add the same header and value to the webhook action
    • This prevents anyone who discovers your webhook URL from sending fake events

    Common gotchas

    1. Test URL vs Production URL. This is the #1 mistake. The Test URL only works when you're actively listening in the n8n editor. The Production URL works 24/7 but only when the workflow is activated. If your webhook "stops working" after you close the n8n editor, this is why.

    2. Payload differences between triggers. GHL sends different payloads for different triggers. A "Contact Created" payload has different fields than a "Form Submitted" payload. Always test with the actual trigger you'll use in production, not a different one.

    3. GHL webhook retries. GHL will retry failed webhooks up to 3 times. If your n8n workflow is slow to respond (> 10 seconds), GHL might retry and you'll process the event multiple times. Add an IF node that checks for duplicate contact IDs, or use the "Respond to Webhook" node to return a 200 immediately before processing. See the n8n production reliability checklist for the full pattern.

    4. Self-hosted n8n behind a reverse proxy. Make sure your proxy forwards the request body correctly. Nginx sometimes strips the body on POST requests if proxy_pass isn't configured with proxy_set_header Host and the correct proxy_buffering settings.

    Extending this pattern

    Once the webhook pipeline works, common extensions:

    • Add an IF node to route different event types to different branches
    • Add a Supabase node to log every event for analytics
    • Add a Slack node for real-time team notifications
    • Chain multiple GHL API calls to enrich the contact data before processing
    • Add error handling with an Error Trigger workflow that alerts you on failures

    Browse 4,900+ ready-to-import workflow templates →

    Need this workflow customized or debugged? Book a 30-min scope call →

    Stuck configuring this workflow?

    I build and fix n8n workflows for agencies and SaaS teams. 30-minute scope call — bring the problem, leave with an estimate.

    Related pages

    Related workflows