Reference matching

Resolve freeform medication, condition, and concept text to canonical IDs without consumer-side make_key lookups.

Reference matching

The isa.zyins.reference accessors turn freeform text — what an agent types, what an applicant says, what your form collects — into canonical condition and medication concepts. The SDK builds the lookup index from isa.zyins.datasets.get(); your code never iterates response-root maps, never calls make_key, never re-derives keys.

Unknown text never rejects. It flows through prequalify, and the engine canonicalizes server-side.

What it solves

In v2, every consumer pulled medications_by_condition, normalized input with a private make_key, walked the map, and fell back to raw strings. Everyone wrote it slightly differently.

In v3, relationships live inline on the dataset row itself (treated_with[] on conditions, used_for[] on medications). The reference.match() method is the resolution surface, and the inline arrays power the traversal. See Reference catalog for the wire shape and Match for the adapter contract.

The three accessors

CallReturnsUse when
isa.zyins.medications.match(text)MedicationConceptYou know the input is a drug.
isa.zyins.conditions.match(text)ConditionConceptYou know the input is a condition.
isa.zyins.concepts.match(text)ConceptYou don't know which kind upfront — concept.kind tells you.

All three preserve the caller's input verbatim on inputText.

The Concept shape

Every match returns the same fields:

FieldTypeMeaning
idstringOpaque, kind-prefixed token (e.g. cond_01KSR2WVAGC05ZGR6FA4QYEA8X).
namestringCanonical display name from the dataset.
kind"condition" | "medication" | "nicotine"Resource discriminator.
isKnownbooleantrue if the index resolved the input; false for freeform passthrough.
inputTextstringThe caller's original text, byte-identical.
.conditions(sort?)ConditionConcept[]Symmetric traversal — conditions that use this concept.
.medications(sort?)MedicationConcept[]Symmetric traversal — medications associated with this concept.

Both traversal methods are symmetric: medication.conditions() returns the conditions a drug treats; condition.medications() returns the drugs that treat it.

Sort

Traversal accepts a namespaced Sort enum, not a closure:

  • isa.zyins.reference.Sort.MostCommonFirst — frequency-ordered (default).
  • isa.zyins.reference.Sort.Alphabetical — name-ordered.

Enums keep the call site greppable and the SDK type-stable across versions; closures would break wire-format parity with non-JS SDKs.

Unknown text never rejects

When the index doesn't recognize the input, match() still returns a ConceptisKnown is false and inputText is preserved. Pass it straight to prequalify.

The engine canonicalizes server-side and, for nicotine inputs it cannot resolve, falls back to the OTHER nicotine concept (nic_01KSR2WVAGC05ZGR6FA4QYEA8T). Your code never has to decide whether the dataset is "complete enough" before sending.

ID stability

id is a kind-prefixed ULID:

  • cond_<ULID> for conditions (e.g. cond_01KSR2WVAGC05ZGR6FA4QYEA8X)
  • med_<ULID> for medications (e.g. med_01KSR2WVAGC05ZGR6FA4QYEB12)
  • nic_<ULID> for nicotine concepts (e.g. nic_01KSR2WVAGC05ZGR6FA4QYEA8T)

IDs are stable for the lifetime of one dataset version. The dataset version is the version (and etag) returned from isa.zyins.datasets.get(); when either changes, treat all cached IDs as potentially invalid.

Persist name, not id. When you save a case to your own store and want to recall it on a future SDK release, save the name and re-match() it on load. id is a cache key, not a primary key.

Example

import { Isa } from 'isa-sdk';

const isa = await Isa.withBearer();

await isa.zyins.datasets.get();
const insulin = isa.zyins.medications.match('insulin');

console.log(insulin.id, insulin.name, insulin.isKnown);
// med_01KSR2WVAGC05ZGR6FA4QYEB12  INSULIN  true

const usedFor = insulin.conditions(isa.zyins.reference.Sort.MostCommonFirst);
// usedFor is a frequency-ordered list of ConditionConcept, drawn from
// the medication row's inline used_for[] array.

Pass insulin straight into a prequalify medication entry. The engine matches by id when it can and by inputText when it cannot — either way, your code stays on one path. See Prequalify for the recommended autocorrect → match → prequalify pipeline.