Skip to content

Make requests

Read and update resources with the TypeScript SDK.

Updated View as Markdown

Use resource methods such as get, list, create, and update.

Read a resource

Pass path identifiers before request options.

const order = await affinity.forPractice(practiceId).orders.get("ord_...");

List resources

Pass query parameters in one object.

const practices = await affinity.practices.list({ limit: 25 });

for (const practice of practices.data) {
  console.log(practice.id, practice.name);
}

List available pharmacies

Use a key with catalog:read to list the pharmacies available to your platform in the key’s Test or Live mode.

const pharmacies = await affinity.pharmacies.list({ limit: 25 });

const offers = await affinity.forPractice(practiceId).catalog.items.list({
  pharmacyId: selectedPharmacyId,
  availability: "orderable",
  hideUnpriced: true,
  limit: 25,
});

Use a returned pharmacy ID as selectedPharmacyId. Pharmacy access does not mean every catalog item is orderable; use the catalog’s availability filters.

Discover medications and offers

Request one representative priced prescription offer per medication group:

const medications = await affinity.forPractice(practiceId).catalog.items.list({
  view: "medications",
  query: "tadalafil",
  availability: "orderable",
  hideUnpriced: true,
  limit: 25,
});

Grouped results include medicationGroup.offerCount, pharmacyCount, and strengths. Use a returned item’s ID to retrieve individual offers for the same medication and route:

const offers = await affinity.forPractice(practiceId).catalog.items.list({
  view: "offers",
  relatedToCatalogItemId: medicationId,
  availability: "orderable",
  hideUnpriced: true,
  limit: 25,
});

Omitting view preserves the individual-offer response. Keep the same filters when paginating; when hasMore is true, pass the last returned item ID as startingAfter. Select and review an individual offer before creating a prescription.

Create a patient

Use synthetic patient data in Test mode.

const patient = await affinity.forPractice(practiceId).patients.create({
  name: { first: "Synthetic", last: "Patient" },
  dateOfBirth: "1980-01-10",
  externalId: "patient-456",
  address: {
    line1: "100 Test Street",
    city: "Austin",
    state: "TX",
    postalCode: "78701",
    country: "US",
  },
  phone: "+15125550100",
});

Request options are optional. The SDK generates keys for routine patient writes. Consequential actions require a persisted key. Supply your own stable idempotencyKey when retrying an operation across separate calls or processes.

Use actorId and actorType in request options when attributing an action to a person. Order signing accepts a prescriber selector or inherits the draft’s prescriber without requiring actor options. Legacy requests with userId still require the registered clinician as a user actor.

externalId is the patient ID in your integration. Affinity scopes it to the authenticated platform or practice, so you do not need to provide a source. Creating a patient with a matching externalId returns the existing patient without overwriting demographics.

Use externalIdentities for aliases owned by another system, such as a legacy EHR:

externalIdentities: [{ source: "legacy-ehr", value: "12345" }];

Find your patient with patients.list({ externalId: "patient-456" }, { practiceId }). To find an explicit alias, provide externalIdentitySource and externalIdentityValue together. Updating externalId changes only your integration’s identifier. Updating externalIdentities replaces the explicit aliases.

Manage practice Live access

Use a Live API key from an approved platform with practices:write.

const practice = await affinity.practices.create({
  ...practiceDetails,
  liveEnabled: true,
});

await affinity.practices.update(practice.id, { liveEnabled: false });
await affinity.practices.update(practice.id, { liveEnabled: true });

practiceDetails contains the required practice name, address, and attestations. The response uses liveEnabled: boolean; disabled access is false, not a pending approval. Your platform can change only its owned practices. Affinity Admin decisions take precedence. See Practice Live access for restrictions.

Use domain types

import type {
  Practice,
  Patient,
  Order,
  CreatedOrder,
  CatalogItem,
  PracticeLocation,
} from "@affinity-health/sdk";

const practice: Practice = await affinity.practices.get(practiceId);
const id: string = practice.id;

Resource IDs are non-null strings. Fields that can be empty, such as legalName, remain nullable. CreatedOrder describes the creation response; Order describes the full retrieved order. When upgrading from older releases, replace practice productionAccess comparisons with liveEnabled checks.

Use typed compounding reasons

import { CompoundingReason } from "@affinity-health/sdk";

const category: CompoundingReason = CompoundingReason.ConcentrationAdjustment;

Use catalog.prescribingOptions.get to get the categories accepted for a medication. Send the selected value as clinical.compoundingReason.category on the prescription. Add context when required. See Compounding reasons for the complete workflow.

Iterate through a collection

The iterator loads pages as you consume them and preserves practice context and filters.

for await (const patient of affinity.forPractice(practiceId).patients.iterate({ limit: 20 })) {
  await syncPatient(patient);
}

Use the API reference for direct HTTP access to endpoints outside the SDK.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close