Avon SDK

Official TypeScript SDK for the Avon Health API. It provides typed resource services for the /v2 REST API, pagination helpers, retries for transient failures, and typed errors.

Installation

npm install @avon-health/sdk

Requires Node.js 18+. The package is ESM and includes TypeScript declarations.

Quick Start

import { Avon } from '@avon-health/sdk'

const avon = new Avon({
  baseUrl: 'https://{{base_subdomain}}.avonhealth.com',
  clientId: '<client_id>',
  clientSecret: '<client_secret>',
  jwt: '<jwt>',
  account: 'acct_123',
})

const patient = await avon.patients.create({
  first_name: 'Ada',
  last_name: 'Lovelace',
  email: 'ada@example.com',
})

const fetched = await avon.patients.retrieve(patient.id)
await avon.patients.update(patient.id, { phone: '(555) 555-0123' })

Authentication

Every client needs the API credentials provided during onboarding:

  • baseUrl - Avon API base URL.
  • clientId and clientSecret - your API key.
  • account - your account identifier.

Plus the identity of the acting caller (a jwt). There are two ways to provide it:

Option 1: Mint the jwt, then construct

Get a JWT for the acting user, then pass it to the synchronous constructor. This gives you the raw JWT to cache or reuse across clients:

const jwt = await Avon.getJwt({
  baseUrl: 'https://{{base_subdomain}}.avonhealth.com',
  id: 'user_<memberId>',
})

const avon = new Avon({
  baseUrl: 'https://{{base_subdomain}}.avonhealth.com',
  clientId: '<client_id>',
  clientSecret: '<client_secret>',
  account: 'acct_123',
  jwt,
})

Option 2: Let the factory mint it for you

Pass userId to the async create factory and it mints the JWT and constructs the client in one step:

const avon = await Avon.create({
  baseUrl: 'https://{{base_subdomain}}.avonhealth.com',
  clientId: '<client_id>',
  clientSecret: '<client_secret>',
  account: 'acct_123',
  userId: 'user_<memberId>',
})

Resources

Typed services are available on the client:

  • Core: patients, providers, supports, organizationMembers, users, auth
  • Scheduling: appointments, appointmentTypes, slots
  • Clinical content and care plans: notes, noteTemplates, forms, formResponses, documents, documentTemplates, carePlans, carePlanTemplates, quizzes, quizResponses, tasks
  • Billing: invoices, superbills, insuranceClaims, insurancePolicies, insuranceRemittances, products, coupons, serviceFacilities, billingProviders, referringProviders, feeSchedules, customPayers
  • Patient chart: allergies, conditions, medications, familyHistories, vitals, procedures, labOrders, labResults, requisitions, prescriptions, orderSets
  • Organization and communication: medicalCenters, careTeams, peerGroups, specializations, tags, smartPhrases, customFields, intakeFlows, customPages, messageThreads

The resources support the standard CRUD methods:

await avon.patients.create({ first_name: 'Ada', last_name: 'Lovelace' })
await avon.patients.retrieve('user_123')
await avon.patients.update('user_123', { phone: '(555) 555-0123' })
await avon.patients.list({ limit: 50 })
await avon.patients.del('user_123')

Some resources include domain-specific actions:

await avon.patients.merge({ ids: ['user_1', 'user_2'] })
await avon.appointments.trigger('appt_1')
await avon.notes.sign('note_1')
await avon.forms.publish('form_1')

const count = await avon.tasks.count({ status: 'todo' })

Resources without a typed service can be called through the generic resource helper:

const objects = avon.resource('custom_objects')

await objects.create({ name: 'Widget' })
await objects.update('obj_1', { name: 'Gadget' })
await objects.list()

Pagination

List endpoints return a { object: "list", data: [...] } envelope and support limit / offset. Use autoList to iterate across pages or listAll to collect every item.

for await (const patient of avon.patients.autoList({ status: 'active' })) {
  console.log(patient.id)
}

const allPatients = await avon.patients.listAll({ status: 'active' })

Errors

Failed requests throw AvonError subclasses with status, code, message, requestId, and the raw response when available.

import { AvonError, NotFoundError } from '@avon-health/sdk'

try {
  await avon.patients.retrieve('user_missing')
} catch (err) {
  if (err instanceof NotFoundError) {
    // 404
  } else if (err instanceof AvonError) {
    console.log(err.status, err.code, err.message, err.requestId)
  }
}

GET and DELETE requests are retried automatically for transient failures. Bodied requests such as POST and PUT are not retried unless the request is marked idempotent.

License

ISC