Contact sync: Every prospect becomes or updates a HubSpot Contact
Meeting records: Bookings appear as HubSpot Meetings linked to the contact
Notes: Form answers and disqualification reasons attach as Notes
Stage tracking: SalesCal lifecycle stages flow into HubSpot's lifecyclestage and hs_lead_status properties
Auto field mapping: Match SalesCal form fields to HubSpot properties in one click, with missing fields created automatically
HubSpot shares the unified CRM Integration page with our other CRMs (only one CRM can be connected per team at a time).
Go to Settings > Integrations
Open CRM Integration
Pick HubSpot from the CRM provider dropdown
Click Connect
HubSpot's OAuth screen opens — pick the account/portal you want to connect and click Authorize
You're returned to SalesCal on the Configuration tab, ready to set up field mapping
SalesCal requests these HubSpot scopes:
Scope | Purpose |
| Look up existing contacts by email |
| Create and update contacts |
| List the contact properties you already have |
| Auto-create missing custom properties when mapping fields |
These scopes cover Contacts only. SalesCal does not touch Companies, Deals, or Tickets — if you need a deal created when a meeting books, set up a HubSpot workflow that watches the contact properties SalesCal updates.
HubSpot has no separate "Lead" object — everything is a Contact, and "lead-ness" is a value on the lifecyclestage or hs_lead_status property. SalesCal mirrors this: each prospect upserts a Contact (matched by email) and SalesCal lifecycle changes update the property values, not separate records.
Open the Configuration tab to control how SalesCal fields land in HubSpot.
Click Auto-map Now and SalesCal will:
Match SalesCal fields to HubSpot properties by label
Create a property group called "SalesCal Information" in HubSpot to hold any new properties
Create a salescal_source boolean property so you can filter HubSpot for SalesCal-synced contacts
Set sensible defaults for status mapping (e.g. "potential" → hs_lead_status: NEW + lifecyclestage: lead)
Turn on Auto-map new fields and any new form field you add later will auto-create in HubSpot on first sync. Leave it off if you'd rather review each new field manually.
The Field Mapping card lets you pick the HubSpot property for each SalesCal field:
Contact fields: first_name, last_name, email, phone — these are always synced as the contact's core identity
System fields: event_name, location, host_email, host_name, start_time, booking_status, outcome, outcome_reason
Form fields: every custom field you've added to your booking forms
Click the + next to any field to create a new HubSpot property without leaving SalesCal. Auto-created fields are text or number only — for dropdowns or date fields, create them in HubSpot first then map them in SalesCal.
HubSpot has two status-like properties; SalesCal lets you map to either or both:
Lifecycle Stage (lifecyclestage) — HubSpot's fixed pipeline: subscriber, lead, MQL, SQL, opportunity, customer, evangelist, other
Lead Status (hs_lead_status) — your custom values
For each SalesCal stage (e.g. potential, qualified, booked, completed), you can pick a value for one or both fields.
The Connection tab has global toggles for each sync trigger. All are on by default:
Toggle | Fires when |
Form started | Prospect enters name + contact info |
Form completed | Prospect submits the booking form |
Booking created | A meeting time is confirmed |
Booking cancelled | The booking is cancelled |
Booking rescheduled | The booking moves to a new time |
Outcome recorded | You mark the meeting completed, no-show, won, or lost |
Contact info changed | Prospect details update on an existing lead |
These are team-wide — they apply to every event you publish under this team. There's no per-event toggle.
Email is the dedup key. SalesCal looks up the contact by email and updates it; new prospects without an email will not sync.
Notes are HTML. SalesCal converts newlines to <br> so multi-line answers render correctly in HubSpot.
Meetings have outcomes. SalesCal sets hs_meeting_outcome from the SalesCal outcome you record (Completed, No-show, etc.), so you can filter HubSpot meetings by result.
Form-started has an 180s delay. SalesCal waits ~3 minutes before syncing "Form started" to avoid creating duplicate contacts when a prospect re-enters the form.
Make sure you have admin access to the HubSpot portal you're trying to connect. SalesCal needs to install OAuth scopes that require admin permissions on the portal.
Check the Sync Log tab. The most common reasons:
Prospect didn't supply an email
HubSpot rate-limited us (free tier: 5 req/s) — retry from the log
A custom property you mapped no longer exists in HubSpot (rename or recreate it, then re-sync)
HubSpot only allows lifecycle stage to move "forward" on the default pipeline. If you have stage-progression rules in HubSpot, our update may be silently ignored. Switch to hs_lead_status instead, or remove the HubSpot-side restriction.
By design — SalesCal does not create Deals. Set up a HubSpot workflow triggered by salescal_source = true (or by hs_lead_status changing) to create the Deal in your pipeline.
Go to Settings > Integrations > CRM Integration
Open the Connection tab and click Disconnect
The contacts and meetings already synced stay in HubSpot. SalesCal stops sending updates and clears the stored OAuth tokens.
OAuth tokens are stored encrypted and refresh automatically
SalesCal only sends data to HubSpot in this direction — HubSpot edits do not sync back into SalesCal
The salescal_source property gives you an easy filter for any SalesCal-managed contacts if you need to bulk-export or delete them
The OAuth scopes SalesCal uses (crm.objects.contacts.*, crm.schemas.contacts.*) are available on every HubSpot tier including Free CRM. Free-tier portals have lower API limits (5 req/s vs. 100+ on paid plans), so very high booking volume may need a paid plan to avoid retries.
GoHighLevel CRM Integration — the same unified CRM page, different provider
Qualification Rules — controls which SalesCal stage maps to which HubSpot value
Custom Form Fields — the form fields you'll be mapping to HubSpot properties