SDKs

The recommended way to interact with the Avon Health API is the official @avon-health/sdk TypeScript/JavaScript library. It provides typed services for many /v2 resources, generic access to the rest, and handles authentication, pagination, retries, and error mapping for you.

Installation

Install with npm

npm install @avon-health/sdk

Authentication

The SDK uses the same OAuth2 flow described in Authentication: an organization-level client ID + secret (exchanged for a bearer token) and a user-level JWT. You provide all four values once when constructing the client and the SDK attaches the right headers to every request, refreshing the bearer automatically.

  • Name
    baseUrl
    Type
    string
    Description

    The API base URL, e.g. https://{{base_subdomain}}.avonhealth.com.

  • Name
    account
    Type
    string
    Description

    Your account identifier (sent as the account header).

  • Name
    clientId
    Type
    string
    Description

    Organization client ID. Exchanged for a bearer token at /v2/auth/token.

  • Name
    clientSecret
    Type
    string
    Description

    Organization client secret.

  • Name
    jwt
    Type
    string
    Description

    User-level JWT (sent as x-jwt). Identifies the acting caller.

Create a client

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

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

Minting a JWT from a user ID

If you don't already have a jwt, pass a userId to the async Avon.create(...) factory and the SDK mints one for you via /v2/auth/get-jwt:

Mint the JWT automatically

const avon = await Avon.create({
  baseUrl: 'https://{{base_subdomain}}.avonhealth.com',
  account: '{{accountID}}',
  clientId: '{{client_id}}',
  clientSecret: '{{client_secret}}',
  userId: 'user_{{memberId}}', // SDK mints the jwt from this
})

You can also mint one explicitly with the static helper:

Mint a JWT explicitly

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

Quick start

Create, retrieve, and update a patient

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: '+15555550123' })

Resources

Every resource follows the same convention, mapping directly onto the REST API:

MethodHTTP
list(params?)GET /v2/{resource}
retrieve(id)GET /v2/{resource}/{id}
create(data)POST /v2/{resource}
update(id, data)POST /v2/{resource}/{id}
del(id)DELETE /v2/{resource}/{id}

Typed services available on the client include:

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

Many add domain actions, for example:

Domain actions and nested resources

await avon.patients.createEmergencyContact('pat_1', { name: 'Kin', phone: '+1...' })
await avon.appointments.trigger('apt_1')
await avon.notes.sign('note_1')
await avon.forms.publish('form_1')
const count = await avon.patients.count({ status: 'active' })

Any resource without a dedicated service is reachable through the generic escape hatch, which exposes the same CRUD surface:

Generic resource access

const objects = avon.resource('custom_objects') // -> /v2/custom_objects
await objects.list()
await objects.create({ name: 'Widget' })
await objects.action('obj_1', 'archive')        // POST /v2/custom_objects/obj_1/archive

Pagination

List endpoints return the { object: 'list', data: [...] } envelope and paginate with limit/offset. The SDK can walk every page for you:

Auto-pagination

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

// Or collect everything into an array
const all = await avon.patients.listAll({ status: 'active' })

// Or fetch a single page
const page = await avon.patients.list({ limit: 50, offset: 0 })

Errors

Failed requests throw a typed subclass of AvonError carrying the backend's status, code, message, and the requestId for support correlation. See Errors for the full list of codes.

Handling errors

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

try {
  await avon.patients.retrieve('pat_missing')
} catch (err) {
  if (err instanceof NotFoundError) {
    // 404
  } else if (err instanceof RateLimitError) {
    console.log('retry after', err.retryAfter, 'seconds')
  } else if (err instanceof AvonError) {
    console.log(err.status, err.code, err.message, err.requestId)
  }
}
ClassWhen
AuthenticationError401 / 403
InvalidRequestError400 / 422
NotFoundError404
ConflictError409
RateLimitError429 (retryAfter)
APIError5xx
APIConnectionErrornetwork / timeout

Retries

GET and DELETE requests are retried automatically on 429, 408, and 5xx responses and on network errors, using exponential backoff with jitter and honoring Retry-After. Write requests (POST/PUT) are not retried by default. Tune it with the retry option:

Configure retries

const avon = new Avon({
  baseUrl,
  account,
  clientId,
  clientSecret,
  jwt,
  timeout: 60_000,
  retry: { maxRetries: 2, baseDelay: 500, maxDelay: 8_000 },
})

Versioning

Each request is stamped with the SDK version (x-avon-client-version) so it can be traced server-side. If you build an application on top of the SDK, pass appInfo to identify it:

Identify your application

const avon = new Avon({
  baseUrl,
  account,
  clientId,
  clientSecret,
  jwt,
  appInfo: { name: 'my-app', version: '2.3.4' },
})