HighLevel (GoHighLevel)
Creates or updates contacts in a HighLevel (LeadConnector) sub-account server-side through the v2 Contacts upsert API.
Why route GoHighLevel through Datafly Signal
- Profiles are updated from the server, not the browser. Events reach GoHighLevel even when a tracker blocker or a failed page unload would have dropped a client-side call, so the profile reflects what actually happened.
- One consent decision governs every destination. GoHighLevel is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
Prerequisites
Create a Private Integration token
In the sub-account, open Settings > Private Integrations and create one with the contacts.write scope.
Find the Location ID
Settings > Business Profile, or the sub-account URL.
Check duplicate settings
The upsert follows the location’s Allow Duplicate Contact setting (email or phone priority).
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
access_token | secret | Yes | A HighLevel Private Integration token created in the target sub-account with the contacts.write scope. Settings > Private Integrations > Create New Integration. Sent as a Bearer token. Rotate every 90 days. |
location_id | text | Yes | The HighLevel sub-account (Location) ID that contacts are written to. Found in Settings > Business Profile, or in the URL when viewing the sub-account. Must match the sub-account where the Private Integration token was created. |
Signal setup
- Navigate to Integrations in the sidebar and open the Integration Library tab.
- Find HighLevel (GoHighLevel), click Install and fill in the fields above.
- Pick the preset for your use, then review the mappings in the blueprint editor.
API endpoint
POST https://services.leadconnectorhq.com/contacts/upsert
Authorization: Bearer {access_token}
Version: 2021-07-28Example request:
{"locationId": "ve9EPM428h8vShlRW1KT", "email": "jane.doe@example.com", "phone": "+447700900123",
"firstName": "Jane", "lastName": "Doe", "name": "Jane Doe", "companyName": "Acme Ltd",
"city": "Bath", "state": "Somerset", "postalCode": "BA1 1AA", "country": "GB",
"website": "https://acme.example", "timezone": "Europe/London", "source": "pricing_page"}The presets turn on the strict output contract: only the fields the blueprint maps are sent.
Event mapping
Default preset (default)
Upsert a HighLevel contact in the configured sub-account when a visitor identifies, signs up or submits a lead or demo request: name, email, phone (E.164), company, city, state, postcode, country (ISO code), website, timezone and the lead source. Sent in plain text: HighLevel matches the contact on email or phone and the business works from the record. Consent is not written into do-not-disturb, and tags are not sent (the upsert would replace the contact’s tags). Events with neither an email nor a phone are not sent.
| Signal event | Sent to the vendor as | Enabled |
|---|---|---|
page | upsert | no (mapped, disabled) |
identify | upsert | yes |
sign_up | upsert | yes |
generate_lead | upsert | yes |
demo_requested | upsert | yes |
Identity and personal data
The contact comes from the identify traits: name, email (trimmed, lower-cased), phone (E.164), company, address and website, with the browser timezone and the lead source. These are sent in plain text: HighLevel matches the contact on email or phone and the business works from the record. Events with neither an email nor a phone are not sent.
Consent
Map the integration to the consent category your organisation uses for CRM or sales data. Signal does not write cookie consent into the CRM: no subscription status, do-not-disturb flag, list or tag is set from it, because a cookie banner choice is not a permission to email or call someone. In particular the dnd (do-not-disturb) flag is never set from consent.
Known limitations
tagsreplaces every tag on the contact, so the presets send none; use HighLevel’s Add Tag API or a workflow instead.customFieldstake location-specific field IDs; add them in the blueprint per sub-account.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
401 | Token expired or from another sub-account. |
422 | Invalid email or phone. |