Testing writes, per system
Which health record systems take each write, what the API does on the others, and how you know a write landed.
Your Open Dental sandbox takes every write the API makes, so you can test all of them there. Live practices run 15 systems, and not every system takes every write. Before you ship, know which writes work on each practice's system.
How to read the tables
Every write can land in two places: NexHealth, and the practice's health record system. Each table shows both.
- Saved in NexHealth means the API returns
2xxand the NexHealth record changes. - Written to the health record system means NexHealth queues the change for the practice's sync and it lands on the next cycle, usually within minutes. See How a write reaches the health record system. On a system the column does not list, the write stays in NexHealth and the practice does not see it.
400means the API rejects the call. Nothing is saved anywhere.- To learn which system a practice runs, call
GET /sync_status; each sync returns anemrobject with adisplay_name. On v3.1.0 (beta),GET /locations/{id}returns it asehr.
Appointments
Every PATCH /appointments write is confirmed the same way: when the command finishes, appointment_updated fires on success, or appointment_updated.failed, .timed_out or .incomplete otherwise, with previous_attributes showing the field you changed.
| API call | Saved in NexHealth | Written to the health record system on | Webhook that confirms it |
|---|---|---|---|
POST /appointments | Yes | Every system, once the location has insert_appt_client: true. Until then the appointment stays in NexHealth. | appointment_insertion: complete, or failed, timed_out or incomplete. On complete the appointment's foreign_id is set. |
PATCH /appointments with cancelled: true | Yes | athenahealth, Cloud9, Curve Hero, Denticon, Dentrix, Dentrix Ascend, Dentrix Enterprise, Dolphin, Eaglesoft, eClinicalWorks, ModMed, NextGen Office, Open Dental | appointment_updated |
PATCH /appointments with confirmed: true | Yes | Every system | appointment_updated |
PATCH /appointments with checkin_at | Yes | Denticon, Dentrix, Dentrix Enterprise, Eaglesoft, ModMed, NextGen Office, Open Dental | appointment_updated |
PATCH /appointments with start_time and end_time, operatory_id or note | Only on the systems in the next column. operatory_id alone: yes on every system. A time or note change on any other system: 400 EMR does not support appointment update, nothing saved. | Denticon, Dentrix, Dentrix Enterprise, Eaglesoft, Open Dental | appointment_updated |
Two more rules on live practices:
PATCH /appointmentsworks once the appointment has reached the system (foreign_idset). Before that, onlycancelled: trueis accepted, so you can free the slot when an insertion fails. Anything else returns400Cannot update appointment because it is not synced with the PMS and/or a live client.- A cancelled appointment or a scheduling block cannot be updated.
Patients
| API call | Saved in NexHealth | Written to the health record system on | Webhook that confirms it |
|---|---|---|---|
POST /patients | Yes | No system on v3.0.0. The patient reaches the system when you book their first appointment. | None on v3.0.0. The patient's foreign_id stays null until an appointment lands. |
POST /appointments for a patient with no foreign_id | Yes | athenahealth, Cloud9, Denticon, Dentrix, Dentrix Ascend, Dentrix Enterprise, Eaglesoft, eClinicalWorks, ModMed, NextGen Office, Open Dental, OrthoTrac. The patient is created in the system as part of the booking. Curve Hero, Dolphin and PracticeWorks cannot take a new patient from the API, so book with a patient the system already has. | appointment_insertion. The patient's foreign_id is set when it lands. |
PATCH /patients | Yes | No system on v3.0.0 | None on v3.0.0 |
On v3.1.0 (beta), POST /patients sends the patient straight to Denticon, Dentrix, Eaglesoft and Open Dental and fires patient_insertion; PATCH /patients sends the change and fires patient_update.
Payments and adjustments
| API call | Saved in NexHealth | Written to the health record system on | Webhook that confirms it |
|---|---|---|---|
POST /payments | Not directly. The API returns 202 on every system, and the record appears on GET /payments once the sync reads it back from the ledger. | Dentrix, Dentrix Enterprise, Eaglesoft, Open Dental, where the practice has ledger sync. On any other system the payment never reaches the ledger. | payment_insertion: complete, or failed, timed_out or incomplete |
POST /adjustments | The same, on GET /adjustments | The same four | adjustment_insertion, same suffixes |
Both calls return 202 with an empty body.
Documents
POST /patients/{id}/documents reaches the system only where document insertion is turned on for it: Curve Hero, Denticon, Dentrix, Dentrix Ascend, Dentrix Enterprise, Eaglesoft and Open Dental. For athenahealth, eClinicalWorks and OrthoTrac, ask developer support. Elsewhere the document stays in NexHealth. document_insertion fires with complete, or failed, timed_out or incomplete.
v3.1.0 (beta) only
Sandbox keys can call v3.1.0; production keys need access for your organization. See Versioning.
POST /insurance_plans,POST /insurance_coveragesandDELETE /insurance_coverages/{id}are sent to Dentrix, Eaglesoft and Open Dental. Elsewhere the API accepts the call and the change stays in NexHealth.insurance_plan_insertion,insurance_coverage_insertionandinsurance_coverage_deletedtell you whether it landed: the suffix onevent_nameis.complete,.failedor.timed_out.POST /communication_logsis Open Dental only, and the endpoints are turned on per organization (sandbox keys included). Other systems return422.
What this means for your sandbox
Every row that names Open Dental works on your Open Dental sandbox, so you can test each write end to end there. The demo practice has no sync behind it: bookings are accepted and never land, and PATCH /appointments returns 400 for anything but a cancel. See Sandbox and test mode.
Updated 6 days ago