A number of HL7 affiliates or associates would like to make terminology content that they own and manage available to the FHIR validation and IG publication system. Such requests might come from:

  • HL7 affiliates
  • national services such as VSAC or Australia's NCTS
  • other SDOs such as DICOM, IHE 
  • design services such as simplifier
  • business such as IMO

In principle, terminology content (CodeSystems, ValueSets, and ConceptMaps) can be made available to the FHIR ecosystem in the following ways:

  • publish the terminology through HL7 - this means, make a change request through the UTG system to get the content published on http://terminology.hl7.org. Content published through terminology.hl7.org is available across the entire ecosystem automatically - users don't need to do anything for that 
  • publish a package containing the value set and code system definitions into the FHIR NPM package system. Users reference the package, and all the content is automatically available when they do. To publish a package to the FHIR ecosystem, either:
  • Provide a terminology server, and declare it's availability to the FHIR tools. Content hosted on these terminology servers will automatically be available to all users in the FHIR eco-system. Note that these servers can require user tokens to protect their content (see below)
  • Ask one of the maintainers of tx.fhir.org to make your content available directly by some other means (currently: grahame@hl7.org)

The rest of this page documents the third option: providing a terminology server for the wider use of the FHIR community.

Providing a terminology server for the FHIR ecosystem

Services made available to the FHIR community in this way are only intended to be used for design time tooling, not operational health services. Whatever SLA they are made available under can and should exclude use for supportin operational health services. 

Requirements for the service

The service must host a FHIR terminology service. At least R4 must be supported. It's server discretion whether to support R2, R3, or R5. At around the time that R5 is finally published, providing an R5 service will probably be required (in place of R4?). 

The service must support:

  • metadata?mode=terminology
  • read on CodeSystem, ValueSet, and ConceptMap
  • search on CodeSystem, ValueSet, and ConceptMap by canonical URL
  • $expand, $validate-code, $lookup (if code systems are hosted), and $translate (if ConceptMaps are hosted). $subsumes is highly recommended but not required
  • support for $validate-code in a batch (potentially very large number)

Services may provide operation support for implicit value sets and code systems that are not available through read/search

Content rules:

  • All CodeSystems, ValueSets, and ConceptMaps must be have an associated URL at which a user with a browser can read the definition of the artifact. This should be a human readable web page that describes the artifact of the type that FHIR implementation guides provide (note that the specific presentation used by the IG guides is not required). The page must include a link/method for the user to download the raw definition of the resource. This URL must known for each resource. If it is not algorithmically determined (see below), then it must be specifically identified in the (Resource).meta.source property when the resource is accessed.
  • The service is assumed to be the source of truth and trusted expansions for terminology artifacts, but it can use the trusted-expansion-source to indicate another service that is the trusted-expansion-source but this will be ignored by FHIR tools unless it's also a registered server

Operation Rules:



  • Must return a list of all code systems that are supported, whether they are explicitly made available as CodeSystem resources or not
  • valueSets will be identified by the URL parameter and valueSetVersion
  • displayLanguage, activeOnly, and limitedExpansion must be supported
  • system-version, force-system-version & default-to-latest-version must be supported
  • includeDesignations / designation should be supported
  • paging should be supported (but won't be used by the most important tools)
  • if the tools provide the parameter _limit and _incomplete, it should be honored (and the extension http://hl7.org/fhir/StructureDefinition/valueset-toocostly returned if appropriate) (note: this requirement may be changed to use count - under investigation)
  • value sets or code systems will be identified by URL and version
  • displayLanguage and activeOnly must be supported
  • system-version, force-system-version & default-to-latest-version must be supported
  • the inputs system, code, coding, and codeableConcept must all be supported
  • in the parameters returned: 
    • A parameter 'cause' must be returned with the valueCode 'unknown' if validation failed because a value set / code system could not be found. If the code isn't valid or in the value set, cause = invalid. Other failures, use some other code from OperationOutcome.issue.cause if a cause is returned 
    • the service must return an 'issues' parameter with an OperationOutcome if any issues are found (for hints and warnings too)


The service may require authentication. If the service requires authentication, it must be in the form of an authentication header - usually a bearer token - that the user can determine in advance, and then provide to their FHIR tooling in some configuration (configuration will be different for different tools, but their requirement is to provide the authentication header as configured). It is assumed that the service will have some mechanism to provide these tokens to appropriate authorised users (which might be anyone who accepts the required license, or any users with appropriate citizenship or business relationship with the entity that provides the service). 

Note that there must be an arrangement for FHIR tool smiths to get a token that grants access to the service without cost in order to test their support of the services.

Registering the service

Such services are registered following discussion with the FHIR Product Director (grahame@hl7.org) which will also include discussion on the tooling channel on chat.fhir.org. When registering a service, the host that operates the service must declare in a json file that will be public to the FHIR community:

  • The identity or the hosting organization
  • the URL(s) at which the service is provided for which FHIR versions. The URLs may change but changing will require advance notice to the community of at least a month 
  • Whether the service requires authentication, and if it does,
    • who is eligible to get a token
    • a link to a web page that initiates the process of getting a token 
  • a list of canonical patterns that identify resources that the service hosts (see notes below)
  • (optional) an algorithm that defines how to turn resource ids on the service into web pages for a human to read 

Canonical Patterns

These are used by the tools to decide whether to use the service. Note that the tools will never consult all the terminology servers in case they know a particular terminology artifact - unless instructed otherwise, the tools will only consult their default terminology server (usually tx.fhir.org unlesss configured otherwise). The tools will look through the known registered services seeing if the canonical URL of the artifact they are dealing with matches any of the canonical URL patterns that the server provides services for, and if it finds a match, it will use that server.

A registered server may host more artifacts than it declares itself to be 'the' host for - e.g. the Australian NCTS hosts LOINC etc but it is not the authoritative host for LOINC. 

The list of canonical patterns may change - changing the list will require a PR to a JSON file managed by the FHIR product director.


The algorithm is a simple string that may contain the tokens {type} and {id} to define the web page for the resource. Anything more complicated than this will have be done using .meta.source (see above)

Documentation for toolsmiths

  • There will be registry for registered terminology services. Probably a single json file made available vis github
  • tools should cache their own copy and refresh it occasionally 
  • there will be a standard way a user to store tokens for the services - probably (user)/.fhir/tokens.txt. The json file will identify the token name in the that file
  • the ci-build will have it's own tokens for services that authorise the ci-build to use their service (not all will, since ci-build content is public)
  • tools should use the nominated alternative service for artifacts that are owned by other services 
  • but it won't really matter, because if they just use tx.fhir.org, tx,fhir.org will use the correct server directly anyway 

  • No labels


  1. Resource.meta.source doesn't seem like the clearest element for identifying the web page associated with a terminology artifact. It's also a single cardinality element that is overloaded to meet different requirements and different use cases, including things like data import, leading to conflicts -- and here in particular, The narrative of page where somebody can view a terminology does not seem to be in any obvious way the "source" of the fhir resource. I might suggest a dedicated extension for "see it on the web at".

    1. I agree but that already is being used for this purpose in the system (simplifier packages). So changing it isn't easy

    2. I think we need an extension that is clearly used for "here is the FHIR content" and one that is "here is the browsable view." I'm not sure that trusted source (and we need to make this a single consistent extension for both code system and value sets, perhaps more?) is the right element for "here is the resource" but a server should have an element it can populate for "here is the browsable view on my server."

  2. Has there been discussion about supporting the bulk export of terminology resources as a server requirement or a nice to have? I think it would be extremely useful.

    1. Probably useful, but not required for this particular usage

  3. It would be very helpful if tools offered a way for local users to override or augment the set of configured servers, just like they can override the default server. That would allow authors to point to a local server or an internal organization server for certain canonical URL patterns, which is a very powerful kind of flexibility that takes advantage of all this infrastructure without the centralized control.

    1. well, tools can already do that now, but it would be intelligent for them to follow this same pattern when doing so 

  4. Regarding:

    > A parameter 'cause' must be returned with the value 'unknown' if validation failed because a value set / code system could not be found

    We return a 404 if any of the resources required to complete validation can not be found.  Is this a viable (better) alternative?

    1. Why not an Operation Outcome Resource with issue.code = "not-found", which is a friendlier equivalent of a 404 response?

    2. that would be a discussion for the terminology stream. My take is 404 = the operation wasn't found. 200 ok with result = false is success for the operation

      1. But result=false says that the code is invalid; we don't know that.

        404 says that we cannot find the answer (which is actually the case) - State is unknown and thus cannot return a Representation.

        If a 200 is the desired response, then I'd suggest that result be 0..1 (or not be boolean).

  5. It might be useful to add that the server should be able to handle all operations in batch mode as well.

    tx.fhir.org supports the valueSet parameter on ValueSet/$validate-code, which the FHIR Validator seems to use (correct me if I'm wrong). Shouldn't support for this parameter be required as well?

    1. yes, I'll add that - it does use it. That part is incomplete

  6. Content Rules...

    a. I would suggest that the mandate for human-readable, IG-like web pages might be better handled by a dedicated FHIR IG for the Terminology Service or a National Base IG. That might also be preferable to requiring that R4 Servers implement metadata?mode=terminology which boils down to support for a resource that's at Maturity Level 0.

    b. "The service is assumed to be the source of truth and trusted expansions for terminology artifacts"... that may not always be feasible if Terminology Servers used by EHR/EMR/PHR systems are out of scope. Perhaps it might be better to say a "source of truth and trusted expansions?

    1. I don't understand either of these.

      a. I would of course recommend that there be a FHIR IG, but there doesn't have to be - just some way to get a human readable page. It's not related to the mode=terminology, which is the only way to find out what code systems a server actually supports 

      b. operational tx servers aren't going to be in this picture. And it's not that there's no other servers can be trusted, just in the absence of any statement to the contrary, the servers are assumed to be trusted

      1. a. Well, on Terminz, at least, [base]/CodeSystem is the best way to find out which code systems are supported. Also, much depends on the degree of human readability that you require.

        b. I'm not sure that a mere assumption is helpful.

        1. it's not a mere assumption, it's stated here as an agreement in advance. And not all the code systems that a server supports are declared through the CodeSystem end-point.

          1. It would be a surprise to me to see code systems that are not declared via the CodeSystem end-point to be declared in TerminologyCapabilities...although, as they say, life can be full of surprises, and I'd be interested to know a use case for that.

            1. This is the use case for it - knowing that they're supported even if they're not explicit. SNOMED, RxNorm, UCUM, all the little internet terminologies... tx.fhir.org supports them all, but doesn't have code system resources for them

              1. OK - looking at https://tx.fhir.org/r4/metadata?mode=terminology I see a large collection of codeSystem uris. What's the expected mechanism for ensuring that they are all represented by a human-readable page for those that aren't also represented by CodeSystem resources?

  7. I've noticed different responses from different terminology servers regarding display checks. tx.fhir.org seems to return result=true with an additional warning if the display string doesn't match, while the Dutch Nationale Terminologieserver (Ontoserver) returns result=false. Is this behavior something that you want to define here as well?

    1. Discussion of this topic, with regard to SNOMED CT here.

    2. Our reasoning for Ontoserver's behaviour was as follows:

      1. The spec itself says very little about the details of what is / is not to be considered valid.
      2. The response (OUT) parameters only offer a boolean true/false and then free-text; any kind of nuanced information is not available in a (standardised) machine-readable form.
      3. If, as a client, you are not interested in whether the display text is valid, you can just omit it from the request.

      Hence, we took the position that a client who supplies a value for display in the $validate-code call cares whether it's valid or not, and thus we need to report that in an unambiguous way → result=false

    3. we might want to define that somewhere, but not here 

  8. What is "default-to-latest-version", I don't see it as a parameter in the R4 spec or the current build?