Deploy clinical terminology without building a runtime data pipeline: one immutable image for ICD-10-CM, LOINC, RxNorm, SNOMED CT, search, and FHIR ValueSet expansion.
Clinical terminology should not turn into a runtime integration project. A team needs code search, validation, and FHIR ValueSet expansion; too often that also means a database, a content refresh job, an external terminology service, and versions that drift apart.
ReasonHealth Terminology API is ready to run as one immutable OCI image. It provides ICD-10-CM, LOINC, RxNorm, and SNOMED CT through a finalized local terminology store and matching retrieval model. At runtime, it does not download content, call a terminology service, connect to PostgreSQL, or bootstrap a data pipeline.
The image is the installed release boundary: specific terminology versions and a small API surface that an application can put behind its own trusted gateway.
One immutable image
Terminology store + local retrieval model
ICD-10-CM, LOINC, RxNorm, and SNOMED CT stay versioned together at runtime.
POST /v1/search
Code, display, designation, prefix, and local semantic evidence help a person or workflow find a concept.
POST /fhir/R4/ValueSet/$expand
FHIR compose rules define the membership. A filter may rank within that boundary but cannot add another code.
The API provides both discovery and membership operations. They answer different questions, and treating them as interchangeable is how clinical code selection becomes difficult to review.
| When a workflow needs to… | Use | What comes back |
|---|---|---|
| Find candidate concepts from a phrase or code | POST /v1/search | Ranked discovery evidence, including match type and matched term |
| Determine the codes allowed by an explicit clinical definition | POST /fhir/R4/ValueSet/$expand | A FHIR ValueSet expansion from defined membership |
Search begins with exact codes, displays, and designations; then it can use local semantic retrieval when the installed image has a compatible model and index. Results identify their evidence. They are candidates for an application or clinician to evaluate, not an autonomous coding decision or an authoritative crosswalk.
ValueSet expansion starts from a definition. The API evaluates the supplied
FHIR compose clauses against the installed, versioned terminology releases.
An operation-level filter can narrow and rank that computed membership, but it
cannot add a code that the ValueSet did not admit. That boundary is useful for
clinical review: search helps a user find a term; the ValueSet tells the
workflow what is allowed.
The examples below use a private local endpoint and an illustrative, gateway-owned authorization scope. In production, a trusted gateway authenticates the caller, authorizes the request, strips caller credentials, and forwards a stable, non-sensitive scope to the private API. This header is not an end-user JWT or an application login token.
These examples require an installed LOINC 2.82 release and a compatible local
search model. Check the installed release identity with GET /v1/releases.
Without that model, filtered expansion returns a typed HTTP 503; unfiltered
ValueSet expansion remains available.
This request searches one exact LOINC release in a laboratory-analyte context. The response carries the installed release identity and evidence for each candidate, including whether it matched a code, display, designation, prefix, or semantic retrieval path.
1API=http://127.0.0.1:8080
2AUTHORIZATION_SCOPE=local-terminology-reader
3
4curl --fail-with-body "$API/v1/search" \
5 -H "Authorization: $AUTHORIZATION_SCOPE" \
6 -H 'Content-Type: application/json' \
7 --data '{
8 "system_uri": "http://loinc.org",
9 "source_version": "2.82",
10 "query": "hemoglobin blood",
11 "context": "lab-analyte",
12 "limit": 5
13 }'The release and context are part of the request because terminology meaning is
versioned and workflow-specific. The endpoint is intentionally bounded:
limit is at most 25, and application-owned eligibility constraints remain
outside the image.
This request supplies an inline FHIR ValueSet with two explicit LOINC codes:
718-7 and
6690-2. Its filter asks the service to rank only
within that ValueSet. In the response, the expansion parameters record the
exact terminology version used. Because this is filtered retrieval, the response
does not claim an exhaustive semantic-match count.
1curl --fail-with-body "$API/fhir/R4/ValueSet/\$expand" \
2 -H "Authorization: $AUTHORIZATION_SCOPE" \
3 -H 'Accept: application/fhir+json' \
4 -H 'Content-Type: application/fhir+json' \
5 --data '{
6 "resourceType": "Parameters",
7 "parameter": [
8 {
9 "name": "valueSet",
10 "resource": {
11 "resourceType": "ValueSet",
12 "url": "https://example.org/fhir/ValueSet/blood-count-analytes",
13 "status": "active",
14 "compose": {
15 "include": [
16 {
17 "system": "http://loinc.org",
18 "version": "2.82",
19 "concept": [{"code": "718-7"}, {"code": "6690-2"}]
20 }
21 ]
22 }
23 }
24 },
25 {"name": "filter", "valueString": "hemoglobin blood"},
26 {"name": "count", "valueInteger": 20},
27 {"name": "activeOnly", "valueBoolean": true}
28 ]
29 }'Remove the operation-level filter from the same request to retrieve the
unfiltered, deterministic membership and its exact expansion.total. The FHIR
surface is deliberately bounded. It accepts inline ValueSets and
supports explicit concepts, whole-system and property-filter inclusion,
exclusion, exact versions, paging, and selected hierarchy filters. It rejects
unsupported or ambiguous constructs rather than silently approximating them.
The maximum response page is 100 concepts, and a request can name at most 1,000
explicit concepts.
The all-in-one image simplifies deployment without hiding the work that belongs elsewhere. Customers still own their gateway policy, ingress, scaling, rollout, and image-digest verification. The API image owns its local immutable content, retrieval model, and endpoint behavior.
The delivery model also makes the content boundary explicit:
That separation matters. An open API or a local model does not grant rights to licensed terminology content. And an image that is easy to run should still be traceable to the exact release that supplied its concepts, designations, and retrieval index.
For a product team, the useful result is less plumbing around a critical clinical dependency. A frontend can request candidates with evidence. A FHIR workflow can expand a definition against a known release. An operator can promote or roll back one digest. A reviewer can inspect which boundary governed the result.
That is the point of an all-in-one terminology service: not a black box that chooses clinical meaning, but a deployable knowledge layer that keeps source identity, retrieval, and deterministic membership in view.
If you are building terminology-backed workflows and want to walk through the contract, deployment boundary, or a specific FHIR use case, get in touch.