August 2026
What's New
This release adds Provider and WorkingHour webhook events, includes booking details in appointment_created webhooks, reworks how v3.1 patient phone numbers are written and returned, and removes last_sync_time from several v3.1 responses.
Added
-
[v3.1] New
provider_createdandprovider_updatedwebhook events, subscribable under theProviderresource type. -
[v3.1] New
working_hour_createdandworking_hour_updatedwebhook events, subscribable under theWorkingHourresource type. -
[v3.1]
appointment_createdwebhook payloads (for subscriptions pinned tov3.1.0) now include:booking_details— context about how the appointment was booked online:booked_via_nexhealth_generated_link,campaign_type,campaign_id,campaign_medium,booked_via_one_click. This isnullwhen the appointment wasn't booked through NexHealth online booking.- A
patientobject, which containsguarantor_idonly (not a nested guarantor).
-
[v3.1] Patient responses now include two new fields:
cell_phone_numberpreferred_phone_number(read-only) — the best-known number, in priority order: the integrated system's untyped primary number, then cell, home, and work numbers.cell_phone_numberfalls back to that same untyped primary number when the integrated system doesn't report a distinct typed cell number.- Note: the previous untyped
phone_numberfield is no longer present on patient responses (provider responses are unaffected).
-
[v3.1]
ssnis now included in patient responses (previously write-only) — but only on single-patient responses (create, update, and fetch-by-id). It does not appear in patient list responses or in patient objects embedded in other resources (e.g., an appointment'spatient). -
[v3.1]
GET /locations/:idresponses now include anehrfield describing the EHR the location syncs with.
Changed
-
[v3.1]
POST /patients/PATCH /patientsrequest shape:- Phone number and other demographic fields now live at the root of the
patientobject (previously nested underbio). - Address fields move into a new nested
addressobject —line_1,line_2,city,region,postal_code— instead of separatebiokeys.
- Phone number and other demographic fields now live at the root of the
-
[v3.1]
POST /patientsnow requires at least one non-blank phone number (cell_phone_number,home_phone_number, orwork_phone_number). On bothPOSTandPATCH, phone number fields can no longer be set to a blank value. -
[v3.1]
POST /patientsonly enqueues insertion into the EHR when the connected EHR supports creating patients directly (currently Denticon, Dentrix, Eaglesoft, and Open Dental). For other EHRs, the responsedescriptionnow explains that the patient will be added when an appointment is booked for them. -
[v3.1]
PATCH /patients/:idno longer returns422("Patient has not been synced to the EHR") in two cases:- For a patient at a location with no connected EHR — such a patient can never receive a
foreign_id, so this update was previously never possible at all. - When the patient's EHR insert is merely still in progress — the update is now accepted and applied once the insert completes.
- For a patient at a location with no connected EHR — such a patient can never receive a
-
[v3.1]
GET /payment_plans/:idwithinclude=patientorinclude=guarantor:- Now nests the patient/guarantor object in v3.1's patient shape (no
biowrapper; includescell_phone_number/preferred_phone_number) instead of the v2 shape it previously received. - The
location_idsandpreferred_localefields, previously available on that nested object, are no longer present.
- Now nests the patient/guarantor object in v3.1's patient shape (no
-
[v3.1]
GET /available_slots:- Now respects an explicitly-provided
slot_intervaleven when the location hasbook_on_minutesconfigured. Previously,book_on_minutesalways forced a fixed 5-minute step between candidate slots, regardless of anyslot_intervalpassed. slot_intervalmust now be a positive integer.
- Now respects an explicitly-provided
-
[v3.0, v3.1]
POST /paymentsno longer always rejects a payment with400 Bad Requestfor a patient that hasn't finished syncing to the EHR. If a patient-insert sync is already in flight, the request now returns202 Accepted(empty body), and the payment syncs to the EHR once the patient insert completes. -
[v2, v3.0]
GET /locationsandGET /locations/:idnow exclude locations that are still in onboarding; requesting one directly by id returns404 Not Found. -
[v3.1]
GET /locations(list) also excludes onboarding locations.GET /locations/:iddoes not — an onboarding location can still be fetched directly by id. -
NexHealth no longer supports server operating systems prior to Windows 10. To maintain compatibility with the NexHealth Synchronizer, servers running legacy operating systems must be upgraded to Windows 10 or higher.
Fixed
-
[v3.1]
GET /appointment_categoriesandGET /appointment_categories/:idnow actually return theoperatoriesfield wheninclude=operatoriesis passed — previously the parameter was accepted and used internally, but the field was never exposed in the response. -
[v3.1] The
operatory_idsfilter on theavailable_slotsendpoint no longer silently falls back to returning slots for every operatory when the filter matches none; it now correctly returns no slots. -
[v2]
POST /webhook_endpointsandPATCH /webhook_endpoints/:idnow return the correctdescriptionmessage ("New endpoint created successfully" / "Endpoint updated successfully") in the response — a parameter-name typo previously caused a generic fallback message to be returned instead.
Removed
-
[v3.1]
last_sync_timehas been removed from responses for:- appointment
- EHR appointment descriptor
- provider
- patient
- location
- operatory
-
[v3.1]
POST /patientsandPATCH /patientsno longer accept the following fields (all previously available under the nestedbioobject):street_addresscustom_contact_numberdrivers_licensefaxheightinsurance_namemarital_statuspreferred_nameracesalutationweightphone_number(untyped) — superseded by the typedcell_phone_number/home_phone_number/work_phone_numberfields described above.