Liking cljdoc? Tell your friends :D

HTTP API

Start the server:

hermes --db snomed.db --port 8080 serve

Options:

FlagDefaultDescription
--port8080Port number
--bind-addressBind address (use 0.0.0.0 for containers)
--allowed-originsCORS policy: "*" or comma-delimited hostnames
--localeautoDefault locale (e.g. en-GB). Auto-detected from installed language reference sets.

Data is returned as JSON by default. Request EDN by setting Accept: application/edn. Locale-aware endpoints respect the Accept-Language header.

Endpoint summary

EndpointDescription
GET /v1/snomed/concepts/:idConcept record
GET /v1/snomed/concepts/:id/extendedFull concept with descriptions, relationships, refsets
GET /v1/snomed/concepts/:id/descriptionsAll descriptions
GET /v1/snomed/concepts/:id/preferredPreferred synonym (locale-aware)
GET /v1/snomed/concepts/:id/propertiesDefining relationships and concrete values
GET /v1/snomed/concepts/:id/historicalHistorical associations for inactive concepts
GET /v1/snomed/concepts/:id/refsetsReference set memberships
GET /v1/snomed/concepts/:id/subsumed-by/:subsumer-idSubsumption check
GET /v1/snomed/concepts/:id/map/:refset-idCross-map to a target code system or reference set
GET /v1/snomed/crossmap/:refset-id/:codeReverse map from external code to SNOMED
GET /v1/snomed/searchFull-text search with ECL constraints
GET /v1/snomed/expandExpand an ECL expression
GET /v1/snomed/subsumesExpression-level subsumption
GET /v1/snomed/classifyOWL classification (requires --owl)
GET /v1/snomed/necessary-normal-formNecessary Normal Form (requires --owl)
GET /v1/snomed/statusInstalled distributions and module info

Concept endpoints

Get a concept

curl -s 'http://localhost:8080/v1/snomed/concepts/24700007' | jq .
{
  "active": true,
  "definitionStatusId": 900000000000074008,
  "effectiveTime": "2002-01-31",
  "id": 24700007,
  "moduleId": 900000000000207008
}

Try it live: http://128.140.5.148:8080/v1/snomed/concepts/24700007

Get extended concept

Returns the concept with all descriptions, parent relationships (with transitive closures), concrete values and reference set memberships. If an Accept-Language header is provided, includes a preferredDescription.

Try it live: http://128.140.5.148:8080/v1/snomed/concepts/24700007/extended

curl -s -H 'Accept-Language: en-GB' \
  'http://localhost:8080/v1/snomed/concepts/24700007/extended' | jq .

The response includes all descriptions (with acceptableIn and preferredIn arrays indicating language reference set status), parent relationships with full transitive closures for each relationship type, and reference set memberships. Clients can use the transitive closures for local subsumption checks without further server round-trips.

Full response example (multiple sclerosis, 24700007)
{
    "concept": {
        "active": true,
        "definitionStatusId": 900000000000074008,
        "effectiveTime": "2002-01-31",
        "id": 24700007,
        "moduleId": 900000000000207008
    },
    "descriptions": [
        {
            "acceptableIn": [],
            "active": true,
            "caseSignificanceId": 900000000000448009,
            "conceptId": 24700007,
            "effectiveTime": "2017-07-31",
            "id": 41398015,
            "languageCode": "en",
            "moduleId": 900000000000207008,
            "preferredIn": [900000000000509007, 900000000000508004, 999001261000000100],
            "refsets": [900000000000509007, 900000000000508004, 999001261000000100],
            "term": "Multiple sclerosis",
            "typeId": 900000000000013009
        },
        {
            "acceptableIn": [900000000000509007, 900000000000508004, 999001261000000100],
            "active": true,
            "caseSignificanceId": 900000000000448009,
            "conceptId": 24700007,
            "effectiveTime": "2017-07-31",
            "id": 1223979019,
            "languageCode": "en",
            "moduleId": 900000000000207008,
            "preferredIn": [],
            "refsets": [900000000000509007, 900000000000508004, 999001261000000100],
            "term": "Disseminated sclerosis",
            "typeId": 900000000000013009
        },
        {
            "acceptableIn": [900000000000509007, 900000000000508004, 999001261000000100],
            "active": true,
            "caseSignificanceId": 900000000000017005,
            "conceptId": 24700007,
            "effectiveTime": "2003-07-31",
            "id": 1223980016,
            "languageCode": "en",
            "moduleId": 900000000000207008,
            "preferredIn": [],
            "refsets": [900000000000509007, 900000000000508004, 999001261000000100],
            "term": "MS - Multiple sclerosis",
            "typeId": 900000000000013009
        }
    ],
    "directParentRelationships": {
        "116676008": [409774005, 32693004],
        "116680003": [6118003, 413834006, 128283000, 39367000],
        "263502005": [90734009],
        "363698007": [21483005],
        "370135005": [769247005]
    },
    "parentRelationships": {
        "116676008": [138875005, 107669003, 123037004, 409774005, 32693004, 49755003, 118956008],
        "116680003": [
            6118003, 138875005, 404684003, 27624003, 413834006, 128139000,
            23853001, 246556002, 363170005, 64572001, 118940003, 414029004,
            362975008, 363171009, 128283000, 39367000, 80690008, 362965005
        ],
        "263502005": [138875005, 288524001, 90734009, 303102005, 281586009, 362981000, 272099008, 272103003],
        "363698007": [138875005, 21483005, 442083009, 1193638008, 123037004, 25087005, 91689009, 714488006, 91723000],
        "370135005": [138875005, 769247005, 308489006, 303102005, 281586009, 362981000, 719982003]
    },
    "refsets": [
        1322291000000109, 1382531000000102, 991381000000107, 999002271000000101,
        991411000000109, 733073007, 1127601000000107, 900000000000497000
    ]
}

Each description includes acceptableIn and preferredIn arrays indicating which language reference sets consider it acceptable or preferred. The parentRelationships contain the full transitive closure for each relationship type, enabling client-side subsumption checks without further server calls.

Get preferred synonym

Locale-aware preferred term:

Try it live: http://128.140.5.148:8080/v1/snomed/concepts/80146002/preferred

curl -s -H 'Accept-Language: en-GB' \
  'http://localhost:8080/v1/snomed/concepts/80146002/preferred' | jq .term
# => "Appendicectomy"

curl -s -H 'Accept-Language: en-US' \
  'http://localhost:8080/v1/snomed/concepts/80146002/preferred' | jq .term
# => "Appendectomy"

Get properties

Returns defining relationships grouped by role group, optionally with human-readable labels.

Try it live: http://128.140.5.148:8080/v1/snomed/concepts/1231295007/properties

curl -s -H 'Accept-Language: en-GB' \
  'http://localhost:8080/v1/snomed/concepts/1231295007/properties?format=id:syn' | jq .
{
  "0": {
    "116680003:Is a": ["779653004:Lamotrigine only product in oral dose form"],
    "411116001:Has manufactured dose form": "385060002:Prolonged-release oral tablet",
    "763032000:Has unit of presentation": "732936001:Tablet",
    "1142139005:Count of base of active ingredient": "#1"
  },
  "1": {
    "732943007:Has BoSS": "387562000:Lamotrigine",
    "732945000:Has presentation strength numerator unit": "258684004:mg",
    "732947008:Has presentation strength denominator unit": "732936001:Tablet",
    "762949000:Has precise active ingredient": "387562000:Lamotrigine",
    "1142135004:Has presentation strength numerator value": "#250",
    "1142136003:Has presentation strength denominator value": "#1"
  }
}

Parameters:

ParameterDescription
expandInclude transitive (inherited) relationships (true/false)
formatFormat both keys and values
key-formatFormat for relationship type keys
value-formatFormat for target values

Format options: id, syn, id:syn, [id:syn], {id:syn}.

When results are not expanded, the MRCM metadata model is used to determine cardinality — singular attributes are returned as scalars rather than arrays.

Subsumption

# Is multiple sclerosis a type of demyelinating disease?
curl -s 'http://localhost:8080/v1/snomed/concepts/24700007/subsumed-by/6118003' | jq .
# => {"subsumedBy": true}

Search

curl -s 'http://localhost:8080/v1/snomed/search?s=mnd&constraint=<64572001&maxHits=5' | jq .

Try it live

[
  {
    "id": 5372519013,
    "conceptId": 37340000,
    "term": "MND - motor neuron disease",
    "preferredTerm": "Motor neuron disease"
  },
  {
    "id": 486696014,
    "conceptId": 37340000,
    "term": "MND - Motor neurone disease",
    "preferredTerm": "Motor neuron disease"
  },
  {
    "id": 5372732017,
    "conceptId": 37340000,
    "term": "MND - motor neurone disease",
    "preferredTerm": "Motor neuron disease"
  }
]

See Search and ECL for full details.

Parameters:

ParameterDefaultDescription
sSearch text
constraint / eclECL expression to constrain results
maxHitsMaximum number of results (1-9999)
isAConstrain to descendants of this concept
refsetConstrain to members of this reference set
fuzzyfalseEnable fuzzy matching
fallbackFuzzyfalseRetry with fuzzy matching if exact search returns no results
inactiveConceptsfalseInclude inactive concepts
inactiveDescriptionstrueInclude inactive descriptions (recommended)
removeDuplicatesfalseRemove consecutive results with same conceptId and text
fsnfalseInclude fully specified names in results

The default of searching inactive descriptions is deliberate — a user searching for a now-inactive synonym like "Wegener's Granulomatosis" should still find the active concept.

More search examples

Search for UK medicinal products containing amlodipine, with fuzzy fallback and duplicate removal for autocompletion:

curl -s 'http://localhost:8080/v1/snomed/search?s=amlodipine&constraint=<10363601000001109&fallbackFuzzy=true&removeDuplicates=true&maxHits=500' | jq .

Try it live

No search term is needed — you can search with just an ECL constraint. All drugs with exactly three active ingredients:

curl -s -G 'http://localhost:8080/v1/snomed/search' \
  --data-urlencode 'constraint=<373873005|Pharmaceutical / biologic product| : [3..3] 127489000 |Has active ingredient| = < 105590001 |Substance|' | jq .

Try it live

All disorders of the lung associated with oedema:

curl -s -G 'http://localhost:8080/v1/snomed/search' \
  --data-urlencode 'constraint=<19829001 AND <301867009' | jq .

Try it live

ECL expansion

If you are expanding an ECL expression without search terms, use the expand endpoint.

curl -s -G 'http://localhost:8080/v1/snomed/expand' \
  --data-urlencode 'ecl=<19829001 AND <301867009' -d includeHistoric=true | jq .

Try it live

See Search and ECL for full details.

Parameters:

ParameterDescription
eclECL expression (required)
preferredInclude preferred term for each concept
dialectIdLanguage reference set SCTID for preferred terms (overrides Accept-Language)
includeHistoricExpand to include historical associations

History supplements

SNOMED ECL v2.0 introduced dedicated history supplement functionality. For example, this returns asthma and all subtypes, including those now considered inactive or duplicate:

<<195967001 |Asthma| {{ +HISTORY-MOD }}

Try it live

As a concept identifier is a valid ECL expression, you can find historical associations for a single concept:

curl -s 'http://localhost:8080/v1/snomed/expand?ecl=24700007&includeHistoric=true' | jq .

Try it live: http://128.140.5.148:8080/v1/snomed/expand?ecl=24700007&includeHistoric=true

Concrete values in ECL

ECL supports concrete values. Here are all products containing 250mg of amoxicillin in an oral dose form:

< 763158003 |Medicinal product (product)| :
     411116001 |Has manufactured dose form (attribute)|  = <<  385268001 |Oral dose form (dose form)| ,
    {    <<  127489000 |Has active ingredient (attribute)|  = <<  372687004 |Amoxicillin (substance)| ,
          1142135004 |Has presentation strength numerator value (attribute)|  = #250,
         732945000 |Has presentation strength numerator unit (attribute)|  =  258684004 |milligram (qualifier value)|}

Try it live: http://128.140.5.148:8080/v1/snomed/expand?ecl=<763158003...

Cross-mapping

Map multiple sclerosis (24700007) into ICD-10 using the UK complex map reference set (999002271000000101):

curl -s 'http://localhost:8080/v1/snomed/concepts/24700007/map/999002271000000101' | jq .

Try it live: http://128.140.5.148:8080/v1/snomed/concepts/24700007/map/999002271000000101

And crossmap back from ICD-10 to SNOMED:

curl -s 'http://localhost:8080/v1/snomed/crossmap/999002271000000101/G35X' | jq .

Try it live: http://128.140.5.148:8080/v1/snomed/crossmap/999002271000000101/G35X

If you map a concept that isn't directly in a reference set, hermes walks up the hierarchy to find the best parent match. Here "limbic encephalitis with LGI1 antibodies" (763794005) isn't in the UK emergency unit reference set (991411000000109), but "encephalitis" (45170000) is:

curl -s 'http://localhost:8080/v1/snomed/concepts/763794005/map/991411000000109' | jq .

Try it live: http://128.140.5.148:8080/v1/snomed/concepts/763794005/map/991411000000109

This makes it straightforward to allow clinicians to record highly-specific terms while mapping to less granular categories for analytics on demand.

See Cross-mapping for full details.

Expression subsumption

Tests whether expression A subsumes expression B.

curl -s 'http://localhost:8080/v1/snomed/subsumes?a=73211009&b=73211009:363698007=84301002' | jq .
ParameterRequiredDescription
aYesSCG expression or concept ID
bYesSCG expression or concept ID
modeNostructural (default) or owl (requires --owl at startup)

Returns {"outcome": "equivalent"}, {"outcome": "subsumes"}, {"outcome": "subsumed-by"}, or {"outcome": "not-subsumed"}.

OWL reasoning endpoints

These require starting the server with --owl. See OWL reasoning.

Classify expression

curl -s 'http://localhost:8080/v1/snomed/classify?expression=73211009:363698007=84301002' | jq .

Returns equivalent concepts, direct super-concepts and proximal primitive supertypes.

Necessary Normal Form

curl -s 'http://localhost:8080/v1/snomed/necessary-normal-form?expression=73211009:363698007=84301002' | jq .

JSON identifier handling

SNOMED CT identifiers are 64-bit positive integers. Most JSON parsers handle these correctly, but some (notably JavaScript's default JSON.parse) may silently truncate large numbers. If your client has this issue, use a reviver parameter. See discussion.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close