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
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.
Go to Integrations
Find HighLevel
Click Connect
A HighLevel window opens. Sign in if you aren't already
Choose the location (sub-account) you want to connect, and approve the requested permissions
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.
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.
When a lead is captured in SalesCal:
Contact created in GHL
Contact data mapped to GHL fields
GHL contact ID stored in SalesCal
Future updates use this ID
Event | GHL Action |
Step 1 Complete | Contact created (status: incomplete) |
Qualification Pass | Contact updated (status: qualified) |
Qualification Fail | Contact updated (status: disqualified) |
Booking Complete | Contact updated (status: booked) |
SalesCal Field | GHL Field |
First Name | First Name |
Last Name | Last Name |
Phone | Phone |
Custom Fields | Custom Fields (mapped) |
Lead Score | Custom Field (optional) |
Lead Grade | Custom Field (optional) |
Event Name | Tag or Custom Field |
Map SalesCal form fields to GHL custom fields:
Go to integration settings
Find Field Mapping
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
Save mappings
Match field types (text to text, dropdown to dropdown)
Use consistent naming
Map all important fields
Test with a sample lead
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.
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.
Four system fields turn your booking time into formats HighLevel workflows can actually use:
Field | Example | Use it for |
SalesCal Call Start Time |
| HighLevel's Event Start Date workflow action — set it on a custom field, then use Wait events relative to it |
Lead Timezone |
| The timezone your prospect picked their slot in |
Call Day/Date (Lead timezone) |
| Prospect-facing message copy — reads naturally when quoted back, e.g. "see you Tuesday July 28, 2026" |
Call Time (Lead timezone) |
| Prospect-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.
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.
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:
Stage | Meaning |
New | Started form, didn't finish |
Qualified | Form completed, passed qualification rules |
Disqualified | Failed qualification rules |
Booked | Call is scheduled |
Rescheduled | Call time changed |
Cancelled | Booking cancelled |
Completed | Call 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.
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 event | HighLevel appointment |
Booking made | Appointment created |
Booking rescheduled | The same appointment moves to the new time |
Booking cancelled | Status set to cancelled |
Call marked Completed | Status set to showed |
Call marked No Show | Status 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.
*/}
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
In GHL, create a workflow
Set trigger: "Contact Tag Added" or "Custom Field Changed" — or "Event Start Date" conditions built on the SalesCal Call Start Time field
Use the SalesCal status values
Add your automation steps
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
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
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
Verify field mapping is saved
Check field types match
Ensure GHL field exists
Test the specific field
Creating custom fields needs write permission that older connections didn't grant. Disconnect and reconnect GoHighLevel to refresh permissions, then try again.
Review GHL duplicate settings
Check if email matching is enabled
Consider merging duplicates manually
Verify webhook/trigger is active
Check GHL automation is running
Look for GHL error logs
In SalesCal lead records:
GHL Contact ID: Shows if synced
GHL Synced At: Last sync timestamp
Sync Status: Success or error
To remove the connection:
Go to Integrations
Find GoHighLevel
Click Disconnect
Confirm
Note: Existing GHL contacts remain, but new leads won't sync.
Only lead data is sent to GHL
Follows your GHL privacy settings
You control what fields sync
Can disconnect at any time
Map all fields before going live
Test sync with sample leads
Set up automations for each status
Use same field names when possible
Keep custom fields organized
Document your mapping
Check sync status regularly
Address errors promptly
Review automation performance
Automate follow-ups
Create tasks for sales team
Segment leads by status/grade
For more control, use webhooks:
Enable webhook mode in integration settings
SalesCal sends events to your webhook
Your system processes and syncs to GHL
More flexibility for custom logic
Managing Leads - Lead management in SalesCal
Qualification Rules - Status triggers
Lead Grading - Scoring data sync