A lead picks a 2:00 PM slot on your HighLevel calendar, but the confirmation email says 11:00 AM, and the event syncs to Google Calendar as 7:00 PM UTC. This exact bug cost an agency client of mine six missed sales calls in 48 hours.
Timezone drift in GoHighLevel isn’t random. It happens because HighLevel evaluates time across four distinct layers: the sub-account business profile, the assigned user profile, the individual calendar configuration, and the lead’s browser environment. If any of those four layers disagree or pass an unformatted offset, your booking slots shift by hours or vanish entirely.
Here is how to isolate where the offset happens and lock down your calendar settings so every appointment lands at the right time.

The 4-Layer Timezone Hierarchy in GoHighLevel
HighLevel determines slot availability by stacking timezones from the top level down to the browser. When an appointment lands at the wrong time, one of these four layers has a conflicting IANA timezone string:
- Layer 1: Sub-Account Business Profile (Settings > Business Profile). Sets the default fallback timezone for workflows, reporting, and newly created calendars.
- Layer 2: User Profile (Settings > My Staff > Edit User > User Availability). Dictates the actual working hours of the assigned team member.
- Layer 3: Calendar Settings (Calendars > Calendar Settings > Edit). Controls slot intervals, buffer times, and whether the calendar locks to a fixed timezone or lets the visitor switch it.
- Layer 4: Contact / Browser Environment. The client’s local browser timezone detected via JavaScript via the
Intl.DateTimeFormatAPI.
If your Sub-Account is set to America/New_York (EDT), your sales rep’s user profile is set to America/Chicago (CDT), and the calendar widget has “Auto-detect timezone” turned off, your calendar will calculate availability using New York time while displaying slots in Chicago time. That immediately introduces a 1-hour offset error.
If you also encounter days where no slots render at all, verify our companion guide on how to fix GoHighLevel calendars not showing available slots before tweaking timezone logic.
Diagnosing the Slot Offset in the Browser
Before changing calendar settings, check the raw network payload returned by HighLevel’s booking engine. This will show you whether the bad timestamp originates on the client side or the server side.
- Open your calendar booking page in an Incognito/Private window.
- Open Chrome DevTools (press
F12) and click the Network tab. - Filter network requests by
free-slots. - Click a date on your calendar to trigger the API call.
Inspect the JSON response payload. You’ll see an array of available slots returned by the HighLevel backend:
{ "dates": { "2025-04-15": { "slots": [ "2025-04-15T14:00:00-04:00", "2025-04-15T14:30:00-04:00", "2025-04-15T15:00:00-04:00" ] } }, "timezone": "America/New_York"
}Check two properties in that response:
- The timezone key at the root of the JSON object.
- The ISO-8601 offset string at the end of each timestamp (for example,
-04:00for EDT or+00:00for UTC).
If the timezone key shows UTC but your calendar is supposed to operate in Eastern Time, your calendar configuration is missing an explicit location timezone and is defaulting to raw server time.
Fix 1: Lock the Calendar Timezone vs Auto-Detect Settings
HighLevel provides two options for visitor timezone handling inside every calendar: Auto-Detect and Locked Timezone.
For national or international sales funnels, you want Auto-Detect enabled so leads see slots in their local time. For local brick-and-mortar businesses (like dental clinics, med spas, or auto repair shops), you must Lock the timezone to the business’s physical location.
- Navigate to Calendars > Calendar Settings.
- Click the three dots next to your calendar and select Edit.
- Go to the Customizations or Forms & Payment tab (depending on whether you are using the Classic or New Calendar Builder).
- Locate the Timezone Detection toggle.
- For local businesses: Set the timezone explicitly to your local IANA Time Zone identifier and disable the visitor timezone dropdown.
- For remote sales teams: Enable visitor auto-detection, but verify the base calendar timezone matches the primary sub-account location.
If you have multiple staff members sharing appointments, you should also review your team calendar sync and availability settings to prevent one rep’s offset from skewing the entire pool.
Fix 2: Align Assigned User Availability and External Calendar Timezones
A frequent cause of slot shifts in Round Robin and Simple Calendars is a mismatch between the HighLevel user profile and their connected Google or Outlook calendar.
Here is what happens behind the scenes: when HighLevel queries Google Calendar via the Google Calendar API, Google returns busy blocks formatted in UTC. HighLevel translates those busy blocks against the user’s HighLevel profile timezone.
If John’s Google Calendar is set to America/Los_Angeles (UTC-7) but his HighLevel staff profile is set to America/New_York (UTC-4), HighLevel will block out 3 hours in the middle of his afternoon when his Google calendar actually had an 11:00 AM meeting.
To align them:
- Go to Settings > My Staff in HighLevel.
- Click Edit on the assigned user.
- Expand User Availability.
- Verify the Time Zone dropdown matches the primary timezone configured inside their Google Calendar (Google Calendar Settings > Time Zone > Primary Time Zone) or Microsoft 365 profile.
- Save the user profile.
If you’re using two-way sync for team distribution, make sure you followed our guide on GoHighLevel Round Robin Google Calendar two-way sync so calendar read/write permissions don’t drop during timezone calculations.
Fix 3: Fix Workflow Confirmation Emails Showing UTC or Wrong Offsets
You fix the calendar booking widget, the meeting books at the right time, but the confirmation email sent to the lead states the appointment is at 2025-04-15 18:00:00 UTC. This happens because default HighLevel merge tags sometimes pull unformatted raw timestamps.
Standard merge tags like {{ appointment.start_time }} output the start time formatted according to the sub-account’s default business timezone, NOT the lead’s local timezone unless explicitly configured.
To format appointment dates accurately across timezones in automated emails and SMS notifications:
- Go to Automation > Workflows and open your Appointment Confirmation workflow.
- Click the action sending the email or SMS.
- Do not rely on naked date strings. Use HighLevel’s native appointment format tags:
Recommended merge tag combinations for emails:
{{ appointment.only_start_date }}— Prints the date (e.g., April 15, 2025).{{ appointment.only_start_time }}— Prints the time in the sub-account’s configured timezone (e.g., 2:00 PM).{{ appointment.start_time }}— Prints the full timestamp with timezone name.
If you need custom formatting with fallback values for contacts where timezone data failed to capture, see our breakdown on GoHighLevel merge fields and fallback values in workflows.
Fix 4: Handling Timezones in Custom API v2 Bookings
If you create or reschedule appointments programmatically using the HighLevel API v2, passing a bare UTC string (with Z) without the contact’s target timezone identifier will force HighLevel to default the appointment to the location’s root timezone.
Here is a Node.js snippet showing how to construct an appointment booking payload with an explicit IANA timezone and ISO-8601 offset:
import axios from 'axios';
async function bookHighLevelAppointment(calendarId, contactId, locationId, startTime, timeZone) { const payload = { calendarId: calendarId, locationId: locationId, contactId: contactId, startTime: startTime, // e.g., '2025-04-15T14:00:00-04:00' endTime: '2025-04-15T14:30:00-04:00', title: 'Strategy Consultation', appointmentStatus: 'confirmed', assignedUserId: 'USER_ID_HERE', toNotify: true, // Explicitly declare the timezone to avoid sub-account fallback timezone: timeZone // e.g., 'America/New_York' }; try { const response = await axios.post( 'https://services.leadconnectorhq.com/calendars/events/appointments', payload,
{ headers: { 'Authorization': `Bearer ${process.env.GHL_ACCESS_TOKEN}`, 'Version': '2021-07-28', 'Content-Type': 'application/json' } } ); return response.data; } catch (error) { console.error('Booking failed:', error.response?.data || error.message); throw error; }
}Always pass the explicit timezone field in the request body alongside the ISO offset inside startTime. This ensures that HighLevel’s internal scheduler triggers the workflow notifications with the exact timezone context the client expects.
Fix 5: Iframe Embed and Website Timezone Inheritance
When embedding HighLevel calendar widgets into external websites (WordPress, Webflow, Shopify, or custom React apps), browser security sandboxes or aggressive caching plugins can block the widget’s timezone detection script.
If you notice visitors on your external site booking slots with a 3-hour shift, check the embed code snippet.
Make sure your calendar iframe code includes the data-auto-height and standard script loader provided by HighLevel:
If the iframe is embedded inside an environment with strict Content Security Policy (CSP) headers, the script might fail to read Intl.DateTimeFormat().resolvedOptions().timeZone from the host window. In that case, the widget defaults to the calendar’s root timezone. Test your page in multiple browsers (Safari on iOS is notorious for blocking third-party iframe timezone lookups if cross-site tracking prevention is strictly enforced).
Frequently Asked Questions
Why does my calendar show available slots at 3:00 AM?
This happens when a user’s working hours are configured in one timezone (e.g., 9 AM to 5 PM in Asia/Kolkata), but the calendar’s base timezone is set to America/New_York without auto-detection enabled. The calendar translates the user’s daytime hours directly into the visitor’s overnight window.
How does Daylight Saving Time (DST) affect my HighLevel calendars?
HighLevel relies on standard IANA timezone database strings (like America/New_York or Europe/London) rather than fixed GMT/UTC offsets (like GMT-5). When DST shifts in March and November, HighLevel automatically adjusts slot offsets—provided you used an IANA location name instead of a static offset in your sub-account settings.
Can I force the calendar to display in the visitor’s timezone while keeping confirmation emails in the business timezone?
Yes. Leave visitor auto-detection enabled on the calendar customization tab. In your workflow confirmation emails, reference the {{ appointment.only_start_time }} merge tag alongside your business timezone text (e.g., “{{ appointment.only_start_time }} EST”), or use custom webhook formatting if you want to display both the lead’s local time and your team’s local time side by side.
Why did a slot book successfully despite conflicting with a Google Calendar event?
Check the “All Day” setting on the Google Calendar event. HighLevel occasionally treats all-day events as free unless they are explicitly set to “Busy” in Google Calendar settings. Additionally, verify that two-way sync is enabled under Settings > Integrations > Google for that specific user.
Next Steps
Audit your sub-account business timezone first, then verify the individual staff availability timezones for all reps assigned to your calendars. If your team uses round-robin routing across multiple timezones, test your setup with our diagnostic guide on fixing HighLevel team calendar sync and availability conflicts.

