Reference catalog (datasets)
The /v3/datasets bundle — inline-row shape, ULID identifiers, prescription_count sorting, and ?include= slicing.
Reference catalog (datasets)
GET /v3/datasets ships the reference catalog the SDK and your UI use to resolve free text to canonical conditions, medications, products, nicotine options, and spelling corrections.
Every row is self-contained: a condition row carries its medications inline as treated_with[], and a medication row carries its conditions inline as used_for[]. Each inline entry includes a prescription_count integer for sorting. No response-root joins, no client-side re-keying.
The SDK calls this for you. await isa.zyins.datasets.get() warms the
bundle cache; every match() / autocomplete() after that reads from it.
Wire shape
{
"object": "dataset_bundle",
"request_id": "req_01HZK2N5GQR9T8X4B6FJW3Y1AS",
"livemode": true,
"data": {
"version": "2026-05-29.r41",
"datasets": {
"conditions": { "version": "2026-05-29", "item_count": 3812, "items": [ /* … */ ] },
"medications": { "version": "2026-05-29", "item_count": 5174, "items": [ /* … */ ] },
"products": { "version": "2026-05-29", "item_count": 127, "items": [ /* … */ ] },
"spelling_corrections": { "version": "2026-05-29", "item_count": 942, "items": [ /* … */ ] },
"nicotine_options": { "version": "2026-05-29", "item_count": 8, "items": [ /* … */ ] }
}
}
}A conditions[] row:
{
"id": "cond_01KSR2WVAGC05ZGR6FA4QYEA8X",
"name": "HIGH BLOOD PRESSURE",
"treated_with": [
{ "id": "med_01KSR2WVAGC05ZGR6FA4QYEB12", "name": "LISINOPRIL", "prescription_count": 4120 },
{ "id": "med_01KSR2WVAGC05ZGR6FA4QYEB7K", "name": "AMLODIPINE", "prescription_count": 3088 },
{ "id": "med_01KSR2WVAGC05ZGR6FA4QYEC22", "name": "LOSARTAN", "prescription_count": 2841 }
]
}A medications[] row:
{
"id": "med_01KSR2WVAGC05ZGR6FA4QYEB12",
"name": "LISINOPRIL",
"used_for": [
{ "id": "cond_01KSR2WVAGC05ZGR6FA4QYEA8X", "name": "HIGH BLOOD PRESSURE", "prescription_count": 4120 },
{ "id": "cond_01KSR2WVAGC05ZGR6FA4QYEA9P", "name": "CONGESTIVE HEART FAILURE", "prescription_count": 617 }
]
}Both inline arrays are pre-sorted by prescription_count descending, with ties broken alphabetically. Use the array directly for a "Most Common" picker—no re-sorting needed.
Identifiers
id is a kind-prefixed ULID:
| Prefix | Kind |
|---|---|
cond_ | Condition |
med_ | Medication |
prod_ | Product |
nic_ | Nicotine option |
corr_ | Spelling correction |
Identifiers are stable for the lifetime of a dataset version (the bundle's top-level version token). When version changes, treat every cached id as potentially invalid and re-match() to get fresh identifiers.
Store name in your database, not id. The id is a cache key that changes across versions; name is the stable primary reference.
?include= — slice the bundle
?include= — slice the bundleThe full bundle is large. Ask for only the categories you need:
curl -G https://zyins.isaapi.com/v3/datasets \
-H "Authorization: Bearer $ISA_TOKEN" \
--data-urlencode 'include=conditions,medications'Omitted categories arrive as undefined on the typed bundle. The SDK treats them as empty arrays, so match() against an omitted category returns UnknownConcept instead of throwing an error.
?fields=meta — version-only probe
?fields=meta — version-only probePolling for staleness? Ask for metadata only:
curl https://zyins.isaapi.com/v3/datasets?fields=meta \
-H "Authorization: Bearer $ISA_TOKEN"Each datasets[<category>] entry still carries version and item_count;
items is omitted (the SDK normalizes the absence to an empty array). Compare
per-category version to the one you cached. If anything moved, re-fetch
the full bundle and warm the SDK's bundle cache:
import { Isa } from 'isa-sdk';
const isa = await Isa.withBearer();
await isa.zyins.datasets.get();The next match(), autocomplete(), or autocorrector.correct() call sees the fresh bundle automatically. The SDK rebuilds the cached typo map and frequency map on first use after the bundle changes.
Conditional revalidation
The endpoint honors If-None-Match. Pass the previous response's ETag
and on no-change the server returns 304 Not Modified with no body. The SDK
handles this transparently; on a 304, get() resolves to a sentinel you
can short-circuit on:
import { Isa } from 'isa-sdk';
const isa = await Isa.withBearer();
const result = await isa.zyins.datasets.get();
if ('notModified' in result) {
// Use the previous bundle; the SDK cache is already current.
} else {
// Fresh bundle; the SDK cache has been swapped under the same handle.
console.log(result.version);
}Code samples
TypeScript
import { Isa } from 'isa-sdk';
const isa = await Isa.withBearer();
await isa.zyins.datasets.get(); // warm the SDK cache
const hbp = isa.zyins.conditions.match('high blood pressure');
console.log(hbp.id, hbp.name, hbp.isKnown);
// cond_01KSR2WVAGC05ZGR6FA4QYEA8X HIGH BLOOD PRESSURE true
for (const med of hbp.medications(isa.zyins.reference.Sort.MostCommonFirst)) {
console.log(med.name);
}
// LISINOPRIL
// AMLODIPINE
// LOSARTANPython
from isa_sdk import Isa
from isa_sdk.zyins.reference_v3 import Sort
isa = Isa.with_bearer() # reads ISA_TOKEN; sync, no await
# The reference namespace fetches and caches the dataset bundle on first
# use, so match() / autocomplete() work straight after construction.
hbp = isa.zyins.conditions.match('high blood pressure')
print(hbp.id, hbp.name, hbp.is_known)
for med in hbp.medications(Sort.MOST_COMMON_FIRST):
print(med.name)Go
ctx := context.Background()
if _, err := isa.Zyins.Datasets.Get(ctx); err != nil {
log.Fatal(err)
}
hbp := isa.Zyins.Conditions.Match("high blood pressure")
fmt.Println(hbp.ID, hbp.Name, hbp.IsKnown)
for _, med := range hbp.Medications(reference.SortMostCommonFirst) {
fmt.Println(med.Name)
}PHP
$isa->zyins->datasets->get();
$hbp = $isa->zyins->conditions->match('high blood pressure');
echo $hbp->id, ' ', $hbp->name, ' ', var_export($hbp->isKnown, true), PHP_EOL;
foreach ($hbp->medications(Sort::MostCommonFirst) as $med) {
echo $med->name, PHP_EOL;
}curl
curl https://zyins.isaapi.com/v3/datasets \
-H "Authorization: Bearer $ISA_TOKEN" \
-G --data-urlencode 'include=conditions,medications'What changed from v2
v2 (/v2/reference-data) | v3 (/v3/datasets) |
|---|---|
medications_by_condition response-root map | Inline treated_with[] on each condition row |
frequency_graphs.use_map response-root map | Inline prescription_count on each inline entry |
| Conditions nested inside medications | Flat top-level conditions[] + medications[] |
| Raw display strings as keys | ULID id everywhere |
Client-side make_key and reverse joins | Server-side authoritative shape |
If you wrote any of lookupByCondition, frequencyOf, useMap,
buildIndex, normalizeKey on the v2 surface, delete it. The row is the
source of truth.
Why this matters for licensing
Every row is independently meaningful. A licensee who consumes only
conditions[] does not need to also accept medications[] to render
"Most Common medications for X" — the data is already on the condition
row. See Licensing the datasets for the
standalone-licensing posture.
Updated about 10 hours ago