Skip to content

GHL (GoHighLevel) ​

Discovery plan

On the Discovery plan, one CRM connection is active at a time (error plan_free_one_crm beyond that).

What It Does ​

The native GoHighLevel connection is a one-click (OAuth) link to a GHL sub-account. Once connected:

  • Initial import: contacts, opportunities, appointments and custom field definitions of the sub-account are imported in the background (resumed automatically until the import is complete).
  • Real time, no webhook to create: every new contact, every appointment and every opportunity status change reaches DURUM.ai automatically.
  • Classification by name: your forms, surveys, calendars and pipelines appear with their names in the configuration. You say what each one represents: that is what decides what DURUM.ai counts as a lead, an application, a booking or a sale.
  • Native sale: an opportunity moved to Won in a pipeline you selected counts as one sale, once.
GHL eventType in DURUM.aiCondition
Contact createdLead or ApplicationBased on the classification of the form that created the contact (see below)
Appointment created or updatedBooking, cancellation or no-showBased on the appointment status and the calendar classification
Opportunity moved to WonSalePipeline selected in Configuration; other statuses and pipelines write nothing

What changed on September 15, 2026

The sale is no longer a GHL workflow to build. You select your sales pipelines in DURUM.ai, and every won opportunity becomes a native sale, deduplicated per opportunity.


Before You Start ​

  • Administrator access to the GHL sub-account (location) to connect.
  • Know which forms are opt-ins (lead) and which are qualification forms (application).
  • Know which calendars are closing calendars (booking) and which should be ignored (onboarding, internal, autobook).
  • Know in which pipeline(s) a deal moves to Won when the customer buys, and the amount of a sale if you want a fixed value.

Step-by-Step Connection ​

  1. Open Settings → Integrations → GoHighLevel card → Connect.
  2. GHL asks you to choose the sub-account (location) to connect, then to authorize DURUM.ai.
  3. You return to DURUM.ai: the card shows Connected and the initial import starts in the background.

Permissions requested (read-only): contacts, opportunities, calendars and their events, forms, surveys, sub-account information, custom fields.

From the GHL marketplace ​

If you install the DURUM.ai app from the GHL marketplace, you are redirected to a /connect/ghl page in DURUM.ai to attach the installation to your account. The result is identical to a connection started from Settings.

What happens after the connection ​

  • Initial import: processed in batches every 5 minutes until done (a large CRM is imported over several passes without losing anything).
  • Recurring sync every 10 minutes: GHL users (matched to your reps) and recorded calls, when the connection permissions allow it. Custom field names are refreshed as soon as they are older than 6 hours.
  • UTM fields: when the configuration is saved, DURUM.ai creates the missing UTM custom fields in GHL so attribution follows every contact.

Configuration ​

Open Settings → Integrations → GoHighLevel → Configuration. The window loads your forms, calendars and pipelines with their names. The screen labels are in French: "À classer" (to classify), "Lead", "Application", "Ignorer" (ignore), "Booking".

1. Forms and surveys ​

For each form or survey: To classify, Lead, Application or Ignore.

  • Lead: opt-in.
  • Application: qualification form.
  • Ignore: not counted.

How it is applied to new contacts: GHL does not say which form created a contact. For every contact created, DURUM.ai asks GHL (forms, then surveys, around the contact creation date, up to three attempts) to find the submission that created it, then applies its classification.

Lookup resultWhat DURUM.ai does
Form found and classified Lead or ApplicationCounted with that type
Form found and classified IgnoreContact ignored ("ignored" status in Logs)
Form found but not yet classifiedCounted as a lead
No form found, or GHL does not answerCounted as a lead (never a silent loss)

The lookup result is kept on every lead so it can be checked.

2. Calendars ​

For each calendar: To classify, Booking or Ignore.

  • Booking: closing call, counted.
  • Ignore: everything else (onboarding, internal). The appointment stays in the contact's journey but no longer counts as a booking.
  • To classify: as long as a calendar is unclassified, its appointments count as bookings, and Configuration shows a reminder once at least one calendar has been classified.

Calendar names are stored when you save: cancellations and no-shows follow the calendar classification.

3. Sales (pipelines) ​

Select the pipelines where a deal moves to Won when the customer buys. For each selected pipeline, enter the amount of a sale or leave it empty to use the value entered in the GHL opportunity.

Rule applied:

  • Opportunity status Won and pipeline selected = one sale.
  • An opportunity becomes a sale only once, even if it flips back to Won several times.
  • Sale date = date of the move to Won when GHL provides it.
  • Amount = fixed pipeline amount, otherwise the opportunity value.
  • Any other status, an unselected pipeline or no selected pipeline = nothing is written.

The sale's contact is found in the imported contacts, otherwise requested from GHL. Without an email, the sale is recorded but cannot be tied to the lead. A sale then triggers your conversion workflows (Meta, Google) if you have any on the sale event.

4. Additional options ​

Count new GHL contacts as leads: a contact created without a form (manual add, import, other source) counts as a lead. A form set to Ignore stays ignored.

Click Save. Settings apply immediately to the next events.

Custom fields ​

A contact's GHL custom fields are displayed by name (not by identifier) in the DURUM.ai contact card. Definitions are synced at connection and refreshed by the recurring sync.


Verify It Works ​

  1. Create a test contact in GHL through a form classified Lead (use a recognizable email).
  2. In DURUM.ai, open the Logs page (main menu): the event appears with source ghl.
  3. For the sale: move a test opportunity to Won in a selected pipeline. The log shows the pipeline, the amount and where it came from (pipeline or opportunity).
  4. Delete the test contact in GHL after verification.

Statuses you can see in Logs:

StatusMeaning
processedEvent counted
ignored (status_not_won, pipeline_not_selected)Opportunity change that is not a sale
ignored (ghl_mapping_ignore)Form classified Ignore
ignored (unmapped_ghl_location)The GHL sub-account is not attached to any DURUM.ai account
dedupedSame opportunity or same event already counted
quarantinedUnknown form received through a manual workflow (see below)

Events Captured ​

GHL eventType in DURUM.aiDetails
ContactCreatelead or applicationType based on the form classification; contact without a form = lead
AppointmentCreate, AppointmentUpdate, AppointmentDeletebooking, booking_cancel, no_showDerived from the appointment status; Ignore calendar = kept without counting
OpportunityStatusUpdatesaleOnly Won status in a selected pipeline; deduplicated per opportunity

An appointment without email or phone is rejected (ghost booking).


Alternative Method: Manual GHL Workflows ​

If you do not use the native connection, the standard webhooks remain valid. The URLs are in Settings → Integrations → For your developer section, already filled with your Business ID. For GHL, always add &source=ghl at the end.

EventGHL workflow triggerURL
LeadContact Createdhttps://app.durum.ai/api/webhook/lead?bid=YOUR_BUSINESS_ID&source=ghl
ApplicationForm Submitted (qualification forms)https://app.durum.ai/api/webhook/application?bid=YOUR_BUSINESS_ID&source=ghl
BookingAppointment Status Changed (Booked or Confirmed)https://app.durum.ai/api/webhook/booking?bid=YOUR_BUSINESS_ID&source=ghl
No-showAppointment Status Changed (No Show)https://app.durum.ai/api/webhook/no-show?bid=YOUR_BUSINESS_ID&source=ghl
SaleOpportunity Status Changed (Won)https://app.durum.ai/api/webhook/sale?bid=YOUR_BUSINESS_ID&source=ghl

In each workflow: Webhook action, POST method, default body (GHL sends the contact data). Publish the workflow.

Unknown forms and quarantine

With a manual workflow, the form arrives with its identifier. If it is classified in Configuration, the classification applies. Otherwise, the event is quarantined until it is categorized; later events from the same form are then recognized. With the native connection this case does not exist: an unclassified form counts as a lead.


Troubleshooting ​

ProblemSolution
The contact does not appear in LogsCheck that the GoHighLevel card shows Connected and that the right sub-account was chosen; reconnect if the card shows an error
A contact counts as a lead although its form is set to IgnoreGHL did not return the submission (delay or form not linked to the contact): the contact is counted as a safety measure; the lookup detail is kept on the lead
No GHL saleNo pipeline selected in Configuration → Sales, or the opportunity is not in Won status, or it is in an unselected pipeline
Sale counted without an amountPipeline selected without a fixed amount and opportunity without a value: enter an amount in Configuration or in the opportunity
Appointments from an internal calendar counted as bookingsSet that calendar to Ignore
unmapped_ghl_location statusThe GHL sub-account is not attached to any account: redo the connection from Settings
401 error on a manual workflowCheck &source=ghl and the Business ID in the URL

FAQ ​

Do I still need to create GHL workflows? ​

No, not with the native connection. Manual workflows remain possible for an account that cannot connect GHL through OAuth.

Can I connect several GHL sub-accounts? ​

One native connection corresponds to one GHL sub-account per DURUM.ai account.

An opportunity goes back to Won after being reopened: two sales? ​

No. The deduplication key is the opportunity: one sale per opportunity.

Where does the sale amount come from? ​

From the fixed pipeline amount if you entered one, otherwise from the monetary value of the GHL opportunity. Without either, the sale is counted without an amount.

What happens to appointments from an "Ignore" calendar? ​

They remain visible in the contact's journey but do not count as bookings, and do not feed counted cancellations or no-shows.


Powered by DURUM.ai: ad attribution and operational intelligence