Uploading CodeSystems

 

Smile CDR bundles all conformance resources (StructureDefinitions, OperationDefinitions, CompartmentDefinitions, CodeSystems, ConceptMaps, and ValueSets) distributed as part of the FHIR release itself. These resources can be seeded into the repository at startup by enabling the Seed Base Validation Resources configuration. Once seeded, you can perform standard terminology operations such as $lookup on the Administrative Gender CodeSystem using a request like:https://try.smilecdr.com/baseR4/CodeSystem/$lookup?system=http://hl7.org/fhir/administrative-gender&code=male

In many cases, it is useful to upload your own CodeSystems for use in validation and search operations. This might involve uploading standard vocabularies such as LOINC or loading local, custom, organization-specific CodeSystems.

This page describes methods for uploading External CodeSystems (also called Not-Present CodeSystems; see CodeSystem Resources for more information on what this means). For general guidance on using external code systems with HL7 standards, including canonical URIs, OIDs, and usage notes for each system, see the HL7 External Code Systems reference.

Withdrawn Operations

 

As of Smile CDR 2026.08.R01 and HAPI FHIR 8.12.0, the following operations have been removed:

The previous operations have been withdrawn because of a number of functional limitations: They were less secure as they relied on local file storage, and they were prone to running out of memory on smaller or heavily loaded servers. The new operations are designed from the ground up to be better replacements:

  • They always work in small chunks, avoiding ever loading large amounts of data into memory. This means that even large CodeSystems such as LOINC and SNOMED CT can be loaded into a database without needing to increase available memory om the server.
  • They are standard batch jobs, meaning that the storage process provides visible progress updates and can be cancelled.
  • They are designed for multithreaded and clustered execution, allowing faster parallel processing if server specs support it.

Uploading External CodeSystems

 
Uploading external terminologies requires the FHIR_UPLOAD_EXTERNAL_TERMINOLOGY permission.

Smile CDR has the ability to import several standard terminology code systems using their native distribution formats. It is also possible to upload external terminology containing any other sets of codes, including other standard vocabularies and locally defined code sets.

This is done using the Upload Terminology Operations, which can be invoked either using a REST client, or automated using the Smile command-line tool (smileutil) command.

The following table lists the various terminologies supported by Smile CDR, as well as their URL and required input format.

CodeSystem URL File Format  
LOINC http://loinc.org LOINC Complete Download ZIP Upload Instructions
SNOMED CT http://snomed.info/sct SNOMED CT RF2 Distribution ZIP Upload Instructions
ICD-10 (International Edition) http://hl7.org/fhir/sid/icd-10 XML Format (ClaML) Upload Instructions
ICD-10-CM (US Edition) http://hl7.org/fhir/sid/icd-10-cm XML Format (CDC Tabular XML) Upload Instructions
All Others Any Any CodeSystem may be uploaded using a CodeSystem resource and/or CSV (comma-separated value) files. Upload Instructions

Performing the Upload with smileutil

The Smile command-line tool (smileutil) Upload Terminology command can be used to upload standard and custom vocabulary. The sections below show examples of how to do this.

Performing the Upload via REST operation

It is also possible to upload external terminology using REST operations directly. See Upload Terminology Operations for details. The Smile command-line tool (smileutil) Upload Terminology command invokes these same operations.

Uploading LOINC

 

Smile CDR can ingest and process the distribution format for the LOINC vocabulary. LOINC is a rich set of codes related to health measurements, observations, and documents. LOINC is most commonly known for codes describing laboratory testing orders and results.

In order to upload LOINC, the LOINC Download File download should be selected from the LOINC website. This file will have a filename similar to Loinc_N.NN.zip. It is available from the LOINC Downloads page.

Importer Updates in 2026.08 (HAPI FHIR 8.12.0)

As of Smile CDR 2026.08 / HAPI FHIR 8.12.0, the LOINC uploader has been rewritten as a batch job in order to provide better performance and better visibility. Previously, uploading LOINC used the $upload-external-code-system operation. The previous mechanism is no longer supported, and LOINC uploads must now use the Upload Terminology Operations instead.

The new importer has several differences from the previous importer:

  • When uploading LOINC, supplying a version ID for the LOINC distribution is now mandatory (previously this was optional).
  • When a version is supplied, the previous importer would create two CodeSystems, one with a null version ID and one with the supplied version ID. Now, only a single version is created.
  • All CodeSystems, ValueSets, and ConceptMaps created by the importer will use the supplied version ID.
  • Linguistic variant files are not imported by default. See loincupload.properties below.

Input Files

The following input files are supported (note that version numbers given are only examples; newer and older versions of these files may also be supported).

Filename Required? Description
Loinc_2.89.zip Yes LOINC Distribution
loincupload.properties   This optional file is not a part of the LOINC distribution and must be created manually. It contains version information about the upload.

The loincupload.properties File

A second optional file may also be uploaded called loincupload.properties. This file supplies additional configuration for the import job.

# Include the following linguistic variants
loinc.linguistic.variants.codes=deAT24, frCA8

Performing the Upload

The Smile command-line tool (smileutil) Upload Terminology command can be used to upload LOINC files. An example command is shown below:

bin/smileutil upload-terminology -d Loinc_2.73.zip -d loincupload.properties -v r4 -t "http://localhost:8000" -u "http://loinc.org"

The easiest way to use this tool is to adapt the provided script, upload-loinc.sh in the terminology/loinc directory within the Smile CDR distribution.

Uploading SNOMED CT

 

Smile CDR has the ability to ingest and process the "RF2" distribution format for the SNOMED CT vocabulary. SNOMED CT is a very large and complex set of vocabulary covering almost all areas of healthcare.

For SNOMED specifically, the Upload Terminology command will likely need more memory than the default. See SmileUtil Memory Settings for details.

An example with memory increased to 4GB is given below:

$ env JAVA_OPTS=-Xmx4g bin/smileutil upload-terminology -d "./SnomedCT_RF2Release_INT_20160131.zip" -v "dstu3" -t "http://localhost:8000" -u "http://snomed.info/sct"

Input Files

The following input files are supported (note that version numbers given are only examples; newer and older versions of these files may also be supported).

Filename Required? Description
SnomedCT_RF2Release_INT_20160731.zip Yes This file contains a complete release of SNOMED CT in the "RF2" format. The filename shown here is the international release of SNOMED CT, but national editions may be used instead as they share the same release format.

The SNOMED CT distribution is a copyrighted work and requires a license to download and use. See the SNOMED CT website for more information.

Uploading ICD-10

 

Smile CDR can ingest and process the distribution format for the WHO international editiion of the ICD-10 vocabulary.

Input Files

The following input files are supported (note that version numbers given are only examples; newer and older versions of these files may also be supported). Only one of the following files must be provided. ICD-10 distribution files can be obtained at the following URL: https://icdcdn.who.int/icd10/index.html

Filename Required? Description
icd102019en.xml.zip Either the ZIP or the XML file must be provided, but not both. This ZIP file contains the "ClaML XML" file.
icd102019en.xml Either the ZIP or the XML file must be provided, but not both. This file in the "ClaML XML" format contains the complete codeset and hierarchy for ICD-10 codes.

Performing the Upload

In order to upload ICD-10, the Smile command-line tool (smileutil) Upload Terminology command can be used. An example command is shown below:

bin/smileutil upload-terminology -d icd102019en.xml.zip -v r4 -t "http://localhost:8000" -u "http://hl7.org/fhir/sid/icd-10|2019en"

Uploading ICD-10-CM

 

Smile CDR has the ability to ingest and process the distribution format for the ICD-10-CM vocabulary.

Input Files

The following input files are supported (note that version numbers given are only examples; newer and older versions of these files may also be supported). Only one of the following files must be provided. ICD-10-CM distribution files can be obtained at the following URL: https://ftp.cdc.gov/pub/health_statistics/nchs/publications/ICD10CM/

Filename Required? Description
icd10cm-table and index-2026.zip Either the ZIP or the XML file must be provided, but not both. This ZIP file contains the "tabluar XML" file.
icd10cm-tabular-2026.xml Either the ZIP or the XML file must be provided, but not both. This XML file contains the complete codeset and hierarchy for ICD-10-CM codes.

Performing the Upload

In order to upload ICD-10-CM, the Smile command-line tool (smileutil) Upload Terminology command can be used. An example command is shown below:

bin/smileutil upload-terminology -d icd10cm-tabular-2026.xml -v r4 -t "http://localhost:8000" -u "http://hl7.org/fhir/sid/icd-10-cm|2026"

Uploading Other Vocabularies

 

If you have a set of concepts that is not already supported by one of the formats above, you can convert it into a standard HAPI FHIR custom vocabulary format and then upload it.

Input Files

The following input files are supported (note that version numbers given are only examples; newer and older versions of these files may also be supported). Only one of the following files must be provided. ICD-10-CM distribution files can be obtained at the following URL: https://ftp.cdc.gov/pub/health_statistics/nchs/publications/ICD10CM/

Filename Required? Description
custom.zip Either the ZIP or the CSV/JSON/XML file(s) must be provided, but not both. This ZIP file contains one or more of the CSV/XML/JSON files described in Vocabulary Input File Formats below.
concepts.csv No This CSV file contains concept codes and display names. The format is described below.
hierarchy.csv No This CSV file contains parent/child relationships between concepts. The format is described below.
properties.csv No This CSV file contains concept properties (key/value pairs associated with a specific concept). The format is described below.
codesystem.json or codesystem.xml No This file is a JSON or XML encoded CodeSystem resource. It can be used to describe the CodeSystem, and it can also be used to supply the concept definitions instead of using the CSV file formats. An example is provided below.

Upload Mode / Delta Operations

Set of codes can be provided as a SNAPSHOT, meaning that any existing codes are replaced with the complete set of concepts, relationships, properties, etc. are all replaced with those supplied to the job. It is also possible to supply a delta, meaning a set of concepts/relationships/properties/etc. to ADD or REMOVE.

See the mode parameter of the $hapi.fhir.upload-terminology.create-job operation for more information on how to do this.

Performing the Upload

To upload custom terminology using the standard Custom CSV Vocabulary Input Files, use the Smile command-line tool (smileutil) Upload Terminology command. An example command is shown below:

bin/smileutil upload-terminology -d codesystem.json -d concepts.csv -d hierarchy.csv -v r4 -t "http://localhost:8000" -u "http://example.com/labCodes|1.0" -m SNAPSHOT

You can also package the distribution files into a single zip file, and upload it instead:

bin/smileutil upload-terminology -d custom.zip -v r4 -t "http://localhost:8000" -u "http://example.com/labCodes|1.0" -m SNAPSHOT

Vocabulary Input File Formats

 

A zip file should be created that has the following file(s) listed below as contents. Note that all CSV files are required to have a header line containing the column names as the first line. This is shown in the examples below.

Concepts File: concepts.csv

This file should have the following columns:

  • CODE – contains the concept code
  • DISPLAY – contains the concept display name

Example:

CODE,DISPLAY

CHEM,Chemistry
HB,Hemoglobin
NEUT,Neutrophils
MICRO,Microbiology
C&S,Culture and Sensitivity

Hierarchy File: hierarchy.csv

This file contains optional hierarchy information if your codes have a parent-child hierarchy. This file should have the following columns:

  • PARENT – contains the concept code for the parent
  • CHILD – contains the concept code for the child

Example:

In the example below, the HB and NEUT concept will be children of the CHEM concept. The C&S concept will be a child of the MICRO concept.

PARENT,CHILD

CHEM,HB
CHEM,NEUT
MICRO,C&S

Omitting hierarchy.csv

The hierarchy.csv file is always optional; if it is missing, all codes defined in concepts.csv are treated as root concepts (concepts with no parents).

Adding Child Records

When using this file for the Delta Operations it is possible to specify PARENT codes that do not exist in concepts.csv but are already present in the existing CodeSystem. In this case, the child code is added as a child to the existing PARENT code, whether it is a root concept itself, or is a child as well. If the PARENT code does not already exist, it will be created (with no display name or other attributes populated).

Properties File: properties.csv

This optional file can be used to supply properties to be applied to a concept (i.e. values for CodeSystem.concept.property). This file should have the following columns:

  • CODE – The concept code to which the property will be attached.
  • KEY – The property name.
  • VALUE – The property value. This should be a simple string value for all types except CODING, where it should be a JSON string containing the serialized Coding object.
  • TYPE – The property type. Must be one of the following: string, integer, boolean, code, dateTime, decimal, Coding

Example

The following example shows a number of properties being applied to the CHEM concept. Note that the Coding concept has its quote marks escaped using the CSV escape syntax (a double quote).

CODE, KEY,         TYPE,     VALUE      

HB,   color,       string,   red        
HB,   sequence,    integer,  25         
HB,   archived,    boolean,  false      
HB,   created,     dateTime, 2022-01-01
HB,   k_score,     decimal,  1.23
HB,   loinc_equiv, Coding,   "{""system"":""http://loinc.org"", ""code"":""1-2345""}"

CodeSystem Definition: codesystem.json or codesystem.xml

This file contains the CodeSystem definition. If this file is not supplied and a CodeSystem resource already exists for the given CodeSystem URL, the existing CodeSystem resource is not modified.

codesystem.json Example Without Codes

If a CodeSystem resource is supplied along with the CSV file(s), it will be stored in the repository if no CodeSystem already exists for the given system URL and version.

{
	"resourceType": "CodeSystem",
	"id": "example-lab-codes-1.0",
	"url": "http://example.com/labCodes",
	"version": "1.0",
	"name": "Example Lab Codes",
	"description": "A set of lab codes",
	"status": "active",
	"publisher": "Example Organization Corporation Worldwide",
	"date": "2019-07-30",
	"content": "not-present"
}

codesystem.json Example With Codes

The CodeSystem resource can be used to supply concepts as well, instead of using the CSV files described above.

{
	"resourceType": "CodeSystem",
	"id": "example-lab-codes-1.0",
	"url": "http://example.com/labCodes",
	"version": "1.0",
	"name": "Example Lab Codes",
	"description": "A set of lab codes",
	"status": "active",
	"publisher": "Example Organization Corporation Worldwide",
	"date": "2019-07-30",
	"content": "not-present",
	"concept": [ {
		"code": "CODE-1",
		"display": "Code 1",
		"property": [ {
			"code": "property-key",
			"valueString": "A Property Value"
		} ],
		"concept": [ {
		"code": "CHILD-CODE-1",
		"display": "A Child Code"
		} ]
	}, {
		"code": "CODE-2",
		"display": "Code 2"
	}, {
		"code": "CODE-3",
		"display": "Code 3"
	} ]
}

Upload Terminology Operations

 

To upload external terminology directly using REST operations (as opposed to using The Smile command-line tool / smileutil Upload Terminology command), a set of FHIR operations can be used.

These operations support uploading both supported standard terminologies (using their native distribution formats), and other terminologies (using a standard file format described on this page).

Uploading terminology involves a sequence of operations:

These operations are safe to use on a live system, even if clients are actively invoking the terminology services directly (through operations such as CodeSystem/$lookup) and indirectly (through operations such as $validate). After a job is complete, there may be a short delay (up to several minutes) before the new or updated content becomes available due to internal memory caches in Smile CDR. The system will remain consistent throughout the process.

External Terminology Upload Operation: $hapi.fhir.upload-terminology.create-job

 

The $hapi.fhir.upload-terminology.create-job operation is used to create a new terminology upload job. This operation assigns a unique ID to the job and returns it in the response. The job is ready for one or more files to be attached to it, and is not yet started.

Request Parameters

This operation takes the following parameters, which may be supplied in the request URL or in the request body using a Parameters resource:

Name Cardinality Type Description
system 1..1 uri Specifies the CodeSystem URL to upload. This may be a versioned canonical URL (e.g. http://loinc.org|2.89) or an unversioned canonical URL (e.g. http://loinc.org). If a version is not specified, it must be provided in the version parameter instead.
version 1..1 code Specifies the CodeSystem version to upload.
mode 0..1 code This parameter determines whether the operation should add, remove, or replace existing concepts in the database. It supports the following values:
  • SNAPSHOT – (This is the default if not explicitly specified) Any existing concepts (and their relationships/properties/etc.) for the CodeSystem version being targeted will be removed, and replaced with the concepts supplied to the job.
  • ADD – Any existing concepts for the CodeSystem version being uploaded will be retained, and the concepts supplied to this job will be added to them. If any concepts supplied to the job are already present in the database, they will be updated if necessary (replacing the display name if it has changed, adding properties and designations, etc) but no duplicate concepts will be created.
  • REMOVE – Any supplied concepts will be removed if they are found in the database. Any children of supplied concepts will also be removed.
makeCurrent 0..1 boolean Specifies whether the CodeSystem version being uploaded should be marked as the current version. This means that code lookups, code validations, and other operations will use this version by default if a CodeSystem version isn't explicitly specified. This parameter defaults to true, so the version being uploaded will be marked as the current version unless this parameter is included with a value of false.

Response Parameters

The response to this operation is a Parameters resource containing the following parameters:

Name Cardinality Type Description
outcome 1..1 string Returns a human-readable message indicating the outcome of the operation.
jobInstanceId 1..1 code Returns a unique identifier for the newly created job instance.

External Terminology Upload Operation: $hapi.fhir.upload-terminology.attach-file

 

The $hapi.fhir.upload-terminology.attach-file operation is used to upload the terminology distribution file(s) and attach them to the job for processing. This operation is a nonstandard FHIR operation, and requires a resource body containing a raw distribution file, such as a ZIP file.

Request Parameters

This operation takes the following parameters, which must be supplied in the request URL.

Name Cardinality Type Description
filename 1..1 code Specifies the filename being uploaded. Different CodeSystems files with specific names to be uploaded, so the filename must be appropriate for the CodeSystem. For example, the LOINC CodeSystem (see above) requires a file with the name Loinc_[version].zip or Loinc.zip).
jobInstanceId 1..1 code The job instance identifier for the upload job, as returned by the $hapi.fhir.upload-terminology.create-job operation.

Request Example

The following example shows an invocation of the $hapi.fhir.upload-terminology.attach-file operation.

POST /CodeSystem/$hapi.fhir.upload-terminology.attach-file?jobInstanceId=SOME-INSTANCE-ID&filename=Loinc_2.89.zip
Concept-Type: application/octet-stream

[...zip file contents...]

Response Parameters

The response to this operation is a Parameters resource containing the following parameters:

Name Cardinality Type Description
outcome 1..1 string Returns a human-readable message indicating the outcome of the operation.
jobInstanceId 1..1 code Returns a unique identifier for the newly created job instance.

Response Example

The following example shows the response to the $hapi.fhir.upload-terminology.attach-file operation.

{
  "resourceType": "Parameters",
  "parameter": [ {
    "name": "outcome",
    "valueString": "Attachment with ID[SOME-ATTACHMENT-ID] has been stored for job with ID[SOME-INSTANCE-ID]."
  }, {
    "name": "jobAttachmentId",
    "valueCode": "SOME-ATTACHMENT-ID"
  } ]
}

External Terminology Upload Operation: $hapi.fhir.upload-terminology.start-job

 

Once all required files have been attached to the job, the $hapi.fhir.upload-terminology.start-job operation is used to start the upload job. This operation uses the FHIR Asynchronous Interaction Request Pattern, and requires a Prefer: respond-async header to be included in the request.

Request Parameters

This operation takes the following parameters, which may be supplied in the request URL or in the request body using a Parameters resource:

Name Cardinality Type Description
jobInstanceId 1..1 code The job instance identifier for the upload job, as returned by the $hapi.fhir.upload-terminology.create-job operation.

Request Example

The following example shows an invocation of the $hapi.fhir.upload-terminology.attach-file operation.

POST /CodeSystem/$hapi.fhir.upload-terminology.start-job?jobInstanceId=SOME-INSTANCE-ID
Prefer: respond-async

The server will respond with a 202 Accepted response code, and will include a Content-Location header with a URL that can be used to poll the status of the upload job.

External Terminology Upload Operation: $hapi.fhir.upload-terminology.poll-for-status

 

The $hapi.fhir.upload-terminology.poll-for-status operation is used to poll the status of the upload job. It should be invoked as an HTTP GET using the URL retuend in the Content-Location header of the response to the $hapi.fhir.upload-terminology.start-job operation.

This operation will return a 202 Accepted response code if the upload job is still in progress, and a 200 OK response code if the job has been completed successfully. If the job has failed, a 5xx series error code will be returned.

How Uploaded Terminology Interacts with IG Packages

 

A CodeSystem with content=not-present is typically a licensed external terminology (e.g. ICD-10-CM, CPT) that an IG ships as a placeholder. It registers the CodeSystem URL but contains no concepts. Only CodeSystems actually shipped in an installed package get a placeholder; one that's merely referenced (e.g. by a ValueSet) but never shipped by any installed package has none.

Uploading terminology via the Upload Terminology Operations (or smileutil upload-terminology) loads the concepts into dedicated terminology tables alongside the placeholder, regardless of whether the upload happens before or after IG installation. The placeholder itself is never replaced or deleted by this, and its content=not-present status stays intentional, since the concepts live in the terminology tables rather than inline in the resource. By default, a later package install also leaves an existing placeholder alone; see overwriteContentNotPresentCodeSystems below.

Protecting uploaded CodeSystems during package installation

The overwriteContentNotPresentCodeSystems parameter (default false) controls what happens when a subsequent package installation encounters an existing content=not-present CodeSystem:

  • When set to false (the default), the package's CodeSystem resource is skipped, preserving the externally loaded concepts in the terminology tables. This is the safe default.
  • When set to true, the package's CodeSystem resource overwrites the existing placeholder. This can cause externally loaded concepts to become orphaned from the CodeSystem resource. Only use this if you intentionally want the package version to replace an externally loaded one.

When installing IGs on a repository that already has externally loaded terminology, always ensure overwriteContentNotPresentCodeSystems is false (or omitted) to avoid accidentally replacing loaded CodeSystems.