API Changelog
A log of notable changes to the SavvyCal Appointments API.
May 18, 2026
- Changed: -- The
X-SavvyCal-Accountheader is no longer listed as a parameter on individual operations in the OpenAPI spec or API reference; it's now documented once on the Platforms and Authentication pages. The header is unchanged at the protocol level — it is still required when authenticating with a platform token to specify the target account. - New: -- The Create Provider and Update Provider endpoints now accept an optional
time_zonefield for setting the provider's preferred IANA time zone. When omitted on create, it defaults to the account location's time zone. See CreateProviderRequest and UpdateProviderRequest.
May 16, 2026
- Changed: -- The
start_dateandend_datefields on Block, CreateBlockRequest, and UpdateBlockRequest have been consolidated into a singledatefield. The List Blocks endpoint'sstart_date,end_date,start_date_min,start_date_max,end_date_min, andend_date_maxquery parameters have likewise been replaced withdate,date_min, anddate_max, and results are now sorted bydate.
May 15, 2026
- New: -- Provider and AppointmentProvider responses now include a
time_zonefield — the provider's preferred IANA time zone, used as the default when authoring schedules. - New: -- Provider schedules now have a
time_zonefield. ProviderSchedule responses include the IANA time zone the schedule's weekly rules are authored in, and the Create Provider Schedule and Update Provider Schedule endpoints accept an optionaltime_zoneto declare it; when omitted, it defaults to the provider's time zone.
May 12, 2026
- New: -- AppointmentMeeting now includes a
host_urlfield — a proxy URL on the account's booking domain that the meeting host follows to start the meeting. SavvyCal refreshes the underlying conferencing-provider URL behind the proxy transparently, so the proxy URL is generally stable acrossappointment.meeting.updatedevents, though it may change if SavvyCal rotates the underlying token. It always changes when the meeting is replaced (e.g. a reschedule routes the appointment to a different host on the account, producing a brand-new meeting with a newid). Treat as a credential — anyone with this URL can start the meeting as host. Valid through the appointment's end time + a 24h grace window, then returns 410 Gone. Listen forappointment.meeting.updatedandappointment.meeting.replacedto keep stored copies fresh.nullwhen the meeting is not yetcreatedor when the conferencing provider has no distinct host start URL (e.g., Google Meet). - New: --
client_dataon Appointment and BookingIntent now includes afieldsmap containing custom client field values, keyed by field slug. Values for fields flagged as sensitive are redacted unlessinclude_sensitiveistrue. - Changed: -- The
client_datainput on appointment and booking intent endpoints is now exposed as named, reusable schemas: AppointmentClientDataInput (used by CreateAppointmentRequest and CreatePublicAppointmentRequest) and ClientDataInput (used by booking intent create/update requests). Shapes are unchanged; thefieldsdescription has been tightened to clarify that each key must correspond to a Client Field defined in the account — arbitrary key-value pairs are not accepted.
May 7, 2026
- New: -- Appointment and PublicAppointment now expose individual top-level URL fields. Appointment exposes
add_to_calendar_url,cancel_url,confirm_url,ics_url,join_url, andreschedule_url. PublicAppointment exposesadd_to_calendar_url,cancel_url,ics_url, andreschedule_url. Each is a single canonical URL string that resolves to the account's active custom domain when configured. There is no top-level replacement forurls.add_to_google_calendar; useadd_to_calendar_urlinstead. - Deprecated: -- The
urlsobject on Appointment and PublicAppointment is deprecated in favor of the new top-level URL fields and will be removed in a future release.
April 30, 2026
- New: -- Added two endpoints for listing time slots based on a booking intent's configuration: List available slots for a booking intent (authenticated) and List available slots for a booking intent (public). Both return the new SlotListResponse schema.
- New: -- Appointment responses now include a
meetingfield with conferencing details (provider, join URL, password, etc.) and an asynchronous lifecycle status. See AppointmentMeeting. - New: -- Added webhook events for the appointment meeting lifecycle:
appointment.meeting.created,appointment.meeting.updated,appointment.meeting.canceled, andappointment.meeting.replaced, plus terminal-failure eventsappointment.meeting.create_failed,appointment.meeting.update_failed,appointment.meeting.cancel_failed, andappointment.meeting.replace_failed. See AppointmentMeetingCreatedEventData, AppointmentMeetingUpdatedEventData, AppointmentMeetingCanceledEventData, AppointmentMeetingReplacedEventData, AppointmentMeetingCreateFailedEventData, AppointmentMeetingUpdateFailedEventData, AppointmentMeetingCancelFailedEventData, and AppointmentMeetingReplaceFailedEventData. - New: -- Booking intents now support secondary providers via a
secondary_providersfield on CreateBookingIntentRequest, UpdateBookingIntentRequest, and BookingIntent. - New: -- Appointment responses now include a
providersarray containing each assigned provider with their role (primaryorsecondary). See AppointmentProvider. - New: -- Dashboard sessions now support an
idle_timeout_minutesfield for configuring the inactivity period before re-authentication is required. See Create Dashboard Session. - Changed: -- The
sourcefield on ConfirmationEvent and RescheduleEvent now includes apublic_apivalue to distinguish events initiated through the public API. - Changed: -- The
PublicServiceSlotsResponseschema has been renamed to SlotListResponse and is now used by both authenticated and public slot listing endpoints. The response shape is unchanged.
March 25, 2026
- New: -- Booking intents now include
requirementsandworkflowfields. Requirements provides per-section completeness status for booking, info, and form submission steps. Workflow provides server-computed step routing, completability, and defunct state. See BookingIntentRequirements, BookingIntentWorkflow, and SubmissionRequirement. - Changed: -- The
locked_fieldsfield on BookingIntent, PublicBookingIntent, and related request schemas is now a typed enum array instead of a freeform string array. - Changed: -- The
locked_fieldsenum valuesstart_at,end_at, andtime_zonehave been consolidated into a singleslotvalue on BookingIntent, PublicBookingIntent, and related request schemas.
March 23, 2026
- New: -- Added a BookingIntentBookingPolicy schema representing hold policy overrides applied to a booking intent.
- Changed: -- The
hold_durationandhold_enabledfields on BookingIntent, CreateBookingIntentRequest, and UpdateBookingIntentRequest have been replaced with a nestedbooking_policyobject. Hold settings are now atbooking_policy.hold.durationandbooking_policy.hold.enabled.
March 21, 2026
- New: -- Booking intents now include a
submissionsfield for attaching form responses during the booking flow. See BookingIntent and IntentSubmissionInput. - New: -- The Get Client and List Clients endpoints now support an
include_sensitivequery parameter for controlling whether sensitive fields (name, email, phone) are included in the response. - New: -- Booking intents now include an
errorsfield containing validation errors in JSON:API format. See BookingIntent and JsonError. - New: -- Added a JsonError schema representing a single validation error object.
March 20, 2026
- New: Forms -- Added endpoints for managing intake forms with typed fields: Create Form, Get Form, List Forms, Update Form, and Delete Form. See Form.
- New: Client Fields -- Added endpoints for managing custom client fields: Create Client Field, Get Client Field, List Client Fields, Update Client Field, and Delete Client Field. See ClientField.
- New: Service Forms -- Added endpoints for attaching forms to services: Attach Service Form, List Service Forms, Sort Service Forms, and Detach Service Form. See ServiceForm.
- New: -- Services now include a
formsfield containing attached intake forms. See Service.
March 10, 2026
- Removed: -- The deprecated
client_locale,client_reference_id,client_time_zone, andfieldsproperties have been removed from the Appointment schema. Useclient_datainstead.
March 5, 2026
- New: -- Clients and services now support a
metadatafield for storing custom key-value pairs (maximum 16 KB). See Client and Service. - New: -- The List Clients and List Services endpoints now support filtering by
metadatausing bracket notation. - New: -- Added a ForbiddenResponse schema and 403 status code to the List Appointments endpoint.
March 2, 2026
- New: -- Services now include an optional
internal_namefield for setting an internal admin label. When set, this name is displayed in the admin UI instead of the public name. See Service.
March 1, 2026
- New: -- Services now include a
provider_notificationsfield for configuring staff email notification settings, including which notification types are enabled and additional recipients. See ProviderNotificationConfig and ProviderNotificationType.
February 27, 2026
- New: -- PublicAppointment now includes a
urlsfield containing client-facing action URLs for rescheduling, canceling, adding to calendar, downloading ICS files, and adding to Google Calendar.
February 26, 2026
- New: -- Error responses now include an optional
codefield containing a machine-readable error code (e.g.slot_unavailable,no_available_provider). See GenericErrorResponse and JsonErrorResponse.
February 25, 2026
- Changed: -- The
fromanduntilquery parameters on the List available time slots and List public time slots endpoints are now optional.fromdefaults to today if not provided. Eitheruntilorlimitmust be provided. - New: -- Added a
limitquery parameter to the List available time slots and List public time slots endpoints as an alternative tountilfor controlling the number of aggregated slots returned. - New: -- Added webhook events for booking intents:
booking_intent.created,booking_intent.updated,booking_intent.completed, andbooking_intent.abandoned. See Webhooks. - New: -- Booking intent endpoints now accept an
auto_assign_providerflag. Whentrue, an available provider is automatically assigned for the selected time slot if noprovider_idis specified. Supported on create, update, and complete operations for both authenticated and public booking intents.
February 24, 2026
- New: Booking Intents -- Added 6 authenticated endpoints under
/v1/booking_intentsand 5 public endpoints under/v1/public/booking_intentsfor managing multi-step booking flows with time slot holding. See Booking Intents and Public Booking Intents. - New: Hold Policy -- Services now include a
holdfield withinbooking_policyfor configuring time slot holds during the booking flow. See HoldPolicy and BookingPolicy. - New: Booking Intent schemas -- Added BookingIntent, PublicBookingIntent, HoldPolicy, and related request/response types.