SalesCal Docs
Integrations

GoHighLevel CRM Integration

Connect GoHighLevel (GHL) to automatically sync leads and booking data to your CRM.

Benefits

  • Automatic Lead Sync: Leads pushed to GHL automatically
  • Status Updates: Booking status synced in real-time
  • Custom Field Mapping: Form responses sync to GHL fields
  • Workflow Triggers: Trigger GHL automations from bookings

Connecting HighLevel

The connection is authorized entirely through HighLevel. You don't need an API key, and you don't enter a Location ID anywhere in SalesCal.

  1. Go to Integrations
  2. Find HighLevel
  3. Click Connect
  4. A HighLevel window opens. Sign in if you aren't already
  5. Choose the location (sub-account) you want to connect, and approve the requested permissions
  6. The window closes and the card shows as connected

The location you pick during that approval step is the one SalesCal syncs to. To sync to a different location, disconnect and connect again.

Reconnecting

SalesCal allows one CRM per team, so connecting HighLevel means you can't also have HubSpot connected at the same time. If you click Connect while a connection is already active you'll see:

gohighlevel is already connected. Disconnect first.

Disconnect from the same card, then connect again.

Reconnect if you change your HighLevel password, remove SalesCal from HighLevel's connected apps, or start seeing failures in the sync log.

How Sync Works

Lead Creation

When a lead is captured in SalesCal:

  1. Contact created in GHL
  2. Contact data mapped to GHL fields
  3. GHL contact ID stored in SalesCal
  4. Future updates use this ID

Sync Triggers

EventGHL Action
Step 1 CompleteContact created (status: incomplete)
Qualification PassContact updated (status: qualified)
Qualification FailContact updated (status: disqualified)
Booking CompleteContact updated (status: booked)

Data Synced

SalesCal FieldGHL Field
First NameFirst Name
Last NameLast Name
EmailEmail
PhonePhone
Custom FieldsCustom Fields (mapped)
Lead ScoreCustom Field (optional)
Lead GradeCustom Field (optional)
Event NameTag or Custom Field

Custom Field Mapping

Map SalesCal form fields to GHL custom fields:

  1. Go to integration settings
  2. Find Field Mapping
  3. For each SalesCal field:
    • Select the corresponding GHL field (each dropdown has a search box at the top — type to filter the list)
    • Or create a new GHL field
  4. Save mappings

Mapping Best Practices

  • Match field types (text to text, dropdown to dropdown)
  • Use consistent naming
  • Map all important fields
  • Test with a sample lead

One Saved Question, One GHL Field

Form fields come from your team's shared question library, so a question reused across several events still maps to a single GHL field — you won't get duplicate fields for the same question. Archived questions (from Settings → Questions) can't be picked for a new mapping, but a mapping created before the question was archived keeps working and still shows in your mapping list tagged (archived) — in manual mapping it moves to the Legacy Fields card, where you can unmap it whenever you no longer want it to sync.

When a Mapped Field Is Deleted in GHL

Mappings remember the exact field they point at, so deleting a custom field inside GHL doesn't remove its SalesCal mapping — the row stays in your list. When SalesCal loads your GHL field list and the mapped field is no longer in it, the row shows an amber warning: "This field no longer exists in HighLevel — re-map or delete". Pick a different GHL field to re-map the row, or set it to -- Unmapped -- to remove the mapping.

If you've just recreated the field in GHL, click the refresh button next to the mapped-field count at the top of the Configuration tab to reload the field list — the warning clears once the field is back.

Re-running auto-map (Re-run auto-map in Auto mode, or Auto-map fields in Manual mode) now recreates any mapping whose target field was deleted, instead of leaving it stale.

Automation-Ready Date and Time Fields

Four system fields turn your booking time into formats HighLevel workflows can actually use:

FieldExampleUse it for
SalesCal Call Start Time07-28-2026 02:30 PMHighLevel's Event Start Date workflow action — set it on a custom field, then use Wait events relative to it
Lead TimezoneEurope/LondonThe timezone your prospect picked their slot in
Call Day/Date (Lead timezone)Tuesday July 28, 2026Prospect-facing message copy — reads naturally when quoted back, e.g. "see you Tuesday July 28, 2026"
Call Time (Lead timezone)7:30 PMProspect-facing message copy — "your call is at 7:30 PM your time"

If your connection predates this feature, you'll see a banner on the Configuration tab recommending you reconnect and re-run auto-map so these fields start syncing.

Using SalesCal Call Start Time with the Event Start Date action: if you used automap, SalesCal already created a HighLevel contact field named SalesCal Call Start Time and sends the value there — in your workflow, point the Event Start Date action at that field and you're done. (HighLevel derives the field's merge tag from its name, so it appears as something like {{contact.salescal_call_start_time}} — the exact tag spelling doesn't matter to the action.) If you'd rather use a custom field you already have, such as appointment_start_time, change this field's target in Field Mapping to your existing field instead, and point the action at that one. Either way, this lets you drive Wait steps off the adjusted booking time without needing a native HighLevel appointment.

SalesCal Call Start Time renders in your connected HighLevel account's Business Profile timezone, captured automatically the moment you connect or reconnect. Until you reconnect, it's written in the timezone of the team member hosting each call (UTC if that host hasn't set one) — after reconnecting, it always uses your HighLevel account's timezone instead.

These fields are custom-field values for merge tags and workflow automations — between them and HighLevel's Event Start Date action, your workflows can react to the exact booking time without any extra setup.

Your prospect's timezone

When a prospect books, SalesCal records the timezone they chose their slot in — detected from their browser, or whatever they switched the widget to. Two things happen with it:

  • The contact's standard Time Zone field in HighLevel is filled in automatically. Any workflow you set to "Contact Timezone" then waits and sends on the prospect's clock, using HighLevel's own machinery. (If you map something else to the Time Zone field yourself, your mapping wins.)
  • The Call Day/Date (Lead timezone) and Call Time (Lead timezone) fields above become available for mapping. Use them in prospect-facing messages: HighLevel's {{appointment.only_start_time}} merge field always renders in your account's timezone, which reads wrong to a prospect three timezones away — the Lead-timezone fields read right.

Leads that booked before this feature (or without a detectable timezone) leave these fields empty rather than guessing.

Tag Mapping

GHL has no "lead status" concept, so SalesCal applies tags as a contact moves through each stage. In Tag Mapping, map any of these stages to one or more GHL tags:

StageMeaning
NewStarted form, didn't finish
QualifiedForm completed, passed qualification rules
DisqualifiedFailed qualification rules
BookedCall is scheduled
RescheduledCall time changed
CancelledBooking cancelled
CompletedCall completed with an outcome

When you add a tag, the field suggests tags that already exist in your connected GHL location, so you can pick an existing tag or type a brand-new one. If you type a new name, SalesCal creates the tag in GHL immediately — it shows up in your GHL tag list (and as a workflow trigger option) as soon as the mapping is saved, before any contact reaches that stage.

Tags are applied to a contact at the moment they enter a stage. Adding a mapping doesn't retroactively tag contacts that already passed that stage. If a contact syncs but its tags can't be applied, the sync appears as partial in the Sync Log with the reason, instead of reporting a clean success.

What Gets Pushed

With a calendar selected, every booking on that connection creates a HighLevel appointment titled with the event name and the prospect's name (for example, Demo Call - Jane Smith), with the exact start and end time:

SalesCal eventHighLevel appointment
Booking madeAppointment created
Booking rescheduledThe same appointment moves to the new time
Booking cancelledStatus set to cancelled
Call marked CompletedStatus set to showed
Call marked No ShowStatus set to no-show

SalesCal owns your booking availability, so the appointment is created even if the HighLevel calendar's own availability rules would have rejected the slot — HighLevel is where your bookings land, not where your booking hours come from. Appointment times respect your HighLevel account's timezone automatically.

Important: SalesCal already sends its own confirmation, reminder, and cancellation emails, so HighLevel's calendar notifications for this appointment are not triggered — your prospect won't get a duplicate confirmation from HighLevel.

In your HighLevel automations, use the "Appointment Status" workflow trigger — not "Customer Booked Appointment." HighLevel only fires "Customer Booked Appointment" for bookings made through its own booking widget, never for appointments created by an integration like SalesCal. An automation built on "Customer Booked Appointment" will silently never run for these bookings.

If a push fails, it won't block the rest of the sync — check the Sync Log for a partial entry with the reason.

*/}

GHL Automations

Trigger Ideas

On Incomplete Lead:

  • Send follow-up email
  • Add to nurture sequence
  • Notify sales rep

On Qualified Lead:

  • Send confirmation
  • Assign to rep
  • Add to hot lead list

On Disqualified Lead:

  • Send polite decline
  • Add to long-term nurture
  • Log for analysis

On Booking:

  • Send preparation email
  • Create task for rep
  • Add calendar reminder

Setting Up Automations

  1. In GHL, create a workflow
  2. Set trigger: "Contact Tag Added" or "Custom Field Changed" — or "Event Start Date" conditions built on the SalesCal Call Start Time field
  3. Use the SalesCal status values
  4. Add your automation steps

Duplicate Handling

When a lead already exists in GHL:

  • By Email: Existing contact updated
  • New Contact: Created if no match found
  • Merge Settings: Follow your GHL duplicate settings

Troubleshooting

"Failed to Connect"

  • Make sure you completed the approval step in the HighLevel window rather than closing it early
  • Check your browser isn't blocking the popup
  • Confirm the HighLevel user you signed in as has access to the location you're trying to connect
  • If a connection already exists, disconnect it first — SalesCal allows one CRM per team

Leads Not Syncing

  • Verify the connection is still active on the Integrations page
  • Check the Sync Log tab for failed attempts and the reason given
  • Confirm you connected the HighLevel location you're actually looking at
  • Test with a new lead — the log entry appears within a few seconds

Custom Fields Not Mapping

  • Verify field mapping is saved
  • Check field types match
  • Ensure GHL field exists
  • Test the specific field

Can't Create Fields in GHL ("not authorized" / permission error)

Creating custom fields needs write permission that older connections didn't grant. Disconnect and reconnect GoHighLevel to refresh permissions, then try again.

Duplicate Contacts

  • Review GHL duplicate settings
  • Check if email matching is enabled
  • Consider merging duplicates manually

Status Not Updating

  • Verify webhook/trigger is active
  • Check GHL automation is running
  • Look for GHL error logs

Viewing Sync Status

In SalesCal lead records:

  • GHL Contact ID: Shows if synced
  • GHL Synced At: Last sync timestamp
  • Sync Status: Success or error

Disconnecting GoHighLevel

To remove the connection:

  1. Go to Integrations
  2. Find GoHighLevel
  3. Click Disconnect
  4. Confirm

Note: Existing GHL contacts remain, but new leads won't sync.

Data Privacy

  • Only lead data is sent to GHL
  • Follows your GHL privacy settings
  • You control what fields sync
  • Can disconnect at any time

Best Practices

Clean Setup

  • Map all fields before going live
  • Test sync with sample leads
  • Set up automations for each status

Consistent Data

  • Use same field names when possible
  • Keep custom fields organized
  • Document your mapping

Monitor Syncs

  • Check sync status regularly
  • Address errors promptly
  • Review automation performance

Leverage Automations

  • Automate follow-ups
  • Create tasks for sales team
  • Segment leads by status/grade

Advanced: Webhook Mode

For more control, use webhooks:

  1. Enable webhook mode in integration settings
  2. SalesCal sends events to your webhook
  3. Your system processes and syncs to GHL
  4. More flexibility for custom logic