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
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.
As of Smile CDR 2026.08.R01 and HAPI FHIR 8.12.0, the following operations have been removed:
$upload-external-code-system – Replaced by Upload Terminology Operations with ?mode=SNAPSHOT$apply-codesystem-delta-add – Replaced by Upload Terminology Operations with ?mode=ADD$apply-codesystem-delta-remove – Replaced by Upload Terminology Operations with ?mode=REMOVEThe 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:
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 |
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.
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.
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.
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:
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. |
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
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.
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"
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. |
Smile CDR can ingest and process the distribution format for the WHO international editiion of the ICD-10 vocabulary.
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. |
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"
Smile CDR has the ability to ingest and process the distribution format for the ICD-10-CM vocabulary.
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. |
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"
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.
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. |
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.
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
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.
This file should have the following columns:
Example:
CODE,DISPLAY
CHEM,Chemistry
HB,Hemoglobin
NEUT,Neutrophils
MICRO,Microbiology
C&S,Culture and Sensitivity
This file contains optional hierarchy information if your codes have a parent-child hierarchy. This file should have the following columns:
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
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).
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).
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:
CODING, where it should be a JSON string containing the serialized Coding object.string, integer, boolean, code, dateTime, decimal, CodingThe 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""}"
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.
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"
}
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"
} ]
}
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:
$hapi.fhir.upload-terminology.create-job operation is used to create a new terminology upload job, and assign an ID to the created job instance.$hapi.fhir.upload-terminology.attach-file operation is used to upload the terminology distribution file(s) and attach them to the job instance.$hapi.fhir.upload-terminology.start-job operation starts the upload job instance and begins processing the distribution file(s).$hapi.fhir.upload-terminology.poll-for-status operation is used to poll the status of the upload job instance.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.
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.
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:
|
| 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. |
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. |
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.
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. |
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...]
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. |
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"
} ]
}
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.
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. |
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.
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.
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.
The overwriteContentNotPresentCodeSystems parameter (default false) controls what happens when a subsequent package installation encounters an existing content=not-present CodeSystem:
false (the default), the package's CodeSystem resource is skipped, preserving the externally loaded concepts in the terminology tables. This is the safe default.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.