npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rinse-dental/open-dental

v4.1.0

Published

A TypeScript library for easily accessing Open Dental APIs.

Downloads

309

Readme

@rinse-dental/open-dental

An unofficial TypeScript/Node.js SDK for the Open Dental REST API.

Open Dental version coverage: This release is synchronized with Open Dental v26.1.12 (beta) and covers every API endpoint documented as of that version.


Installation

npm install @rinse-dental/open-dental

Quick Start

import { OpenDental } from '@rinse-dental/open-dental';

// Initialize once at application startup (the SDK appends /api/v1 automatically)
OpenDental.initialize(
  'https://your-open-dental-server.example.com', // base URL — no trailing slash
  'YOUR_API_TOKEN',                              // Base64 "ODFHIR {DeveloperKey}/{CustomerKey}" token
);

// Use any resource
const patients = OpenDental.Patients();
const results = await patients.getPatients({ LName: 'Smith' });
console.log(results);

Initialization

OpenDental.initialize(baseURL, authToken, options?) must be called once before any other method. All subsequent calls reuse the same HTTP client.

| Parameter | Type | Required | Description | |--------------------|---------|----------|----------------------------------------------------------| | baseURL | string | Yes | Root URL of your Open Dental server (no trailing slash). | | authToken | string | Yes | Base64-encoded ODFHIR {DeveloperKey}/{CustomerKey} API token. | | options.timeout | number | No | Request timeout in milliseconds. Default: 30000. | | options.debug | boolean | No | Log HTTP errors to console (strips PHI). Default: false. |

// Minimal
OpenDental.initialize(
  process.env.OPEN_DENTAL_BASEURL!,
  process.env.OPEN_DENTAL_API_KEY!
);

// With options
OpenDental.initialize(
  process.env.OPEN_DENTAL_BASEURL!,
  process.env.OPEN_DENTAL_API_KEY!,
  {
    timeout: 15_000, // 15 seconds
    debug: process.env.NODE_ENV !== 'production',
  }
);

Error Handling

All API errors throw a standard JavaScript Error with the message:

API Error (Status <code>): <message>

Wrap calls in try/catch:

try {
  const appt = await OpenDental.Appointments().getAppointment(12345);
} catch (err) {
  console.error(err.message); // "API Error (Status 404): Not found"
}

Available Resources

Every resource is accessed via a factory method on OpenDental. Each factory returns a class instance pre-configured with the shared HTTP client.

| Factory Method | API Endpoint | Description | |---|---|---| | OpenDental.AccountModules() | /accountmodules | Account sub-resource data for a patient | | OpenDental.Adjustments() | /adjustments | Ledger adjustments | | OpenDental.Allergies() | /allergies | Patient allergy records | | OpenDental.AllergyDefs() | /allergydefs | Allergy definition master list | | OpenDental.AppointmentTypes() | /appointmenttypes | Appointment type definitions | | OpenDental.Appointments() | /appointments | Patient appointments | | OpenDental.ApptFieldDefs() | /apptfielddefs | Custom appointment field definitions | | OpenDental.ApptFields() | /apptfields | Custom appointment field values | | OpenDental.AsapComms() | /asapcomm | ASAP list communications | | OpenDental.AutoNoteControls() | /autonotecontrols | Auto note control definitions | | OpenDental.AutoNotes() | /autonotes | Auto note templates | | OpenDental.Benefits() | /benefits | Insurance plan benefits | | OpenDental.Carriers() | /carriers | Insurance carriers | | OpenDental.ChartModules() | /chartmodules | Chart module data for a patient | | OpenDental.ClaimPayments() | /claimpayments | Insurance claim payments (EOBs) | | OpenDental.ClaimProcs() | /claimprocs | Claim procedure line items | | OpenDental.ClaimTrackings() | /claimtrackings | Claim tracking history | | OpenDental.Claims() | /claims | Insurance claims | | OpenDental.Clinics() | /clinics | Clinic locations | | OpenDental.ClockEvents() | /clockevents | Employee time clock punches | | OpenDental.CodeGroups() | /codegroups | Procedure code groups | | OpenDental.CommLogs() | /commlogs | Patient communication logs | | OpenDental.Computers() | /computers | Registered workstations | | OpenDental.CovCats() | /covcats | Insurance coverage categories | | OpenDental.CovSpans() | /covspans | Insurance coverage spans | | OpenDental.Definitions() | /definitions | Definition list items (dropdowns) | | OpenDental.DiseaseDefs() | /diseasedefs | Disease/problem definition master list | | OpenDental.DiscountPlanSubs() | /discountplansubs | Patient discount plan subscriptions | | OpenDental.DiscountPlans() | /discountplans | In-house discount plan definitions | | OpenDental.Diseases() | /diseases | Patient problem/disease records | | OpenDental.Documents() | /documents | Patient document/image records | | OpenDental.ETrans() | /etrans | Electronic transaction records | | OpenDental.ETransMessageTexts() | /etransmessagetexts | Raw electronic transaction message text | | OpenDental.ETranss() | /etranss | Bulk electronic transaction listing | | OpenDental.EhrPatients() | /ehrpatients | EHR/Meaningful Use patient data | | OpenDental.Employees() | /employees | Employee records | | OpenDental.Employers() | /employers | Employer records | | OpenDental.EobAttaches() | /eobattaches | EOB attachment images | | OpenDental.Events() | /events | Server audit-trail events | | OpenDental.FamilyModules() | /familymodules | Family module data | | OpenDental.FeeScheds() | /feescheds | Fee schedule records | | OpenDental.Fees() | /fees | Individual fee records | | OpenDental.HistAppointments() | /histappointments | Appointment change history | | OpenDental.InsPlans() | /insplans | Insurance plan records | | OpenDental.InsSubs() | /inssubs | Insurance subscriber records | | OpenDental.InsVerifies() | /insverifies | Insurance verification records | | OpenDental.LabCases() | /labcases | Dental lab case records | | OpenDental.LabTurnarounds() | /labturnarounds | Lab turnaround time records | | OpenDental.Laboratories() | /laboratories | Dental laboratory records | | OpenDental.MedicationPats() | /medicationpats | Patient medication records | | OpenDental.Medications() | /medications | Medication definition master list | | OpenDental.Operatories() | /operatories | Operatory (treatment room) records | | OpenDental.PatFieldDefs() | /patfielddefs | Custom patient field definitions | | OpenDental.PatFields() | /patfields | Custom patient field values | | OpenDental.PatPlans() | /patplans | Patient insurance plan enrollments | | OpenDental.PatientNotes() | /patientnotes | Patient note fields (financial, medical, etc.) | | OpenDental.PatientRaces() | /patientraces | Patient race/ethnicity records | | OpenDental.Patients() | /patients | Patient records | | OpenDental.PayPlanCharges() | /payplancharges | Payment plan charge records | | OpenDental.PayPlans() | /payplans | Payment plan records | | OpenDental.PaySplits() | /paysplits | Payment allocation splits | | OpenDental.Payments() | /payments | Patient payments | | OpenDental.PerioExams() | /perioexams | Periodontal exam records | | OpenDental.PerioMeasures() | /periomeasures | Periodontal measurement records | | OpenDental.Pharmacies() | /pharmacies | Pharmacy records | | OpenDental.Popups() | /popups | Patient chart popup messages | | OpenDental.Preferences() | /preferences | Global practice preferences | | OpenDental.ProcNotes() | /procnotes | Procedure notes | | OpenDental.ProcTPs() | /proctps | Treatment plan procedures | | OpenDental.ProcedureCodes() | /procedurecodes | ADA CDT procedure code definitions | | OpenDental.ProcedureLogs() | /procedurelogs | Procedure log records | | OpenDental.Providers() | /providers | Provider records | | OpenDental.Queries() | /queries | Arbitrary read-only SQL queries | | OpenDental.QuickPasteCats() | /quickpastecats | Quick-paste category records | | OpenDental.QuickPasteNotes() | /quickpastenotes | Quick-paste note templates | | OpenDental.RecallTypes() | /recalltypes | Recall type definitions | | OpenDental.Recalls() | /recalls | Patient recall records | | OpenDental.RefAttaches() | /refattaches | Referral attachment records | | OpenDental.Referrals() | /referrals | Referral source/destination records | | OpenDental.Reports() | /reports | Built-in Open Dental reports | | OpenDental.RxPats() | /rxpats | Prescription records | | OpenDental.ScheduleOps() | /scheduleops | Schedule-to-operatory links | | OpenDental.Schedules() | /schedules | Provider/blockout schedule blocks | | OpenDental.Security() | /security | User security settings | | OpenDental.SecurityLogs() | /securitylogs | Security audit log entries | | OpenDental.SheetDefs() | /sheetdefs | Sheet template definitions | | OpenDental.SheetFields() | /sheetfields | Sheet template field definitions | | OpenDental.Sheets() | /sheets | Filled-out sheet instances | | OpenDental.SignalODs() | /signalods | Real-time server signal records | | OpenDental.Statements() | /statements | Patient billing statements | | OpenDental.Subscriptions() | /subscriptions | Webhook event subscriptions | | OpenDental.SubstitutionLinks() | /substitutionlinks | Tooth material substitution rules | | OpenDental.TaskLists() | /tasklists | Task list folders | | OpenDental.TaskNotes() | /tasknotes | Task comments/notes | | OpenDental.Tasks() | /tasks | Task records | | OpenDental.ToothInitials() | /toothInitials | Existing tooth chart conditions | | OpenDental.TreatmentPlanAttaches() | /treatplanattaches | Procedure-to-treatment-plan links | | OpenDental.TreatmentPlans() | /treatplans | Treatment plan records | | OpenDental.UserGroupAttaches() | /usergroupattaches | User-to-group memberships | | OpenDental.UserGroups() | /usergroups | User security groups | | OpenDental.UserODs() | /userods | Open Dental user accounts | | OpenDental.Transformers() | — | Stateless data transformation utilities |


Usage Examples

Patients

const patients = OpenDental.Patients();

// Search patients
const results = await patients.getPatients({ LName: 'Smith', FName: 'John' });

// Get a single patient
const patient = await patients.getPatient(1234);

// Create a patient
const newPatient = await patients.createPatient({
  LName: 'Smith',
  FName: 'Jane',
  Birthdate: '1985-06-15',
});

// Update a patient
const updated = await patients.updatePatient({ PatNum: 1234, WirelessPhone: '555-867-5309' });

Appointments

const appts = OpenDental.Appointments();

// Fetch appointments for a date range
const list = await appts.getAppointments({
  dateStart: '2026-01-01',
  dateEnd: '2026-01-31',
});

// Create an appointment
const newAppt = await appts.createAppointment({
  PatNum: 1234,
  AptDateTime: '2026-03-15 09:00:00',
  Op: 3,
  ProvNum: 2,
});

// Break an appointment
await appts.breakAppointment(apptNum, { sendToUnscheduledList: 'true' });

Payments

const payments = OpenDental.Payments();

// Create a payment
const payment = await payments.createPayment({
  PatNum: 1234,
  PayAmt: '150.00',
  PayNote: 'Visa ending in 4242',
});

// Refund a payment
const refund = await payments.refundPayment({
  PayNum: 567,
  RefundAmt: 75.00,
  PayNote: 'Partial refund',
});

Queries (read-only SQL)

const queries = OpenDental.Queries();

// Short query (up to 100 rows)
const rows = await queries.shortQuery<{ PatNum: number; LName: string }>({
  SqlCommand: "SELECT PatNum, LName FROM patient WHERE LName = 'Smith' LIMIT 10",
});

// Larger query — results exported to SFTP
await queries.runQuery({ SqlCommand: 'SELECT * FROM procedurelog' });

Insurance Benefits

const benefits = OpenDental.Benefits();

// List benefits for a plan
const list = await benefits.getBenefits({ PlanNum: 42 });

// Create a benefit
const benefit = await benefits.createBenefit({
  PlanNum: 42,
  BenefitType: 'Percentage',
  Percent: 80,
  CovCatNum: 3,
});

// Delete a benefit (note: method renamed from v3.4.x — see Breaking Changes)
await benefits.deleteBenefit(benefitNum);

Date Utilities

Open Dental returns dates and datetimes without timezone information — they reflect the local clock of the Open Dental server. Use toISO to convert these to ISO 8601 UTC strings before storing or comparing them in your application.

import { toISO } from '@rinse-dental/open-dental';

// Datetime string — "yyyy-MM-dd HH:mm:ss"
toISO("2021-08-05 02:00:00", "America/Los_Angeles");
// => "2021-08-05T09:00:00.000Z"  (PDT, UTC-7)

// Date-only string — interpreted as midnight in the given timezone
toISO("2021-08-05", "America/Los_Angeles");
// => "2021-08-05T07:00:00.000Z"  (PDT, UTC-7)

Pass an IANA timezone name matching your Open Dental server's configured timezone. DST transitions are handled automatically. Strings that don't match either format are returned unchanged.

Typical usage after an API call:

const appt = await OpenDental.Appointments().getAppointment(12345);
const TZ = "America/Los_Angeles";

const startISO = toISO(appt.AptDateTime, TZ);
const endISO   = toISO(appt.AptDateTimeEnd, TZ);

API Documentation (Docs/)

This package includes the full Open Dental API reference documentation in the Docs/ folder, enriched with database schema mappings and field-level notes for every endpoint. These markdown files are optimized for AI-assisted development.

Docs/
└── Open Dental 2026-04-22/
    ├── api-url-list.md        — Master list of all API URLs
    ├── apiappointments.md
    ├── apipatients.md
    ├── apibenefits.md         — Enriched with X12 mappings and DB schema
    └── ...                    — One file per API resource

Breaking Changes

v4.0.0

The following changes are breaking relative to v3.x.

ChartModules.PatientInfo()ChartModules.getPatientInfo()

The method was renamed to follow the SDK's getX() naming convention.

// Before (v3.x)
const info = await OpenDental.ChartModules().PatientInfo(patNum);

// After (v4.0.1)
const info = await OpenDental.ChartModules().getPatientInfo(patNum);

Benefits.deletePatPlan()Benefits.deleteBenefit()

The method was renamed to correctly reflect that it deletes a benefit record, not a patient plan.

// Before (v3.x)
await OpenDental.Benefits().deletePatPlan(benefitNum);

// After (v4.0.0)
await OpenDental.Benefits().deleteBenefit(benefitNum);

RefAttaches.deleteInsSub()RefAttaches.deleteRefAttach()

The method was incorrectly named after a different resource. It has been corrected.

// Before (v3.x)
await OpenDental.RefAttaches().deleteInsSub(refAttachNum);

// After (v4.0.0)
await OpenDental.RefAttaches().deleteRefAttach(refAttachNum);

InsVerifies.createInsVerifies() now correctly uses POST

Previously this method called PUT /insverifies instead of POST /insverifies. Any consumers relying on the incorrect behavior should verify their integration.

API errors now throw Error instances

Previously, API errors threw the raw Axios response object. They now throw a standard Error with a descriptive message string. Update any catch blocks that inspected err.status or err.data directly:

// Before (v3.x) — err was an AxiosResponse
catch (err: any) {
  console.log(err.status);
}

// After (v4.0.1) — err is an Error
catch (err: unknown) {
  if (err instanceof Error) console.log(err.message);
}

All GET list endpoints now accept Limit, DateFormatString, and DateTimeFormatString

These are additive and non-breaking for existing callers, but consumers relying on receiving all results in a single call should be aware of the 1000-item hard limit per request.

// Paginate through results
const page1 = await OpenDental.Appointments().getAppointments({ Offset: 0,    Limit: 1000 });
const page2 = await OpenDental.Appointments().getAppointments({ Offset: 1000, Limit: 1000 });

// Custom date format
const patients = await OpenDental.Patients().getPatients({ DateFormatString: "MM/dd/yyyy" });

TypeScript Support

The SDK ships with full TypeScript definitions. All request parameters and response shapes are typed. Import types directly from the package:

import type { Patient } from '@rinse-dental/open-dental/dist/types/patientTypes';
import type { Appointment } from '@rinse-dental/open-dental/dist/types/appointmentTypes';

License

MIT © Rinse Dental Inc.