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.
@avon-health/sdk is an ESM package and requires Node.js 18+. TypeScript type
declarations are bundled.
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
accountheader).
- 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:
| Method | HTTP |
|---|---|
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, andauth - Scheduling:
appointments,appointmentTypes, andslots - Clinical content and care plans:
notes,noteTemplates,forms,formResponses,documents,documentTemplates,carePlans,carePlanTemplates,quizzes,quizResponses, andtasks - Billing:
invoices,superbills,insuranceClaims,insurancePolicies,insuranceRemittances,products,coupons,serviceFacilities,billingProviders,referringProviders,feeSchedules, andcustomPayers - Patient chart:
allergies,conditions,medications,familyHistories,vitals,procedures,labOrders,labResults,requisitions,prescriptions, andorderSets - Organization and communication:
medicalCenters,careTeams,peerGroups,specializations,tags,smartPhrases,customFields,intakeFlows,customPages, andmessageThreads
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)
}
}
| Class | When |
|---|---|
AuthenticationError | 401 / 403 |
InvalidRequestError | 400 / 422 |
NotFoundError | 404 |
ConflictError | 409 |
RateLimitError | 429 (retryAfter) |
APIError | 5xx |
APIConnectionError | network / 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' },
})