Appointment CRUD Setup
Book, read, update, and cancel appointments through the GoHighLevel Calendars API. This guide covers timezone handling, required fields, and the full appointment lifecycle.
Prerequisites
Before you begin, confirm the following:
- A GoHighLevel sub-account with at least one calendar configured
- A Private Integration Token (PIT) with the calendars scope enabled
- Your
locationIdfrom Settings > Business Info - A valid
calendarId(retrieve from GET /calendars) - At least one contact in your CRM to book an appointment for
- A REST client like Postman, Insomnia, or
curlinstalled
Set Up Authentication
Appointment endpoints require a Bearer token with the calendars scope.
- Go to Settings > Integrations > Private Integrations
- Select or create a PIT with calendars scope (read and write)
- Copy the token:
export GHL_TOKEN="your-private-integration-token"
export LOCATION_ID="your-location-id"
Required headers:
Authorization: Bearer $GHL_TOKEN
Content-Type: application/json
Version: 2021-07-28
Make Your First Call
Create an appointment:
curl -X POST "https://services.leadconnectorhq.com/calendars/events/appointments" \
-H "Authorization: Bearer $GHL_TOKEN" \
-H "Content-Type: application/json" \
-H "Version: 2021-07-28" \
-d '{
"calendarId": "your-calendar-id",
"locationId": "'"$LOCATION_ID"'",
"contactId": "your-contact-id",
"startTime": "2026-03-10T10:00:00-05:00",
"endTime": "2026-03-10T10:30:00-05:00",
"title": "Discovery Call",
"appointmentStatus": "confirmed",
"assignedUserId": "team-member-id",
"address": "https://zoom.us/j/123456789",
"ignoreDateRange": false,
"toNotify": true
}'
Key fields: startTime and endTime must include timezone offsets (ISO 8601 format). Set toNotify to true to send confirmation emails. Use ignoreDateRange to bypass availability checks when needed.
Get an appointment:
curl -X GET "https://services.leadconnectorhq.com/calendars/events/appointments/{appointmentId}" \
-H "Authorization: Bearer $GHL_TOKEN" \
-H "Version: 2021-07-28"
Update an appointment:
curl -X PUT "https://services.leadconnectorhq.com/calendars/events/appointments/{appointmentId}" \
-H "Authorization: Bearer $GHL_TOKEN" \
-H "Content-Type: application/json" \
-H "Version: 2021-07-28" \
-d '{
"startTime": "2026-03-10T14:00:00-05:00",
"endTime": "2026-03-10T14:30:00-05:00",
"title": "Rescheduled Discovery Call"
}'
Cancel an appointment:
curl -X DELETE "https://services.leadconnectorhq.com/calendars/events/appointments/{appointmentId}" \
-H "Authorization: Bearer $GHL_TOKEN" \
-H "Version: 2021-07-28"
Handle the Response
A successful POST returns 200 with the appointment object including id, calendarId, contactId, startTime, endTime, appointmentStatus, and notification details.
The appointmentStatus field can be: confirmed, new, showed, noshow, cancelled, or invalid.
A GET returns the full appointment with contact details and assigned user info. A PUT returns the updated object. A DELETE marks the appointment as cancelled.
Important timezone behavior: the API stores times in UTC internally. Always pass ISO 8601 timestamps with timezone offsets (like -05:00 for US Eastern). The response returns times in the same format.
Common errors:
- 401 — Token invalid or expired.
- 404 — Appointment or calendar ID not found.
- 422 — Missing required fields. Minimum:
calendarId,locationId,contactId,startTime,endTime. - 400 — Time slot unavailable. Use the Free Slots endpoint to check availability first, or set
ignoreDateRange: trueto bypass.
Test Your Setup
Confirm your appointment management works:
- Use the Free Slots endpoint to find an available time
- Create an appointment at that time with
toNotify: false(to avoid sending test emails) - Read the appointment by ID and verify all fields
- Update the time by 1 hour and confirm the change
- Check the GHL Calendars dashboard to see the appointment
- Delete the test appointment and verify it shows as cancelled
If the appointment does not appear on the calendar, verify the calendarId is valid and the assignedUserId is a team member on that calendar.
Next Steps
Read the full Appointment CRUD guide for bulk booking patterns and rescheduling workflows. Use Free Slots to check availability before booking, or add context with Appointment Notes.