HL7's Fast Healthcare Interoperability Resources (FHIR) standard describes data types, resources, interactions, coded values and their associated code systems that are used to represent and exchange structured clinical data.
Thanks to its pluggable and extensible architecture, Snow Owl TS is able to expose clinically relevant resources like code systems, value sets and concept maps in a format that can be consumed by third-party FHIR clients. Additionally, Snow Owl's revision model allows concurrent management of resource versions.
Navigate to http://<host>:8080/snowowl/
and select "FHIR API" from the category dropdown to see the full list of FHIR requests supported by Snow Owl TS:
We also provide a Postman collection with pre-populated example requests to try: https://documenter.getpostman.com/view/16295366/2s93z3h6cP
JSON and XML formats are both supported; resources in Turtle RDF format are not accepted (nor produced) by the server. The MIME type for these formats can appear in Accept
and Content-Type
headers. These are the following:
XML
application/fhir+xml
application/xml
text/xml
JSON
application/fhir+json
application/json
Clients can override the desired output format by using the _format
query parameter, if they have limited access to request headers. In this case shorthand values like xml
and json
are also permitted (Content-Type
must still be set correctly if the request includes a body):
Snow Owl returns a 406 Not Acceptable
response if the client requested a response format it does not support. Conversely, if the request body is in a format it does not recognize, a 415 Unsupported Media Type
response is emitted.
For development purposes, responses returned from the server can be formatted so they are more pleasing to the human eye. The example above already includes the query parameter that controls this behavior; it is named _pretty
. Setting its value to true
results in pretty-printed output.
The query parameter _summary
controls whether a subset of the elements should be returned for a resource. Supported values are:
true
-> return a pre-defined subset of elements from the resource (these are marked as "summary" in the FHIR specification)
false
-> return all elements of the resource
text
-> return text
, id
, meta
and top-level elements marked as "mandatory" in the FHIR specification (to ensure that the response remains a valid FHIR resource representation)
data
-> remove the text
element that contains a human-readable rendering of the resource, in the form of eg. an XHTML snippet
count
-> return hit count without the accompanying list of matching resources (applicable in resource search interactions only)
When summary mode is enabled, returned resources are marked with a SUBSETTED
code to indicate that certain elements were left out:
If none of the _summary
modes listed above are appropriate for a use case, clients can select individual elements for inclusion via the _elements
query parameter. Its value should be a comma-separated list of element names. Elements marked as "mandatory" are always returned.
As above, the returned resource's meta.tag
element will also include a SUBSETTED
Coding to indicate that some information has been left out.
Clients can indicate the preferred number of results to return on a single page via the _count
query parameter. Paging via offsets is not supported, but the response usually includes a link of type "next" to retrieve the next page:
As can be seen from the example, the paging mechanism uses an additional state tracking parameter called _after
.
Snow Owl only supports a small subset of FHIR's 150+ resource types – the ones that are relevant from a terminology service perspective. These are described on separate pages in detail:
The id element of each resource is assigned by Snow Owl in create interactions; the assigned value never changes once it has been set and is unique across resource types. Update interactions that use an identifier which did not exist previously will create a new resource – in this case the identifier is checked for potential collisions first.
Snow Owl represents versioned content as standalone resources when accessed via the FHIR API (the version part is separated from the resource identifiers by a /
character which is not allowed to be used in "regular" FHIR identifiers):
If there are no versions present for a given resource, or the requested identifier does not include a version part, the latest development version is returned which may include "in-progress" changes. Therefore it is recommended to always query a specific version of any terminology content to get consistent results, especially when the same terminology server instance is being used for both authoring and distribution.
The following HTTP status codes are used by Snow Owl's FHIR API to indicate the success or failure of an interaction:
If an error occurs, a response containing an OperationOutcome
resource may be returned to include additional details about the problem at hand:
Snow Owl TS differentiates between certain "families" (toolings) of code system resources. Each tooling uses an internal representation for its terminology components that can be searched and edited more effectively. These components are converted to a FHIR-compatible form when a read
or search
interaction happens, and back when new a CodeSystem
resource is created via the FHIR API (or an existing resource receives an update).
SNOMED CT and its extensions are effectively read-only from the FHIR API's point of view – they can not be created via a create
interaction, nor can content be loaded or updated from an RF2 archive. Only Snow Owl's native API has provisions for doing so.
As SNOMED CT code systems contain a considerable amount of concepts, resource responses for this tooling do not include a concept
array and content
is always set to not-present
to highlight this fact:
All SNOMED CT resources behave like editions, which means lookup
operations succeed for any concept that can be found within eg. the International Edition's content, or in any other extension the resource depends on:
The following filters are supported in value set compose statements, should they reference a SNOMED CT code system:
code: expression
operator: =
value: <ECL expression>
matches concepts using the Expression Constraint Language
code: expressions
operator: =
value: <true|false>
specifies whether Post-Coordinated Expressions should be included in the filtered result set or not (even though the filter is recognized, Snow Owl currently does not store PCEs)
code: concept
operator: is-a
value: <conceptId>
matches the descendants of the specified parent concept
code: concept
operator: in
value: <refsetId>
matches concepts that are members of the specified reference set
All SNOMED CT relationship types are supported and can be returned along with concept data if requested. An example can be seen below:
code: 288556008
(the attribute concept's ID)
type: code
URI: http://snomed.info/id/288556008
description: Before
In addition to these (and the common properties that are applicable to all code systems), Snow Owl can also return the following set of SNOMED CT-specific concept properties:
code: inactive
type: boolean
URI: http://snomed.info/field/Concept.inactive
The concept's active
RF2 property (inverted)
code: moduleId
type: code
URI: http://snomed.info/field/Concept.moduleId
The concept's moduleId
RF2 property
code: effectiveTime
type: string
URI: http://snomed.info/field/Concept.effectiveTime
The concept's effectiveTime
RF2 property (in yyyyMMdd
format)
code: sufficientlyDefined
type: boolean
URI: http://snomed.info/field/Concept.sufficientlyDefined
A boolean value derived from the concept's definitionStatusId
(set to true
if the original value is 900000000000073002|Defined|
, false
otherwise)
ICD-10 and its national variants can be imported from XML release files using the ClaML format in the paid edition of Snow Owl, however this functionality is not exposed via FHIR requests; neither can such a code system be created using a create
interaction.
Similarly to SNOMED CT resources, the concept
array remains unpopulated with content
set to not-present
in the response. ICD-10 concepts can still participate in lookup, validation or subsumption testing operations.
In the paid edition the official release archive can be used to populate the code system's contents. It is available over the FHIR API in a read-only fashion as the previous two toolings.
In Snow Owl's paid edition FHIR code system resources submitted as part of a create
or update
interaction (if no resource existed with the same ID earlier) become members of the LCS tooling. Custom properties may be defined when submitting the creation request and added to concepts of the code system.
The code system URL can be set upon creation and is checked for uniqueness.
The concept
array is fully populated in LCS responses and content
is set to complete
.
User-defined properties listed in the top-level property
elements of the resource get included in the LCS schema. The cardinality is set to [0..*]
, which means concepts can have any number of properties associated with the same type code.
Standard GET requests that include the identifier as the final path segment(s) return the code system's current (or versioned) state:
PUT requests that include a resource identifier update an existing (local) code system or create a new instance:
The response code is 201 Created
if the resource did not exist previously, and the URL is included in the Location
response header. Existing code systems are updated and a 200 OK
response is returned instead.
If an error occurs during the update, a 400 Bad Request
response with an OperationOutcome
resource as the response body is emitted instead.
The following non-standard request headers can be used to control certain aspects of the commit process:
X-Effective-Date
-> the effective date to use if a version identifier is present in the resource without a corresponding date
element
X-Author
-> sets the user identifier that the commit should be attributed to (defaults to the authenticated user)
X-Owner
-> sets the owner of the resource, for access control purposes in external systems (defaults to the author or the authenticated user if the former is not set)
X-Owner-Profile
-> sets the human-readable name of the owner of the resource, for presentation purposes in external systems
X-Bundle-Id
-> specifies the parent bundle's resource identifier (defaults to the root bundle if not set)
A DELETE request removes an existing code system:
Successful removal of a code system resource results in a 204 No Content
response. Code systems that have been published can not be removed without adding the force=true
query parameter to signal a forced deletion – this option in turn is only available to administrators.
POST requests are very similar to the instance-level update
interactions with the following important difference: the identifier included in the request body is ignored and a new, random one is generated from scratch. The request path should also omit the path segments corresponding to the resource identifier:
The response code is 201 Created
if the interaction is successful. As mentioned above, the resource URL that can be used in eg. follow-up read
interactions is included in the Location
response header.
GET requests targeting the endpoint corresponding to the resource type return all code systems that satisfy the specified search criteria, in the form of query parameters. The following example uses the count
summary mode to determine the total number of code systems registered in the system, without returning any of the matches:
The specification allows search
interactions to be initiated via a POST request to /fhir/CodeSystem/_search
using name=value
parameter pairs encoded with MIME type x-www-form-urlencoded
, however this is unsupported in Snow Owl and results in a 405 Method Not Allowed
response.
The following search parameters are supported:
_id
-> matches code systems by logical identifier
name
-> matches code systems by name (in Snow Owl this is set to the logical identifier)
title
-> matches code systems by title (Snow Owl uses exact, phrase and prefix matching during its lexical search activities)
url
-> matches code systems by their assigned url
value
version
-> matches code systems by their version
value
status
-> matches code systems by resource status (eg. draft, active, etc.)
Both GET as well as POST HTTP methods are supported. Concepts are queried based on code
, version
, system
or Coding
. Designations are included as part of the response as well as supported concept properties when requested. Date parameters are not supported.
The following example request retrieves details about the SNOMED CT concept 128927009|Procedure by method|
, including properties "inactive" and "Method" (a SNOMED CT attribute), using the latest version of the code system:
Both GET as well as POST HTTP methods are supported.
The example request below validates that 128927009|Procedure by method|
is present in SNOMED CT, selecting the resource to use for validation using a versioned identifier (an instance-level invocation):
Both GET as well as POST HTTP methods are supported.
Subsumption testing is supported for all terminologies, including SNOMED CT. The example uses version 2022-02-28 of code system SNOMED CT (via the URL in the system
query parameter) to determine whether 409822003|Domain Bacteria|
is an ancestor of 112283007|Escherichia coli|
(type-level invocation):
The response is positive (and encouraging). Changing the role of the two codes gives us a subsumed-by
result instead.
HTTP Status | Reason |
---|---|
SNOMED CT code system URLs follow the conventions described in the .
ICD-10 URLs are typically following the naming convention described in HL7's : http://hl7.org/fhir/sid/icd-10-[x]
, where the -[x]
suffix is only included if it is a national variant. One exception is the German Modification where the publisher uses a different value.
Common parameters like _format
, _summary
, _elements
and _pretty
are also applicable. These are described on the previous page:
200
OK
400
Bad Request
401
Unauthorized
403
Forbidden
404
Not Found
500
Internal Error
The paid version of Snow Owl TS supports interactions and operations that target concept map resources.
GET requests that include the identifier of the concept map return the resource's current state:
Just as with CodeSystem or ValueSet read
interactions, query parameters _format
, _summary
, _elements
and _pretty
are applicable. #common-request-parameters expands on these settings.
PUT requests that include a resource identifier will update an existing resource (or create a new one if it didn't exist earlier):
The response code is 201 Created
if the resource did not exist previously, and the URL is included in the Location
response header. Existing concept maps (like in the example above) are updated and a 200 OK
response is returned instead.
If an error occurs during the update, a 400 Bad Request
response with an OperationOutcome
resource as the response body is emitted instead.
The following non-standard request headers can be used to control certain aspects of the commit process:
X-Effective-Date
-> the effective date to use if a version identifier is present in the resource without a corresponding date
element
X-Author
-> sets the user identifier that the commit should be attributed to (defaults to the authenticated user)
X-Owner
-> sets the owner of the resource, for access control purposes in external systems (defaults to the author or the authenticated user if the former is not set)
X-Owner-Profile
-> sets the human-readable name of the owner of the resource, for presentation purposes in external systems
X-Bundle-Id
-> specifies the parent bundle's resource identifier (defaults to the root bundle if not set)
Concept maps are currently limited to a single source and target code system and version (group) they can use to map concepts.
A DELETE request removes an existing concept map:
Successful removal of a resource results in a 204 No Content
response.
Concept maps that have already been versioned can not be removed without adding the force=true
query parameter to signal a forced deletion (this option is only available to administrators however).
In create
interactions a POST request is sent to the path corresponding to the resource type. Any identifier included in the request body is ignored and a new, random one is generated from scratch.
The response code is 201 Created
if the interaction is successful. The request URL that can be used in eg. follow-up read
interactions is included in the response header named Location
.
GET requests with a request path that points to the resource type returns all concept maps that satisfy the specified search criteria, in the form of query parameters. The following example uses the count
summary mode to determine the number of active concept maps in the system, without returning any of the matches:
Just as with code system and value set resources, POST requests for search
interactions are unsupported in Snow Owl and will result in a 405 Method Not Allowed
response.
The following search parameters are supported:
_id
-> matches concept maps by logical identifier
name
-> matches concept maps by name (in Snow Owl this is set to the logical identifier)
title
-> matches concept maps by title (Snow Owl uses exact, phrase and prefix matching during its lexical search activities)
url
-> matches concept maps by their assigned url
value
version
-> matches concept maps by their version
value
status
-> matches concept maps by resource status (eg. draft, active, etc.)
Snow Owl TS uses the path parameter (and optionally, conceptMapVersion
) to identify the concept map used for the operation. Supplying a concept map resource "inline" as input parameter conceptMap
is not supported.
Parameters sourceScope
and targetScope
are also ignored.
The presence of a source*
parameter (code, coding or codeable concept) implies that the translation needs to find "forward" (target) matches, while target*
codes, codings or codeable concepts will run the translation in reverse.
An example translation request can be seen below:
Snow Owl TS supports interactions and operations related to value sets, as described in the FHIR R5 terminology service specification. For certain toolings implicit value sets are also expandable; these are described below in detail.
Value set URIs following SNOMED International's URI format are evaluated based on the associated SNOMED CT code system's content. The following URIs can be set as the url
parameter of the request:
http://snomed.info/sct/900000000000207008?fhir_vs
- all concepts of the International Edition (may include a version suffix as well).
The implicit value set URI for SNOMED CT code systems should always include a module identifier to avoid confusion.
http://snomed.info/sct/900000000000207008?fhir_vs=isa/409822003
- all concepts of the International Edition that are descendants of 409822003|Domain bacteria|
http://snomed.info/sct/900000000000207008?fhir_vs=refset
- all reference set identifier concepts in the International Edition
http://snomed.info/sct/900000000000207008?fhir_vs=refset/733073007
- all concepts of the International Edition that are members of the reference set 733073007|OWL axiom reference set|
Regular value sets are only supported in the paid edition of Snow Owl.
GET requests that include the value set identifier as the final path segment(s) return the resource state:
The returned response uses a filter mentioned in #filters that is supported by SNOMED CT – this enables including or excluding concepts using an ECL expression.
Similarly to CodeSystem read
interactions, query parameters _format
, _summary
, _elements
and _pretty
are also applicable, see #common-request-parameters for a detailed description of these options.
PUT requests that include a resource identifier will update an existing value set or create a new instance:
The response code is 201 Created
if the resource did not exist previously, and the URL is included in the Location
response header. Existing value sets (like in the example above) are updated and a 200 OK
response is returned instead.
If an error occurs during the update, a 400 Bad Request
response with an OperationOutcome
resource as the response body is emitted instead.
The following non-standard request headers can be used to control certain aspects of the commit process:
X-Effective-Date
-> the effective date to use if a version identifier is present in the resource without a corresponding date
element
X-Author
-> sets the user identifier that the commit should be attributed to (defaults to the authenticated user)
X-Owner
-> sets the owner of the resource, for access control purposes in external systems (defaults to the author or the authenticated user if the former is not set)
X-Owner-Profile
-> sets the human-readable name of the owner of the resource, for presentation purposes in external systems
X-Bundle-Id
-> specifies the parent bundle's resource identifier (defaults to the root bundle if not set)
Value sets are currently limited to a single code system and version (domain) they can refer to when including or excluding concepts.
A DELETE request removes an existing value set:
Successful removal of a resource results in a 204 No Content
response.
Value sets that have been published can not be removed without adding the force=true
query parameter to signal a forced deletion (this option is only available to administrators however). The example value set was never published and so can be deleted without this option.
In create
interactions a POST request is sent to the path corresponding to the resource type. Any identifier included in the request body is ignored and a new, random one is generated from scratch.
The response code is 201 Created
if the interaction is successful. The request URL that can be used in eg. follow-up read
interactions is included in the response header named Location
.
GET requests with a request path that points to the resource type returns all value sets that satisfy the specified search criteria, in the form of query parameters. The following example uses the count
summary mode to determine the number of draft value sets in the system, without returning any of the matches:
Just as with code system resources, POST requests are unsupported in Snow Owl and will be met with a 405 Method Not Allowed
response.
The following search parameters are supported:
_id
-> matches value sets by logical identifier
name
-> matches value sets by name (in Snow Owl this is set to the logical identifier)
title
-> matches value sets by title (Snow Owl uses exact, phrase and prefix matching during its lexical search activities)
url
-> matches value sets by their assigned url
value
version
-> matches value sets by their version
value
status
-> matches value sets by resource status (eg. draft, active, etc.)
Snow Owl supports the following input parameters for value set expansion:
url
-> the URI of the value set to expand (can be an implicit or an explicit one)
valueSetVersion
-> the version of the value set for use for the expansion
activeOnly
-> to return only active codes in the response
filter
-> to filter the results lexically
includeDesignations
-> whether to include all designations or not in the returned response
displayLanguage
-> to select the language for the returned display values
count
-> to select the number of codes to be returned in the expansion (10 by default)
after
-> state tracking parameter for concept set paging
The value set with expanded concepts is returned in entirety for this request. It includes a link that can be followed to retrieve the next page of expanded concepts:
Supplying a value set as part of the request (via the input parameter valueSet
) is not supported – nor can additional resources be supplied for expansion via the unofficial
The operation is supported both on the instance level (in this case the value set is located by resource ID) as well as the type level (a canonical URL must be supplied in the url
input parameter to identify the value set to use).
Codes can only be validated against persisted value sets, not implicit ones.
Encountering any of the following conditions will fail the code validation check:
The specified value set does not exist
The value set does not contain the specified code in its expansion
The code does not exist in the code system specified in the request (the corresponding parameter, system
is mandatory in Snow Owl)
The specified code system version differs from the version referenced by the value set
The following example checks whether 429885007|Bar|
satisfies the aforementioned conditions in the value set containing all basic dose forms we created earlier: