GoHighLevel calendar
Besides the webhook, SalesControl can read the calendars of your GoHighLevel sub-accounts directly every 5 minutes. This brings into the Agenda the real duration of calls, reschedules and cancellations made in GHL without a workflow, and appointments created before the webhook was set up. To integrate GHL you do one thing only: connect the SalesControl app. No token to create or paste.
The calendar is available from the Starter plan up, like the lead-in webhook; a second sub-account from the Enterprise plan. Connecting the app and the pause on expiry have no plan limits.
Connecting the GoHighLevel app
- In SalesControl: Admin › Integrations › Calendars › GoHighLevel, press Connect with GoHighLevel. You need to be a GHL agency admin.
- GoHighLevel asks which sub-accounts to install the app on: choose all sub-accounts, including future ones. That way a new sub-account is ready when you want to sync it, without going through the consent again. Your clients see the app installed but cannot remove it.
- Confirm: you are back in SalesControl and the GoHighLevel card shows the agency Company ID and the SaaS API result (only needed for the pause on expiry).
If after Connect with GoHighLevel (or Reconnect) GoHighLevel shows you the app’s page instead of the consent request, the app is already installed in your agency and you never get back to SalesControl. Open the ⋮ menu at the top right, choose Uninstall and try again from SalesControl.
From the same card you can Verify the connection, Reconnect the app (for example after installing it on more sub-accounts) and Disconnect it. Disconnecting uninstalls the app from the GHL agency; if calendars are connected through the app or SalesControl has paused sub-accounts, disconnect or resume those first.
Turning on the calendars
With the app connected, the GoHighLevel — Calendar card lists the sub-accounts the app is installed on. Next to the available ones there is Sync: give the sub-account a name (the label you will recognise it by in the card) and, if you work across several markets, its market. SalesControl obtains access to the sub-account on its own, reads the calendars right away and shows them in the row. You can sync up to 10 sub-accounts.
Sub-accounts that belong to one of your clients (those linked to their record) appear in the list marked as “Sub-account of client”: they are not synced as agency calendars. If a sub-account is missing, check in GoHighLevel that the app is installed there and press Refresh.
Several sub-accounts (and markets)
Every synced sub-account has its own row in the card, with the calendars read and the outcome of the last sync. On each row you can Sync now, Pause (it stops being read without losing the connection) and Resume, Edit name and market, or Disconnect: the row disappears and the sub-account access leaves the vault, while appointments already imported stay in the Agenda. The app stays installed on the sub-account in GHL: to sync it again just press Sync.
If your agency works across several markets (Admin › General › Markets, from the Enterprise plan), each sub-account is assigned to one: that is where the colour of its calls in the Agenda comes from. With markets on, the market is required when you sync a new sub-account.
If a sub-account is paused in GoHighLevel, the sync skips that round and resumes on its own when it is active again.
Automatic migration of pasted tokens
Before the app, each sub-account was connected with a Private Integration Token pasted by hand. Those rows keep working and carry the To migrate badge in the card. When you connect the app, SalesControl moves them on its own to the app’s access and discards the old token: name, market and sync history stay as they were. Back from the consent, a notice tells you how many calendars were migrated.
If the app is not installed on one of those sub-accounts, the row keeps its token and the notice says so: install the app on that sub-account in GoHighLevel, then press Reconnect in the GoHighLevel card.
What the sync does
- Reads appointments from yesterday to the next 30 days, for every active calendar of every synced, non-paused sub-account.
- An appointment already present (from the webhook or a previous sync) is updated: time, duration, status, link. An empty link in GHL never erases a saved link; an outcome set by hand in SalesControl (done, no-show) does not fall back to “scheduled”.
- A new appointment is matched to the contact with the same rules as the webhook: GHL contact id, then email, then phone. If no lead or client matches, the lead is created (source “GHL calendario”) without a new-lead notification: notifications stay with the webhook.
- The closer is the assigned GHL user, recognised by their email when it matches a team member’s.
- A cancellation in GHL cancels the call in the Agenda; cancelling a call never seen creates nothing.
- An event deleted in GHL, which therefore disappears from the list, is cancelled in the Agenda too. If a read fails nothing is cancelled: “gone” has to be verified, not assumed.
Each row shows the last sync (events read, new, updated) and any error; Sync now does not wait for the 5 minutes.
When SalesControl writes to GoHighLevel
The sync is inbound: on its own it touches nothing in GHL. But when someone edits, reassigns or cancels an appointment from the Agenda, the change is written to GoHighLevel first and here afterwards — otherwise the sync would put it back within five minutes. If GHL refuses, nothing is saved in SalesControl. The app already has write access to calendar events.
The closer’s GHL user has to belong to that calendar’s team: otherwise GHL refuses the reassignment, and that is fixed in GoHighLevel, not here.
Call outcomes stay local — done, no-show, closer no-show: those never travel to GHL. See Edit, Reassign and Cancel an Appointment.
The pause on expiry
The GoHighLevel — pause on contract expiry card uses the same connection: it pauses the client’s sub-account when the contract expires and resumes it on renewal. The pause uses GHL’s SaaS APIs: verifying the connection tells you whether your plan includes them. The switch turns on only with GoHighLevel connected.
What it does not do
- It does not replace the webhook: the webhook stays the real-time channel and the one that sends new-lead and new-appointment notifications.
- It does not read the events of your clients’ sub-accounts yet: installing on all sub-accounts prepares that step.