IMO® Precision Normalize - Enrichment API Guide
1 Introduction
This guide is intended to provide an introduction and overview of the Enrichment implementation of the IMO Precision Normalize API for integrating partner organizations.
The IMO Precision Normalize API supports two operations for normalizing input to IMO lexicals:
-
POST /precision/normalize/enrichment: The subject of the current guide, commonly referred to as the Enrichment endpoint. This endpoint is usually the recommended option for term normalization relevant to the Problem domain. Enrichment normalization employs enhanced contextual analysis using AI models and always aims to supply the most specific lexical applicable to your input that is also associated with a billable ICD-10-CM code.
This operation can only match input terms to Problem domain lexicals, does not support custom lexical mappings, and returns a more limited quantity of the highest scoring, billing-relevant lexical matches.
-
POST /precision/normalize/v1: Commonly referred to as the Classic endpoint. This endpoint is the recommended option for term normalization when you want to return lexicals from any domain other than "Problem"; if you want to employ custom lexical mappings; or if you want to return a broader range of lexicals with no specific preference for specificity or billing codes.
This operation can match input terms to lexicals from any domain, but has only limited support for AI models. For more information on this operation, please refer to the CLASSIC GUIDE tab.
This guide consists of the following major sections:
-
1 Introduction
Introduces the Enrichment implementation of the IMO® Precision Normalize API, its operations, and its primary terminology and concepts.
-
Provides guidance on getting started with Enrichment normalization operations, including prerequisites, basic communication and authentication requirements, and a high-level summary of the request and response payload.
-
Describes the code-based matching approach to normalization. This method normalizes each supplied clinical code by returning the one IMO lexical that best represents its clinical concept.
-
Describes the term-based matching approach to normalization for Enrichment operations. This method normalizes each supplied input term by returning one or more IMO lexicals that best match the clinical intent of the input.
-
5 Enrichment Term Normalization Requests
Describes the basic request-response pattern applicable to Enrichment term normalization, including sample payloads.
-
Lists each of the error messages that may be returned for a normalization record in the
response.error_messagearray of a response payload. -
7 Request Rate and Response Times
Provides guidelines on recommended request payload size and expected API response times based on the quantity of supplied normalization records
-
Describes an optional workflow involving the generation of a session to track input term normalization across multiple requests and endpoints with the goal of identifying the most specific lexical applicable to the relevant clinical concept.
1.1 Normalization Overview
The IMO® Precision Normalize API standardizes inconsistent clinical data from diverse systems into clinically-validated terminology with comprehensive mappings to standard industry codes. In IMO products, normalization refers to the process of "cleaning" or standardizing clinical data obtained from various sources to arrive at a common, consistent data set, enabling more effective analysis and accurate billing.
In the IMO Precision Normalize API, each act of normalization takes as input a single medical term or code, which the API attempts to match to an internal IMO library of identifiers known as "lexicals". When using a medical term as input, you may also supply additional context for that term, such as the surrounding text from the original data source. The output to the normalization process is one or more lexicals matched to the input with varying degrees of confidence. Each returned lexical provides a standardized title describing a particular clinical concept and a set of code mappings from all applicable clinical code systems.
Each request to the IMO Precision Normalize API may include multiple normalization records, each describing a single term or code that requires normalization. This API is designed for use cases requiring real-time normalization of small batches of records. When processing large batches of normalization records, for optimal performance each request payload should include 10 to 25 normalization records.
1.2 Document Scope
This guide provides a high level description of each available endpoint applicable to Enrichment normalization, their intended purposes and workflows, guidelines for their use, and example payloads for different use-cases. This guide also briefly describes the internal processes by which the API performs Enrichment normalization and matches input terms and codes to IMO lexicals.
This guide does not provide an exhaustive description of every available parameter and payload field. For full technical details about each supported operation, please refer to the REFERENCE DOCUMENTATION tab.
1.3 Operations
The Enrichment implementation of the IMO Precision Normalize API supports the following operations:
-
Authentication: The following operation retrieves an OAuth 2.0 Bearer token to be supplied in the header of all other IMO Precision Normalize API requests. The body of this request must supply a Client ID and Secret, obtained as described below in 2.1 Prerequisites.
POST /oauth/token
-
Normalization: The following operation matches input terms and codes to IMO lexicals using the Enrichment implementation of the IMO Precision Normalize API. This operation is the primary topic of the current guide.
POST /precision/normalize/enrichment
-
Term Refinement: The following operations are used for the term refinement workflow. This workflow involves generating a session to track the normalization of an input term across multiple requests and endpoints to identify greater levels of lexical specificity. For more information on this workflow, see 8 Term Refinement Workflow below.
-
GET /precision/normalize/sessionRetrieves a new session id. This value can be supplied in the request payloads of a number of IMO API operations.
-
POST /precision/normalize/event/selectionReports which lexical the partner application selected as most specifically identifying the clinical concept represented by the input term.
-
The current guide includes guidelines and best practices for using each of the above operations. For an exhausitive description of each available parameter and payload field, please refer to the REFERENCE DOCUMENTATION tab.
1.3 Terminology and Concepts
Before working with the IMO Precision Normalize API, it is a good idea to familiarize yourself with the following IMO terminology and concepts relevant to normalization:
- 1.3.1 Lexical
- 1.3.2 Clinical Code
- 1.3.3 Domain
- 1.3.4 Term-Based Matching
- 1.3.5 Code-Based Matching
- 1.3.6 Normalization Record
- 1.3.7 Score
1.3.1 Lexical
An IMO data object representing one possible description for a particular clinical concept. A given clinical concept may be represented by several related lexicals, each representing one description "variant" for that concept. For all such related lexicals, there exists a single default variant, which is considered to be the most accurate description for the clinical concept. For example, IMO maintains the lexical variants "Pain in the chest" and "Chest pain, unspecified", both of which are associated with a default variant of "Chest pain".
When performing normalization, the IMO Precision Normalize API always returns both the lexical that was directly matched to your input and its default variant. In response payloads, the directly matched lexical is identified in the items.lexical_title field and its default variant is identified in the items.default_lexical_title field. The default lexical title is typically considered to be the normalized text for the input term. When your input is directly matched to the default variant, these two response fields are identical.
Each IMO lexical has the following properties relevant to normalization:
-
Lexical Code: A unique, numeric IMO identifier for the lexical. This value exists to uniquely identify the lexical data object within IMO applications.
-
Lexical Title: One or more words briefly describing a single clinical concept. When normalizing an input term, this title represents the normalized text that should replace that input term. Lexical titles are written and validated by professionally credentialled subject matter experts employed by IMO Health.
-
Domain: Each lexical is associated with a single IMO content Domain representing a clinical subject area. See Domain below.
-
Subdomain: Each Procedure domain lexical is typically assigned to one or more subdomains representing clinically meaningful classifications for the procedure. For example, a lexical may have a subdomain of "surgical procedure" or "imaging procedure".
In response payloads, a lexical's subdomains are identified in the
items.metadata.subdomainsarray. This array is excluded for lexicals from any domain other than Procedure.
1.3.2 Clinical Code
An alphanumeric identifier from an industry standard code system, such as ICD-10-CM or SNOMED CT. Each clinical code represents a single clinical concept from its respective system. For example, in the ICD-10-CM system, the code "R07.9" represents "Chest pain, unspecified".
IMO maintains a detailed, frequently updated library of clinical codes from each supported system. Within IMO's database, each code can be associated with one or more lexicals corresponding to the same clinical concept. This relationship is often referred to as a "mapping" between codes and lexicals. A lexical is typically mapped to different codes from many different systems, and may be sometimes even be mapped to multiple codes from the same system. Likewise, a given clinical code may be mapped to multiple lexicals, each representing a different variant of the same basic clinical concept (see Lexical above).
When performing normalization, the IMO Precision Normalize API returns a list of all clinical codes associated with the default variant of each matched lexical. In response payloads, these associated codes are listed in the items.metadata.mappings object, broken down by each aplicable code system. For information on how code mappings appear in response payloads, see 2.4.3 Response Metadata Mappings below.
The exact details that can be returned for each code depends on its code system, but the following properties are applicable to most clinical codes stored in IMO's database:
-
Code System: Each clinical code belongs to a particular industry standard code system.
-
Code: The formal alphanumeric identifier for the code, as specified by the applicable code system.
-
Title: The formal description of the clinical concept represented by the code, as specified by the applicable code system.
-
Map Type: This is a property of the relationship between the code and a particular lexical. This property is primarily applicable when a lexical is associated with multiple codes from the same code system and describes the preference relationship of each applicable code to the lexical.
If applicable to the code system, the
mappingsobject in response payloads most commonly reports one of the following values for this property in themap_typefield:-
Preferred Primary - The single best code mapping for the lexical from the applicable system, as recommended by IMO's subject matter experts. For billing workflows, this may serve as the primary billing code.
-
Non-Preferred Primary - An alternate choice to the Preferred Primary when more than one option was deemed clinically defensible by IMO's subject matter experts.
-
Other Preferred Primary - An additional code of equal importance to the Preferred Primary, used when more than one billing code is necessary to fully represent the lexical.
-
Preferred Secondary - A secondary code that may be needed for complete billing in addition to the Preferred Primary (e.g. a manifestation code paired with an etiology code). This code does not in itself suffice as a primary billing code.
-
Other Preferred Secondary - Additional codes that may be needed for complete billing in addition to the Preferred Secondary. Typically listed after preferred codes in all relevant documentation. This code does not in itself suffice as a primary billing code.
-
One of these codes - Used when any one of several returned codes from the same system could possibly apply to the lexical. This is used when every available code represents a more specific clinical concept than the lexical itself.
-
Use one code from group X - Similar to One of these codes, but this property is also accompanied by a relationship_group property specifying a particular value (X). This indicates that any of the returned codes with the same relationship_group value may apply.
-
-
Relationship Type: This is a property of the relationship between the code and a particular lexical. This property indicates how well the clinical concepts respectively represented by the code and the lexical align in terms of specificity. This is sometimes also referred to as the code and lexical's "semantic relationship".
If applicable to the code system, the
mappingsobject in response payloads may report any of the following values for this property in therelationship_typefield:-
Same as - The code and lexical represent the exact same clinical concept.
-
Broader than - The code's clinical concept is less specific than the lexical.
-
Narrower than - The code's clinical concept is more specific than the lexical.
-
1.3.3 Domain
An IMO content category representing a particular clinical subject area, used to group lexicals by their purpose or intended use. Each lexical is associated with only one domain. Each IMO domain supports several applicable clinical code systems, which determine the code mappings returned in response payloads for each lexical matched to your input.
The following table lists every domain applicable to the IMO Precision Normalize API and its supported code systems. When term-based matching, Enrichment normalization operations can only return lexicals from the Problem domain. When code-based matching, normalization operations can return lexicals from any domain:
| Domain | Description | Code Systems |
|---|---|---|
| Problem | Lexicals representing the states of being that can apply to a patient and are relevant to their health or healthcare. Primarily diagnoses, but may also represent symptoms, physical findings, care status, and states of abnormality on lab tests. | ICD-9-CM, ICD-10-CM, ICD-O, DSM-5-TR, SNOMED International, SNOMED US, UMLS, USCDI |
| Procedure | Lexicals representing actions that can be performed on, or on behalf of, a patient as part of the patient’s health care. Examples include surgical procedures, imaging, referrals, and education interventions. | CPT, HCPCS, ICD-10-PCS, LOINC, SNOMED International, SNOMED US, UMLS, USCDI |
| Medication | Lexicals representing generic and branded medications at various levels of granularity, such as dose strength and dose form. | CVX, FDA BIOSIMILAR, NDC, RxNorm, UMLS, USCDI |
| Lab | Lexicals representing laboratory and anatomic pathology results, orders, and associated observations. | LOINC, SNOMED International, UMLS, USCDI |
| Allergen | Lexicals representing a substance that may trigger an allergic reaction in a patient, including but not limited to food, medication, environmental factors, and other allergenic agents. | RxNorm, SNOMED International, UMLS, USCDI |
| Anatomical Site | Lexicals representing specific anatomical locations, structures, and regions of the human body, enabling the extraction and normalization of anatomical observations, abnormalities, and measurements from unstructured clinical data such as radiology reports. | SNOMED International, UMLS, USCDI |
Note: In response payloads, the uscdi field will only appear in the mappings object if your Client ID has confirmed USCDI licensing. For more information, see 2.1 Prerequisites below.
1.3.4 Term-Based Matching
One method by which the IMO Precision Normalize API can match a normalization record's input to lexicals. When term-based matching, the API attempts to match a supplied input_term to one or more lexicals, with the possible assistance of any supplied context. When term-based matching for the Enrichment endpoint, the API can only match lexicals from the Problem domain.
Depending on a normalization request's preferences.match_field_pref setting, the API can be set to use only term-based matching, only code-based matching, or to try one method first before falling back to the other. For more information, see 2.5 Match Field Preference below.
Term-based matching is most commonly used to translate a medical term found in patient data to a standardized lexical title and to identify the codes associated with the corresponding clinical concept. It can also be used a backup to code-based matching when your supplied input code turns out to be incorrect, but your input term is valid.
1.3.5 Code-Based Matching
One method by which the IMO Precision Normalize API can match a normalization record's input to lexicals. When code-based matching, the API attempts to match a supplied input_code and input_code_system to exactly one lexical. When code-based matching, the API can match the supplied input code to a lexical from any domain, regardless of the endpoint or the normalization record's domain preference.
Depending on a normalization request's preferences.match_field_pref setting, the API can be set to use only code-based matching, only term-based matching, or to try one method first before falling back to the other. For more information, see see 2.5 Match Field Preference below.
Code-based matching is commonly used to confirm the correct title of a clinical concept for which you possess the code or when you want to view related codes from alternate clinical code systems. It can also be used as a backup to term-based matching when your supplied input term cannot be adequately matched, but your input code is valid.
1.3.6 Normalization Record
An IMO record for the normalization of a single medical term or code. When defining an IMO Precision Normalize API request payload, in the requests array, you must include one object for each term or code that you want to normalize to an IMO lexical. Each object in this array defines a separate normalization record that you will use to track a single normalization action. The response payload will also include a requests array containing one corresponding object for each normalization record you supplied in the request. In the response, the requests.items array for each normalization record lists one or more lexicals that the API matched to that record's input.
The normalization records that you define in your request payload may map to records from a partner system, or they may exist independently solely for the purpose of performing IMO Precision Normalize API operations. There is no requirement that a normalization record maps to any external entity.
In a request payload, each normalization record includes some or all of the following fields:
-
record_id: A unique identifier for the normalization record, primarily used to identify corresponding record objects between the request and the response. This value may map to a partner application record identifier, or it may exist only for normalization purposes. Each supplied record_id should typically be unique per normalization request, but there is no strict uniqueness requirement and you may use this field as best suits your workflow.
-
domain: This field is used differently depending on the situation:
-
Term-based matching: For the Enrichment endpoint, this field must always be set to "Problem". When term-based matching, the Enrichment endpoint can only return lexicals from the Problem domain.
-
Code-based matching: When code-based matching, the domain field's value is ignored and the API can return a lexical from any IMO clinical domain. For the Enrichment endpoint, this field must still be set to "Problem" in order to receive a valid response.
-
-
input_term: When term-based matching, this is the title of a medical term that you want to normalize to a lexical. This value may include any number of words up to a total of 500 characters, but should be limited to a single medical term without context. For guidelines on populating this field, see 4.1.1 Input Term Values below.
The input term is not used for code-based matching. When code-based matching, you may still want to include an input term if using term-based matching as a backup (i.e. match_field_pref="input_code_first"), but otherwise you can exclude the input term.
-
input_code and input_code_system: When code-based matching, this is the clinical code that you want to normalize to a lexical and its corresponding code system. If supplying an input code, you must also always supply its input code system.
These fields are not directly used for term-based matching. When term-based matching, you may exclude these fields, but you may still want to include them for any of several reasons:
-
Code-based matching as a backup: When term-based matching, you may want to include an input code and system if your request is using code-based matching as a backup (i.e. match_field_pref="input_term_first"). For this use-case, the input code should represent the clinical code that you believe best maps to your
input_term. -
Discrepancy Checking: When term-based matching, if your request is using discrepancy checking (i.e. preferences.discrepancy_check = true), the response will include an
items.discrepancyobject reporting whether there is a mismatch between the supplied input code and the codes mapped to the highest scoring lexical returned for the normalization record. For more information, see 4.9 Discrepancy Checking below.
-
-
context: This object may supply a number of fields providing additional context for the normalization record. The fields you include for a normalization record may vary depending on purpose:
-
AI Analysis: When term-based matching, AI models analyze the
source_text,age,sex, andicd10_codesfields to better understand the context of the input term and find optimal lexical matches. For more information on how these fields are used, see 4.2 Input Term Transformation and 4.4 AI Context Analysis below.The supplied source_text is of particular importance for AI analysis. For guidelines on populating this field, see 4.1.2 Source Text Values below.
-
Record Tracking: In all situations, the
use_count,application_id,facility_id,encounter_id,document_id, andproject_idfields enable you to track any applicable record details from partner applications in the normalization record. These fields are not used for lexical matching, but they are always echoed back in the response.
-
1.3.7 Score
When performing normalization, this is a decimal value representing the IMO Precision Normalize API's confidence in a match between a lexical and a normalization record's supplied input. This is a value from 0 to 1, specified using up to 3 decimal places. Higher scores indicate a better match, with a value of 1 representing an exact match.
For each normalization record in a response payload, the items.score field states the score assigned to each returned lexical. When term-based matching, the items array may return multiple lexical matches with varying degrees of confidence, sorted in descending order by score. When code-based matching, the items array returns at most a single lexical match with a score of 1.
How you should interpret the score for a given lexical match depends on your risk tolerance and use case. For example, data used for a clinical end-user application (e.g. interoperability messages) requires a higher degree of scrutiny than those that will be used for aggregate data analytics. As a general rule of thumb, IMO recommends that you accept lexical matches used for clinical end-user applications at 0.98 or above, and for aggregate data analytics at 0.90 or above.
You might also adopt a workflow incorporating manual review of lexical matches according to the following recommended guidelines:
- 1.0 – 0.98: Automatically accept without review.
- 0.90 – 0.979: Automatically accept after minimal review.
- 0.85 - 0.899: Additional clinical review needed. The effort to rationalize information may not be worth the number of records managed.
- < 0.85: Accept only in exceptional cases. Efforts to rationalize the information may be costly.
2 Getting Started
The following sections provide basic guidance on getting started with the IMO Precision Normalize API:
- 2.1 Prerequisites
- 2.2 Base URL and Environments
- 2.3 Authentication
- 2.4 Payload Summary
- 2.5 Match Field Preference
2.1 Prerequisites
Before working with the IMO Precision Normalize API, you may need to obtain or confirm access to each of the following:
2.1.1 Client ID and Secret
Authentication for the IMO Precision Normalize API is performed using OAuth 2.0 Bearer tokens, as described in 2.3 Authentication below. In order to retrieve a Bearer token, you will first need to obtain a Client ID and Secret, either from IMO Health Customer Support or by manually creating a Trial App from the Developer Portal.
To create a trial app and generate your own Client ID and Secret, perform the following steps:
-
Log in to the Developer Portal.
If you do not have login credentials for the portal, please contact IMO Health Customer Support for assistance. -
At the upper-right corner of the portal, click the Key (My Credentials) icon.
The Credentials screen appears. -
Click the +New Trial button.
The Create Trial App screen appears. -
Enter a Name for your application and in the API Products section, select the Normalize option.
-
At the bottom-right corner of the screen, click the Create Trial App button.
The Credentials screen appears and displays a notification that your Trial App will shortly be created. -
After several minutes, Refresh the credentials screen.
The new Trial App appears as an entry in a tabular interface. -
Beneath the Operations column, click the Eye (View) icon next to your Trial App.
The Trial <Name> screen appears. -
In the Credential section, click the Show links next to the Client Key and Client Secret entries.
Record the displayed values. You may supply these values as your Client ID and Secret when performing authentication, as described 2.3 Authentication below.
2.1.2 USCDI Access
In order to view USCDI (United States Core Data for Interoperability) code mappings for IMO lexicals or to filter lexicals by USCDI fields, your organization must confirm your USCDI licensing with IMO Health. Once confirmed, USCDI access can be granted per Client ID. If your Client ID has not yet been granted USCDI access, in response payloads the mappings object will exclude the uscdi field for returned lexicals and you will receive an error if you attempt to use the filters preference to filter results by USCDI fields.
2.2 Base URL and Environments
The IMO Precision Normalize API includes the following environments and corresponding base URLs:
-
Sandbox: When performing initial integration testing, you should send requests to the Sandbox environment. This is a scaled-down version of the Production environment intended for application development requests that are not considered against usage metering. Requests to the Sandbox environment are sent to the following base URL:
https://api-sandbox.imohealth.com/
-
Production: After integration testing, you should send all requests pertaining to normal operations to the Production environment. Requests to the Product environment are sent to the following base URL:
https://api.imohealth.com/
2.3 Authentication
The IMO Precision Normalize API performs authentication using OAuth 2.0 bearer tokens, which you must supply in the Authorization header of all normalization requests. You can retrieve a Bearer token using the following operation, the body of which must supply a valid Client ID and Secret, as described in 2.1 Prerequisites above:
POST /oauth/token
The response body will supply a Bearer token (access_token) and a time until expiry in seconds (expires_in). IMO Bearer tokens expire anywhere from 16 to 24 hours after retrieval, depending on how recently the token cache has been refreshed. For a full description of this operation, please refer to the REFERENCE DOCUMENTATION tab.
The following snippet demonstrates a cURL request to the authentication endpoint:
curl -u ": " --data "grant_type=client_credentials&audience=https://api.imohealth.com" "https://api.imohealth.com/oauth/token"
A response payload to the above request would appear similar to the following:
{
"access_token": ,
"scope": "normalizeresults normalize nlp.deidentification.read nlp nlp.fhir.read normalize.enrichment.problem",
"expires_in": 86400,
"token_type": "Bearer"
}
2.4 Payload Summary
The following sections summarize the basic structure of request and response payloads for Enrichment normalization operations. This summary briefly describes each available payload field and its purpose in order to provide you with some initial context for when they are discussed in other portions of this guide. For an exhausitive description of each available payload field, please refer to the REFERENCE DOCUMENTATION tab.
2.4.1 Request Payload
| Description | Request Structure |
|---|---|
|
{
client_request_id,
session_id,
preferences: {
match_field_pref,
threshold,
discrepancy_check,
size,
distinct_field,
transformations: [...],
filters: [...]
},
requests: [
{
record_id,
domain,
input_term,
input_code,
input_code_system,
context: {
source_text,
icd10_codes,
age,
sex,
use_count,
application_id,
facility_id,
encounter_id,
document_id,
project_id
}
}
]
}
|
2.4.2 Response Payload
| Description | Response Structure |
|---|---|
|
{
summary: {count, error count},
request_id,
client_request_id,
session_id,
response_time,
requests: [
{
record_id,
domain,
input_code,
input_code_system,
input_term,
transformed_term,
context: {...},
response: {
match_field,
domain,
transformed_term,
explanation,
error_message: [...],
items: [
{
lexical_code,
lexical_title,
default_lexical_code,
default_lexical_title,
score,
certainty,
metadata: {
mappings: {...},
flags: {...},
subdomains: [...]
},
discrepancy: {...}
}
],
}
}
],
preferences: {...}
}
|
2.4.3 Response Metadata Mappings
For each lexical returned in an IMO Precision Normalize API response payload, the metadata.mappings object provides a breakdown of the clinical codes mapped to the default variant of that lexical. Each field in the mappings object corresponds to a particular code system supported by the lexical's domain and defines a child object that may contain up to two fields:
-
codes: If the code system has one or more codes mapped to the lexical, then its object defines a codes array containing one object for each mapped code from that system. If the code system has no codes mapped to the lexical, its codes array is sent blank and the
map_contextfield may supply an explanation.For example, in the followings mappings object, the snomedInternational field defines a codes array identifying a single mapped code from the SNOMED International code system:
"metadata": { "mappings": { "snomedInternational": { "codes": [ { "code": "29857009", "map_type": "Preferred primary", "mesh_code": "D002637", "relationship_type": "Same as", "title": "Chest pain" } ] }, ... -
map_context: If the code system has no codes mapped to the lexical, then its object may include a map_context field describing the reason for the lack of code mappings. For example, in the following mappings object, the icd10cm field reports that the ICD-10-CM code system had no code mappings for the lexical:
"metadata": { "mappings": { "icd10cm": { "codes": [], "map_context": "INSUFFICIENT INFORMATION" }, ...The map_context field is always excluded for code systems with at least one mapping for the lexical. If map_context is included, it will supply one of the following values:
- INSUFFICIENT INFORMATION - The lexical does not represent a specific enough clinical concept to assign a code from the system.
- NON-CODEABLE - The lexical is not codeable to the code system.
The content supplied in each codes object depends on the applicable code system. For details on the fields available in each system's codes object, please refer to the REFERENCE DOCUMENTATION tab.
2.5 Match Field Preference
When defining a request payload, a particularly imporant consideration is the preferences.match_field_pref field, which determines the method the API will use to identify lexical matches for all normalization records suppplied in the request. Your value for this field determines whether the API performs term-based matching, code-based matching, or attempts one method before falling back to the other.
The match_field_pref field can be set to any of the following values:
-
input_term - The API will perform term-based matching only. For this option, each normalization record must include the
input_termfield. The input_code field is ignored for lexical matching. For details on how the API performs term-based matching, see 4 Term-Based Matching below. -
input_code - The API will perform code-based matching only. For this option, each normalization record must include the
input_codeandinput_code_systemfields. The input_term field is ignored for lexical matching. For details on how the API performs code-based matching, see 3 Code-Based Matching below. -
input_term_first - The API will first attempt term-based matching. If no term-based lexical matches within the specified
thresholdare found or if the request did not include a valid input term, then the API will attempt code-based matching. If even one term-based match within the threshold was found, then code-based matching is skipped.For this option, each normalization record must include either:
input_term; bothinput_code and input_code_system; or all three fields.This is the default value if match_field_pref is excluded from the request.
-
input_code_first - The API will first attempt code-based matching. If no code-based lexical match is found or if the request did not include a valid input code and system, then the API will attempt term-based matching. If a code-based match was found, then term-based matching is skipped.
For this option, each normalization record must include either:
input_term; bothinput_code and input_code_system; or all three fields.
The match_field_pref field is a request-level preference, meaning one of the above values applies to all normalization records in the entire request. However, by using one of the "first" approaches (e.g. input_term_first), you have the flexibility to define payloads that include a mix of normalization records intended for either matching method.
When using a "first" value, if a given normalization record in your payload includes only the input_term field or only the input_code and input_code_system fields, then for that record the API will attempt only the one possible normalization method and skip the other. If instead you supply all three of the input_term, input_code, and input_system fields for a normalization record, then a "first" approach allows the API to use either the term or code as a backup for normalization if one of the supplied input values turns out to be invalid.
When supplying all three of the input_term, input_code, and input_system fields, keep in mind that the domain value supplied for the normalization record applies only when term-based matching and should be specified as appropriate for your input_term. Code-based matching may return a lexical from any domain, regardless of the specified domain.
3 Code-Based Matching
In the IMO Precision Normalize API, code-based matching attempts to normalize a supplied clinical code by returning the one IMO lexical that best represents its clinical concept. Code-based matching is commonly used to confirm the correct title of a clinical concept for which you possess the code or when you want to view corresponding codes from alternate clinical code systems.
In order to perform code-based matching, in your request payload, a normalization record must specify both an input_code and input_code_system. The response will return a single lexical mapped to the supplied code, providing both a normalized title for the clinical concept and a list of all other clinical codes mapped to that lexical from every applicable code system. When code-based matching, the API can return a lexical from any domain, regardless of the endpoint or the normalization record's domain preference.
The following sections describe code-based matching in detail:
- 3.1 Code-Based Matching Logic
- 3.2 Code-Based Matching Request Payload
- 3.3 Code-Based matching Response Payload
3.1 Code-Based Matching Logic
When performing code-based matching for a normalization record, the API performs the following steps:
-
Validate the Input: The API confirms that the normalization record supplied a valid
input_codeandinput_code_system. The input_code_system must be one of the following values representing a single industry standard clinical code system, and the input code should be a single alphanumeric identifier from the specified system:ICD-10-CM | ICD-9-CM | SNOMED CT | ICD-10-PCS | LOINC | CPT | HCPCS | RXNORM | NDC | CVX | UMLS | IMO
For example, if your input_code_system was "ICD-10-CM", you might specify an input_code of "R07.9", which represents the clinical concept "Chest pain, unspecified".
Note: For the "IMO" input code system, the input_code value can be the Lexical Code for any IMO lexical. The API will attempt to identify and return the indicated lexical. Lexicals codes can be found in IMO Precision Normalize API response payloads and a number of other IMO tools.
-
Match a Clinical Code: The API attempts to find an exact match between the supplied
input_codeand IMO's library of clinical codes. The supplied code must belong to the specifiedinput_code_systemand it must exactly match a formal identifier from that system. The match is not case-sensitive.The API will parse out any preceding or trailing space included in the input_code field, but otherwise the supplied string is matched as-is. A single additional or misentered character will prevent matching. For example, " r07.9 " would result in a valid code match, but any of the following values would not: "r 07.9", "-r07.9", "1. r07.9", "r7.9", "r07.90"
-
Choose the best Lexical: The API returns the one lexical mapped to the matched code that has been identified by IMO's subject matter experts as best representing the same clinical concept. In the response payload, the lexical match is assigned a
scoreof 1.In general, this will be a lexical whose relationship to the code has a Map Type of "Preferred Primary" and a Relationship Type of "Same as". This may be a lexical from any domain, regardless of the
domainvalue supplied in the request.
Exception - Retired Code Matching
IMO Health takes great care to update our clinical code library to account for newly added and retired codes. When a Problem domain clinical code is retired, IMO Health maps the retired code to its closest active equivalent. If a normalization record specifies a retired Problem domain code, the response will return the lexical associated with the closest active equivalent code. When this occurs, the response payload will not appear any different, but you will notice that the mappings object does not return the actual input_code supplied in the request, but instead its active equivalent. Response payloads never return retired clinical codes.
Retired code matching is only applicable to the Problem domain. A normalization record that specifies a retired code from any system unsupported by the Problem domain will fail to match a lexical.
3.2 Code-Based Matching Request Payload
The following example request payload performs code-based matching for two normalizations records, respectively seeking normalization for the ICD-10-CM code "R07.9" and the CPT code "71047":
{
"client_request_id": "A5B2C1D9",
"preferences": {
"match_field_pref": "input_code"
},
"requests": [
{
"record_id": "ABCD1234",
"domain": "Problem",
"input_code": "R07.9",
"input_code_system": "ICD-10-CM"
},
{
"record_id": "4321ZYXW",
"domain": "Problem",
"input_code": "71047",
"input_code_system": "CPT"
}
]
}
Each normalization record included the mandatory input_code, input_code_system, and domain fields. The domain field must always be included with a valid value, even though it is ignored for code-based matching. The examples above specify a domain value of "Problem" as this is the only permissible value for the Enrichment endpoint, but a code-based matching result is the same regardless of the specified domain.
The preferences.match_field_pref value of "input_code" indicates that the API should attempt only code-based matching for this request's normalization records. For code-based matching, all other preferences fields and the context object are ignored for purposes of lexical matching, and so were excluded from this payload. We could alternatively have opted to supply a context object in order to include the the optional record tracking fields (use_count, application_id, facility_id, encounter_id, document_id, project_id).
The input_term field is not used for code-based matching and so was excluded. Alternatively, if we were using a match_field_pref of "input_code_first", we could have opted to supply an input_term in order to use term-based matching as a backup.
3.3 Code-Based Matching Response Payload
The following is a response payload for the code-based matching request defined above:
Code-Based Matching Response
{
"summary": {
"count": 2,
"error_count": 0
},
"request_id": "67676ab7-ab6a-7b67-67a6-b7a6b7ab6aba",
"client_request_id": "A5B2C1D9",
"response_time": 7,
"requests": [
{
"record_id": "ABCD1234",
"domain": "Problem",
"input_code": "R07.9",
"input_code_system": "ICD-10-CM",
"transformed_term": "",
"response": {
"match_field": "input_code",
"domain": "problem",
"custom_mapped": false,
"transformed_term": "",
"explanation": "",
"items": [
{
"lexical_code": "732485",
"lexical_title": "Chest pain, unspecified",
"default_lexical_code": "85191",
"default_lexical_title": "Chest pain",
"score": 1,
"certainty": "",
"metadata": {
"mappings": {
"icd10cm": {
"codes": [
{
"code": "R07.9",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "CIR012",
"ccsr_description": "Nonspecific chest pain"
}
],
"hcc": []
},
"map_type": "Preferred primary",
"relationship_type": "Same as",
"title": "Chest pain, unspecified"
}
]
},
"icd9cm": {
"codes": [
{
"code": "786.50",
"map_type": "Preferred primary",
"title": "Chest pain, unspecified"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "29857009",
"map_type": "Preferred primary",
"mesh_code": "D002637",
"relationship_type": "Same as",
"title": "Chest pain"
}
]
},
"umls": {
"codes": [
{
"code": "C0008031",
"title": "Chest Pain"
}
]
}
},
"flags": {
"age_indicator": "",
"is_icd10cm_refinable": true,
"sex_indicator": ""
}
}
}
]
}
},
{
"record_id": "4321ZYXW",
"domain": "Problem",
"input_code": "71047",
"input_code_system": "CPT",
"transformed_term": "",
"response": {
"match_field": "input_code",
"domain": "procedure",
"custom_mapped": false,
"transformed_term": "",
"explanation": "",
"items": [
{
"lexical_code": "1064351",
"lexical_title": "X-ray of chest, three views",
"default_lexical_code": "1064351",
"default_lexical_title": "X-ray of chest, three views",
"score": 1,
"certainty": "",
"metadata": {
"mappings": {
"cpt": {
"codes": [
{
"code": "71047",
"long_title": "Radiologic examination, chest; 3 views",
"map_type": "Preferred primary",
"title": "X-ray exam chest 3 views"
}
]
},
"hcpcs": {
"codes": []
},
"icd10pcs": {
"codes": [
{
"code": "BW03ZZZ",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "IMG009",
"ccsr_description": "Plain radiography"
}
]
},
"long_title": "Plain radiography of chest",
"map_type": "Preferred primary",
"relationship_group": "0",
"title": "Plain radiography of chest"
}
]
},
"loinc": {
"codes": [
{
"code": "36298-8",
"map_type": "Preferred primary",
"title": "Views 3:Find:Pt:Chest:Doc:XR"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "399208008",
"map_type": "Preferred primary",
"mesh_code": "",
"title": "Plain X-ray of chest"
}
]
},
"umls": {
"codes": [
{
"code": "C0039985",
"title": "Plain chest X-ray"
},
{
"code": "C1524624",
"title": "Views 3:Find:Pt:Chest:Doc:XR"
},
{
"code": "C2457026",
"title": "Plain Radiography of Chest"
}
]
}
},
"flags": {
"is_chargeable": false,
"is_historical": true,
"is_orderable": true,
"is_performable": true,
"is_resultable": false,
"sex_indicator": ""
}
}
}
]
}
}
],
"preferences": {
"match_field_pref": "input_code",
"size": 3
}
}
In the response, the requests array returned one object corresponding to each normalization record supplied in the request. In each of these objects, the items array includes one child object describing the lexical that was matched to the supplied input_code. The items.default_lexical_title states the IMO normalized text for the clinical concept represented by the input_code, and the items.metadata.mappings array lists each of the clinical codes mapped to the lexical from all applicable code systems.
For the first record, the API identified the input code of "R07.9" as a valid identifier for the input code system of "ICD-10-CM", and then returned lexical "732485 - Chest pain, unspecified" from the Problem domain as the best representation of the applicable clinical concept.
For the second record, the API identified the input code of "71047" as a valid identifier for the input code system of "CPT", and then returned lexical "1064351 - X-ray of chest, three views" from the Procedure domain as the best representation of the applicable clinical concept.
4 Term-Based Matching
In the IMO Precision Normalize API, term-based matching attempts to normalize a supplied input term by returning one or more IMO lexicals that best match the clinical intent of the input. Term-based matching is most commonly used to translate a medical term found in patient data to a standardized lexical title and to identify the codes associated with the corresponding clinical concept.
In order to perform term-based matching, in your request payload, a normalization record must specify an input_term and may optionally include additional context that may assist in finding optimal lexical matches. The response will return one or more lexicals matched with varying degrees of confidence to the supplied term, each providing a normalized title for a clinical concept and a list of all clinical codes mapped to that lexical from every applicable code system. When term-based matching for the enrichment endpoint, the API can only return lexicals from the Problem domain.
When performing term-based matching for a normalization record, the API considers the following factors:
- 4.1 Request Input for Term-Based Matching
- 4.2 Input Term Transformation
- 4.3 Input Term Matching
- 4.4 AI Context Analysis
- 4.5 USCDI Filters
- 4.6 Distinct Field Check
- 4.7 Candidate Lexical Ranking
- 4.8 Size and Threshold Limits
- 4.9 Discrepancy Checking
4.1 Request Input for Term-Based Matching
The following fields from the request payload are relevant to term-based matching:
-
preferences: This request-level object defines a number of optional term-matching preferences applicable to all normalization records included in the request payload:
- size: Specifies the maximum quantity of lexical matches that should be returned for each normalization record. See 4.8 Size and Threshold Limits below.
- threshold: Specifies a minimum score that a lexical match must have in order to be returned in the result. See 4.8 Size and Threshold Limits below.
- discrepancy_check: Determines whether the response should report whether there is a mismatch between any supplied
input_codeand the highest scoring lexical returned for the normalization record. See 4.9 Discrepancy Checking below. - distinct_field: Determines whether the response is permitted to return multiple lexicals linked to the same default variant. See 4.6 Distinct Field Check below.
- transformations: Defines one or more search and replace operations that should be performed on each input_term before attempting to match lexicals. See 4.2 Input Term Transformation below.
- filters: Defines USCDI filter criteria that limits which lexicals can be returned in the results. See 4.5 USCDI Filters below.
-
input_term: For each normalization record, this field specifies the title of a medical term that you want to normalize to a lexical. This is required for term-based matching. For guidelines on populating this field, see 4.1.1 Input Term Values below.
-
domain: For each normalization record, this field specifies the domain from which the API can match lexicals to the
input_term. This is required for term-based matching. For the Enrichment endpoint, the domain must always be set to "Problem". -
context: For each normalization record, the
source_text,age,sex, andicd10_codesfields in this object are used for enriched AI context analysis and term transformation. See 4.2 Input Term Transformation and 4.4 AI Context Analysis below.The supplied source_text is of particular importance for AI analysis. For guidelines on populating this field, see 4.1.2 Source Text Values below.
4.1.1 Input Term Values
The input_term field should describe a discrete medical problem, complaint, symptom, or finding. It should refer to a single problem "entity" with no extraneous words or context. When supplying an input term, please keep in mind the following considerations:
-
You may include any number of words up to a total of 500 characters.
-
Exclude special characters.
-
Avoid acronyms and abbreviations when possible.
-
Avoid sending vague terms like "Vaccination", "Follow-up", "General health", and "Mood".
-
Split conjunctive terms into separate normalization records.
For example, "Right knee effusion and chronic bursitis" should be split into two separate input terms: "right knee effusion" and "chronic bursitis".
Good Input Term examples:
- Chest pain
- Muscular pain in legs
- Diabetes mellitus type 2 with CKD
- Constipation due to pain medication
- Hyperlipidemia
- Lung nodule
- Headaches
Bad Input Term examples:
- I discussed the various treatment options including the option to do nothing at all. I reviewed the side effects of all medications prescribed by me as listed in the PDR and package insert.
- Family History
- Pre-Surgical Preparation
- 1. Left ear fullness and presumed Sudden Hearing Loss in Left Ear:
- 1. Increase dose of BuSpar to 10 mg TID
- Oral Health
4.1.2 Source Text Values
In the context object, the source_text field may supply the sentence or surrounding text in which the input_term was found. When supplying source text, please keep in mind the following considerations:
-
Include Relevant Context Only
- Include only the sentences directly related to the input term.
- Include any modifiers specifying chronicity, laterality, severity, or treatment details.
- Include any assertion status applicable to the input term (i.e. present, negated, uncertain).
- Avoid any billing details, timestamps, or other boilerplate text.
- Avoid large, unrelated narrative text blocks.
-
Pre-process for Quality
- Try use any applicable units consistently.
- Try to use consistent whitespace guidelines for word or paragraph separation.
- Remove any junk or irrelevant phrases.
- De-identify any protected health information.
- Chunk long stretches of text into structured sections.
-
Limit Context Size: To help reduce context rot, the optimal size for the source text should be between 500 - 1,000 characters or < 1,000 tokens.
-
Escape Sequences: For complex textual input requiring multiple lines, use the following escape sequences as needed:
- \n for newline
- \t for tab
- \r for carriage return
- \\ for backslash
Good Source Text examples
- Example 1
- Input term: Musculoskeletal pain
- Context: Sharp pain likely musculoskeletal, possibly related to weightlifting. - Modify exercise routine by reducing upper extremity weightlifting and incorporating swimming and walking.
- Example 2
- Input term: Alzheimer's disease
- Context: Moderate Alzheimer's and dementia confirmed. Late onset Alzheimer's noted.
- Example 3
- Input term: Excessive facial hair growth
- Context: Likely related to PCOS and hormonal imbalance - Prescribe Spironolactone 50 mg twice daily for six months, monitor response and adjust dose if necessary.
Bad Source Text examples
- Example 1
- Input term: Dyspnea
- Context: Slight elevation noted, possibly related to dehydration or fasting. - Repeat hemoglobin test in 6 weeks.
- Example 2
- Input term: Abdominal Pain
- Context: The chest discomfort could be related to a number of conditions, including heart disease. The presence of a systolic murmur is concerning and requires further investigation.
4.2 Input Term Transformation
Term-based matching may perform any of the following actions to transform each normalization record's supplied input_term. When multiple transformations are applicable, these actions are applied in the following sequence:
When an input term is transformed for any of these reasons, in the response, the normalization record's transformed_term field reports the final state of the term, which may have been arrived at after performing multiple transformation actions. The response.explanation field will report any decisions taken by the API to transform the term due to spelling mistakes or AI term transformation, but this field does not describe preference transformations.
4.2.1 Preference Transformations
...
"preferences": {
"transformations": [
{
"type": "string_replace",
"location": "*",
"from": "poc",
"to": "point of care",
"case_sensitive": false
},
{
"from": ["(NORTH)", "1. ", "2. "],
"to": ""
}
],
...
The request's preferences.transformations array may include one or more objects defining search and replace operations that should be performed on each normalization record's supplied input term before attempting to match lexicals. Preference transformations are often used to remove or correct expected errors and extraneous content from your input terms, such as department names or unexpanded acronyms. If these operations result in changes to the input term, then lexical matching proceeds using the revised input term text. If no changes are made to the input term, then lexical matching proceeds using the initially supplied input term text.
In each transformations object, the following fields define the parameters of a single search and replace operation:
-
type: One of the following values determining how many strings to search for:
- string_replace - Search for a single string in the input term. The from value must define a single string that will be transformed to the to value.
- multiple_string_replace - Search for multiple strings in the input term. The from value must define an array of one or more strings, any and all of which will be transformed to the to value. If type is excluded, this is the default value.
-
location: One of the following values determining the portion of the input term that will be searched for any of the from strings:
- beginning - Search only at the beginning of the input term.
- end - Search only at the end of the input term.
- * - Search anywhere in the input term. This option may identify multiple string matches in the input term. If location is excluded, this is the default value.
-
from: One or more strings to find in the input term. If type is set to "string_replace", this should be a single string value. If type is set to "multiple_string_replace", this should be an array of one or more strings.
Only whole string matching is supported. For example, "blue" does not match "blueish". When the search location is "beginning" or "end", the API may find a match by parsing out any preceding or trailing space in the input term, but otherwise the beginning/end of the input term must match a from string exactly. When the search location is "*", the API may also find matches by parsing out any extraneous special characters not included in the from strings.
-
to: The replacement string. Text matched to any of the from strings in the designated location will be replaced with this to string. Setting the to field to a blank string ("") deletes the matched text. If to is excluded, this is set to a blank string by default.
-
case_sensitive: Determines whether from strings are matched to input term text on a case-sensitive basis. If set to "false", the search is not case-sensitive, meaning "blue" matches "Blue". If set to "true, the search is case-sensitive, meaning "blue" will not match "Blue". Regardless of this setting, the replacement to string is always applied using the entered case. If case_sensitive is excluded, this is set to "false" by default.
When multiple transformations objects are included, all specified operations are performed in order from top to bottom, with each subsequent transformation taking as input the result of the the previous transformation. For example, consider an initial input term of "quick brown fox". If you define two transformations objects, with the topmost changing "brown" to "red" and the bottom changing "red" to "purple", the final transformed term will be "quick purple fox".
4.2.2 Spelling Mistakes
Before attempting to match lexicals to a normalization record, the API will correct any common spelling mistakes identified in the input term. For example, a value of "chast pain" will be corrected to "chest pain".
4.2.3 AI Term Transformation
When matching candidate lexicals to a normalization record, the API can choose to expand a low-scoring pool of candidate lexicals by using AI models to revise the input term to a more relevant medical term and attempting to match lexicals against that term. For example, an input term of "busted clavicle" would not in itself match well to any IMO lexical, but an AI model would be able to infer that this phrase may refer to the medical term "Clavicle Fracture" and so transform it. When a normalization record includes the source_text field, the AI models can also use this context to help decide which clinical concept was implied by the input term.
For the Enrichment endpoint, AI analysis is woven into all stages of the term-based matching process. AI term transformation may be attempted at several points and considers both the source text and disease-specific knowledge repositories. The Enrichment endpoint can also clean the input term by rearranging word sequence, or by stripping out special characters, punctuation, and irrelevant words or characters.
4.3 Input Term Matching
To build a list of candidate lexical matches with a normalization record's input term, a major component of the term-based matching process involves comparing the text of the supplied input_term (or transformed input term) to IMO lexical Titles. This process may involve several techniques:
-
Simple text matching: The API can look for text matches between a lexical's title and either the entire text of the input term or individual words within it. This process is assisted by lookups to internal libraries that help map common input text patterns to lexical titles, such as certain acronyms (e.g. "ADD" interpreted as "Attention deficit disorder") and numeric representations (e.g. "II" interpreted as "2").
-
Semantic matching: For Problem domain lexical matching only, the API can find matches with lexical titles by trying semantic variations of the input term. This technique does not literally transform the input term, but instead attempts to match variations of the input text using different words for the same concepts and excluding potentially irrelevant noise. For example, an input term of "pelvic rim fracture" could be matched to a lexical titled "Pelvic ring fracture".
-
Domain Relevance Filter: For Problem domain lexical matching only, the API will fail return any lexicals if the input term is deemed irrelevant to the clinical domain. This process is sometimes referred to as "junk detection" and prevents the API from returning lexicals that may share superficial textual similarities with the input term, but are otherwise unrelated. For example, if a normalization record is erroneously sent with an input term of "misc", the domain relevance filter prevents the API from returning a lexical such as "Miscellaneous certificate requested".
If the input term is deemed irrelevant by the domain relevance filter, the
response.explanationfield will report the following value:"No identifiable problem domain clinical concept in input term - returning no results."
4.4 AI Context Analysis
...
"context": {
"source_text": "The patient was born with a diaphragmatic hernia",
"icd10_codes": ["Q79.0"],
"age": "0",
"sex": "M"
}
...
When lexical matching, the Enrichment endpoint always uses AI models to consider the context of the input term when identifying and ranking lexicals as potential matches for a normalization record. Enrichment AI context analysis considers the following fields from the context object, each of which should be thought of as contributing factors to the ultimate decision to rank and return lexicals as optimal matches for the input term. No one field's input should be thought of as having decisive sway or as a disqualifying factor for a particular lexical.
-
source_text: The sentence or surrounding text in which the
input_termwas found. The API uses this textual context to help interpret the input term and better understand its clinical intent. This analysis includes comparison of both input term and source text with disease-specific knowledge repositories to help determine the relevant condition. The understanding derived from analyzing the source text enables the API to identify optimal lexical matches representing the best and most specific interpretation of the input term. -
age: The patient's age as a whole number. The API may use this value to match lexicals representing age-specific conditions. This is not treated a hard filter, but rather is used to help boost the ranking of any candidate lexicals associated with the supplied age. In the response, returned lexicals report any association with a particular age range in the
metadata.flags.age_indicatorfield. Age-specific context analysis helps ensure that the API returns the most specific lexicals applicable to the relevant clinical context.For example, a lone input term of "BMI 95th percentile" will typically return lexical "1003691 - High body mass index" as top match. However, the same input term supplied alongside an age of 2 will typically return "68209034 - Body mass index (BMI) greater than or equal to 95th percentile for age in pediatric patient" as top match.
-
sex: The patient's biological sex, either male ("M") or female ("F"). The API may use this value to match lexicals representing sex-specific conditions. This is not treated a hard filter, but rather is used to help boost the ranking of any candidate lexicals associated with the supplied sex. In the response, returned lexicals report any association with a particular sex in the
metadata.flags.sex_indicatorfield. Sex-specific context analysis helps ensure that the API returns the most specific lexicals applicable to the relevant clinical context.For example, a lone input term of "infertility" will typically return lexical "370613 - Infertility" as top match. However, the same input term supplied alongisde a sex of "M" will typically return the lexical "79103 - Male infertility" as top match.
-
icd10_codes: One or more ICD-10-CM codes that are believed to correspond to the
input_termor its context. The API may use this field to match lexicals mapped to any of the supplied codes. This is not treated as a hard filter, but rather is used to help boost the ranking of any candidate lexicals associated with one or more of these codes. This field is most commonly used when normalizing entities and codes extracted from an external NER system.Note: The
context.icd10_codesfield is completely distinct from theinput_codefield. The input_code is never used for context analysis and the icd10_codes field is never used for code-based matching or discrepancy checking.
4.5 USCDI Filters
...
"preferences": {
"filters": [
{
"field": "uscdi.profiles.valueset_oid",
"operator": "eq",
"value": "2.16.840.1.113762.1.4.1186.8"
},
{
"field": "uscdi.profiles.data_class",
"operator": "eq",
"value": "Medications"
}
],
...
The request's preferences.filters array may include one or more objects each defining a filter criterion for USCDI code mappings that limits which lexicals can be returned in the results. When USCDI filter criteria is defined for a request, a lexical can only be returned if it is mapped to a USCDI code that meets all supplied criteria. USCDI filters can only be defined if your organization has confirmed your USCDI licensing with IMO Health, as described in 2.1.2 USCDI Access. If you include the filters array without confirming your licensing, the response will return an error.
A maximum of 4 filter objects may be included in the filters array, with each object typically filtering on a different USCDI field. Multiple filter objects are applied as AND statements, meaning a lexical will only be returned if it matches all criteria defined in every object.
In each filters object, the following fields define the parameters of a single filter criterion:
-
field: The USCDI field for which you want to define a filter criterion. This must be one of the following values:
uscdi.profiles.valueset_oid | uscdi.profiles.hrsn_domain | uscdi.profiles.data_element | uscdi.profiles.data_class
-
operator: The comparison operator to apply to the value for the applicable field. Currently, only "eq" (equals) is supported, meaning the field must exactly match the value.
-
value: A single, standard USCDI value for the specified field. The supplied value must correspond exactly to a supported field value documented in the official USCDI specification, including casing.
For the uscdi.profiles.valueset_oid field, only the following values are supported:
2.16.840.1.113762.1.4.1186.8 | 2.16.840.1.113762.1.4.1186.8 | 2.16.840.1.113883.4.642.3.208 | 2.16.840.1.113883.4.642.40.2.48.8 | 2.16.840.1.113883.4.642.40.2.48.21 | 2.16. | 40.1.113883.4.642.40.2.48.21 | 2.16.840.1.113883.4.642.40.2.48.26 | 2.16.840.1.113883.4.642.40.2.48.22 | 2.16.840.1.113883.4.642.40.2.48.24 | 2.16.840.1.113762.1.4. | 247.146 | 2.16.840.1.113762.1.4.1247.83 | 2.16.840.1.113762.1.4.1247.242 | 2.16.840.1.113762.1.4.1247.157 | 2.16.840.1.113762.1.4.1247.3 | 2.16.840.1.113762.1.4.1247.23 | 2.16.840.1.113762.1.4.1010.6 | 2.16.840.1.113762.1.4.1186.8 | 2.16.840.1.113883.4.642.3.232
4.6 Distinct Field Check
The request's preferences.distinct_field field can be used to limit the results for each normalization record to only one match per default lexical. In other words, this preferences determines whether a normalize record can return multiple lexicals linked to the same default_lexical_code.
In any response, the items array for each normalization record lists one or more objects representing lexicals matched to the input. Each of these objects returns unique identifiers for both the lexical that directly matched the input (items.lexical_code) as well as its default variant (items.default_lexical_code). The distinct_field preference enables you to specify which of these fields should be used to determine whether a given lexical match is unique, and so filter out any "duplicates".
The distinct_field preference can be set to either of the following values:
-
lexical_code - The API uses the lexical_code field to determine whether a candidate lexical match is unique. This option effectively does not filter candidate lexicals at all and simply allows the API to return lexicals regardless of their linked default_lexical_code. This means that a normalization record can return multiple lexical matches linked to the same default_lexical_code.
This is the default value if distinct_field is excluded from the request.
-
default_lexical_code - The API uses the default_lexical_code field to determine whether a candidate lexical match is unique. When multiple lexicals matches are linked to the same default_lexical_code, the response can include only the highest scoring match linked to that code. The response may still include other lexical matches linked to different default_lexical_code values.
In effect, this option ensures that a normalization record will only return one matched lexical per default_lexical_code.
For example, consider a situation in which a normalization record has the following candidate lexical matches:
| Lexical Code/Lexical Title | Default Lexical Code/Default Lexical Title | Score |
|---|---|---|
| 324992 - Feeling unwell | 324999 - Feeling poorly | 0.998 |
| 324999 - Feeling poorly | 324999 - Feeling poorly | 0.887 |
| 325751 - Generally unwell | 325751 - Generally unwell | 0.856 |
If distinct_field were set to "lexical_code", then all three candidate lexicals could be returned as separate results if size and threshold limits permitted. If distinct_field were instead set to "default_lexical_code", then only lexicals 324992 and 325751 would remain candidates. Lexical 324999 could not be returned as a separate result, as it would be filtered out as a lower scoring duplicate linked to the same default lexical as another result, even though it is itself the applicable default lexical.
| distinct_field = lexical_code | distinct_field = default_lexical_code |
|---|---|
{
"lexical_code": "324992",
"lexical_title": "Feeling unwell",
"default_lexical_code": "324999",
"default_lexical_title": "Feeling poorly",
"score": 0.998,
...
},
{
"lexical_code": "324999",
"lexical_title": "Feeling poorly",
"default_lexical_code": "324999",
"default_lexical_title": "Feeling poorly",
"score": 0.887,
...
},
{
"lexical_code": "325751",
"lexical_title": "Generally unwell",
"default_lexical_code": "325751",
"default_lexical_title": "Generally unwell",
"score": 0.856,
...
} |
{
"lexical_code": "324992",
"lexical_title": "Feeling unwell",
"default_lexical_code": "324999",
"default_lexical_title": "Feeling poorly",
"score": 0.998,
...
},
{
"lexical_code": "325751",
"lexical_title": "Generally unwell",
"default_lexical_code": "325751",
"default_lexical_title": "Generally unwell",
"score": 0.856,
...
} |
4.7 Candidate Lexical Ranking
After compiling a list of candidate lexical matches for a normalization record, the API ranks all candidates with respect to one another in terms of relative confidence in the match. At this point, the API can adjust the ranking of each candidate lexical based on any of the following considerations. These considerations are only used to determine the relative ranking of candidate lexicals that have already been identified as applicable to the supplied input based on the other factors described in this guide. They are not in themselves used to identify potential matches:
-
Semantic relevance: When ranking Problem domain lexicals, the API uses an AI model to evaluate the semantic relevance of each candidate lexical to the
input_termand any suppliedsource_text. This process judges how well each candidate lexical represents the clinical intent of the input, and then adjusts their relative rankings accordingly. Considering semantic relevance helps prevent the API from returning "false positive" lexicals that superficially resemble the input text, but not the intent. -
Billing code promotion: A candidate lexical can be ranked higher based on the following two criteria relevant to billing related workflows:
-
ICD-10-CM code association: In general, candidate lexicals mapped to an ICD-10-CM code are preferred and ranked above candidate lexicals with no ICD-10-CM code mapping. When term-based matching, one of the primary aims of the Enrichment endpoint is to return a billable code relevant to the supplied input.
-
Lexical specificity: In general, lexicals representing more specific clinical concepts are preferred and ranked above those representing more general concepts. For example, "Closed fracture of left femur, initial encounter" would typically be ranked higher than "Fracture of Femur". For billing related workflows, it is usually ideal to supply the most specific billing code applicable to the patient's condition.
-
At the end of this ranking process, a final score is assigned to each candidate lexical representing the degree of confidence in the lexical match to the normalization record. This score is taken into account when considering the size and threshold limits described below.
4.8 Size and Threshold Limits
To determine the finalized list of lexical matches to return for a normalization record, the API trims the ranked list of candidate lexicals established in 4.7 Candidate Lexical Ranking according to the following request preferences:
-
preferences.threshold: A decimal value defining the minimum score that a lexical match must have in order to be returned in the result. Any candidate lexicals with a score below this value are discarded.
This is a value from 0-1, specified using up to 3 decimal places. An Enrichment normalization request has a default threshold of 0.8.
-
preferences.size: An integer defining the maximum quantity of lexical matches that can be returned for each normalization record. If the quantity of candidate lexicals meeting the threshold limit is greater than the specified size, the API retains only the highest scoring lexicals up to the size limit. When the API must choose between candidate lexicals with equal scores, the response returns the more concise lexical.
An Enrichment normalization request has a default size of 3, but supports from 1-5.
For example, consider a situation in which a normalization record has the following ranked list of candidate lexicals:
| Rank | Candidate Lexical | Score |
|---|---|---|
| 1 | 52807 - Itch | 0.995 |
| 2 | 52808 - Itching | 0.980 |
| 3 | 52810 - Pruritus | 0.860 |
| 4 | 732950 - Pruritus, unspecified | 0.750 |
| 5 | 52876 - Mad itch | 0.640 |
Based on these candidates, below are three possible normalization responses based on different sets of request preferences:
-
threshold=0.700, size=3: The response would return three lexicals: 52807, 52808, and 52810. The threshold limit included 4 candidate lexicals, but the size limit forced the API to drop the 4th and 5th ranked candidates.
"items": [ {"lexical_code": "52807", "lexical_title": "Itch", "score": 0.995, ...}, {"lexical_code": "52808", "lexical_title": "Itching", "score": 0.980, ...}, {"lexical_code": "52810", "lexical_title": "Pruritus", "score": 0.860, ...} ] -
threshold=0.750, size=5: The response would return four lexicals: 52807, 52808, 52810, and 732950. The size limit allowed for 5 lexicals, but the threshold limit forced the API to drop the 5th ranked candidate.
"items": [ {"lexical_code": "52807", "lexical_title": "Itch", "score": 0.995, ...}, {"lexical_code": "52808", "lexical_title": "Itching", "score": 0.980, ...}, {"lexical_code": "52810", "lexical_title": "Pruritus", "score": 0.860, ...}, {"lexical_code": "732950", "lexical_title": "Pruritus, unspecified", "score": 0.750, ...} ] -
threshold=0.996, size=5: The response would return no lexicals as no candidate met the threshold limit.
"items": []
4.9 Discrepancy Checking
...
"items": [
{
"lexical_code": "85191",
...
"metadata": {
"mappings": {...},
"flags": {...}
},
"discrepancy": {
"checked": true,
"found": true,
"type": "Coding",
"message": "Input code does not match with input term result"
}
},
...
If the request's preferences.discrepancy_check field was set to "true", then in the response the first lexical returned in the items array for each normalization record includes a discrepancy object reporting whether there is a mismatch between any supplied input code and the codes mapped to that lexical. This object is only returned for the normalization record's highest scoring lexical match.
The discrepancy object includes the following fields:
-
checked: A boolean value indicating whether a discrepancy check was performed for the lexical. This is set to "true" as long as the normalization record included both an
input_codeandinput_code_system. This is set to "false" if the record was missing either of these fields, or if the lexical was returned by code-based matching. -
found: When checked is true, this is a boolean value indicating whether the API found a discrepancy between the returned lexical and the supplied
input_code. A value of "true" indicates a disrepancy, meaning the request input_code does not appear in theitems.metadata.mappingsobject for the lexical. A value of "false" indicates no discrepancy, meaning the input code does appear in the mappings object.The found field is always set to "false" if checked is "false", or if the input_code or input_code_system were invalid or excluded.
-
type: When found is "true", this is always set to "Coding". When found is false, this is always sent with an empty string.
-
message: When found is "true", this is always set to the following value:
"Input code does not match with input term result"
When found is "false", the message field may alternatively be set to any of the following values:
- Blank - Indicates that the lexical was returned by code-based matching while the
match_field_prefpreference was set to "input_code". - Discrepancy check not performed: unable to normalize input_term - An edge case that occurs when the lexical was returned by code-based matching and the
match_field_prefpreference was set to "input_code_first". - Discrepancy check not performed: Missing <field> - Indicates that the lexical was returned by term-based matching and the request was missing the identified <field>, either
input_codeorinput_code_system.
- Blank - Indicates that the lexical was returned by code-based matching while the
5 Enrichment Term Normalization Requests
When defining your payload for an Enrichment term normalization request, each normalization record must specify an input_term and may optionally include a context object. In the context object, the source_text, age, sex, and icd10_codes fields are analyzed by the operation's AI models to help identify the most specific and accurate match for the clinical intent of the input term. Whenever possible, you should provide as many of these context fields as you can.
The source_text field is important for helping the API understand the intent of the input term, but the age and sex fields can also often improve the clinical relevance of matched lexicals by reducing ambiguity. This capability is particularly valuable for clinical analytics, longitudinal patient data, and population specific insights where age and gender aware interpretation is critical.
The following sections describe the basic request-response pattern applicable to Enrichment term normalization:
5.1 Enrichment Request Payload
The following example request payload performs term-based matching for two normalizations records, respectively seeking normalization for the terms "diaphragmatic hernia" and "impaired fecundity":
{
"client_request_id": "5H4I3J2K",
"preferences": {
"match_field_pref": "input_term"
},
"requests": [
{
"record_id": "AABBCC01",
"domain": "Problem",
"input_term": "diaphragmatic hernia",
"context": {
"source_text": "The patient was born with a diaphragmatic hernia",
"age": 0
}
},
{
"record_id": "AABBCC01",
"domain": "Problem",
"input_term": "impaired fecundity",
"context": {
"source_text": "The patient is unable to become pregnant",
"age": 23,
"sex": "F"
}
}
]
}
Each normalization record included the mandatory input_term and domain fields, with domain set to the only supported Enrichment endpoint value of "Problem". Each record included a context object supplying some of the optional fields used by AI models to help match lexicals. The context objects could also have opted to include the optional record tracking fields (use_count, application_id, facility_id, encounter_id, document_id, project_id), but these are not used for lexical matching.
The preferences.match_field_pref value of "input_term" indicates that the API should attempt only term-based matching for this request's normalization records. By excluding all other preferences fields, this simple request accepted the default values for the size (3), threshold (0.8), discrepancy_check (false), and distinct_field (lexical_code) preferences; performed no manual transformations; and opted not to apply USCDI filters.
The input_code and input_code_system fields are not used for term-based matching and so were excluded. Alternatively, if preferences.discrepancy_check was set to "true", you could have included an input_code and input_code_system in order to perform discrepancy checking against the results.
5.2 Enrichment Response Payload
The following is a response payload for the Enrichment request defined above:
Enrichment Term Normalization Response
{
"summary": {
"count": 2,
"error_count": 0
},
"request_id": "f472fb1a-7bb1-6078-784a-84511c80f684",
"client_request_id": "5H4I3J2K",
"response_time": 1761,
"requests": [
{
"record_id": "AABBCC01",
"domain": "Problem",
"input_term": "diaphragmatic hernia",
"transformed_term": "diaphragmatic hernia",
"context": {
"age": 0,
"source_text": "The patient was born with a diaphragmatic hernia"
},
"response": {
"match_field": "input_term",
"domain": "problem",
"custom_mapped": false,
"transformed_term": "diaphragmatic hernia",
"explanation": "Candidates Generation for the input term 'diaphragmatic hernia': 2 candidates were generated: 'diaphragmatic hernia; congenital diaphragmatic hernia'.; Candidate term 'congenital diaphragmatic hernia' resolved to a lexical match on 'Congenital diaphragmatic hernia' with score 0.98",
"items": [
{
"lexical_code": "5718",
"lexical_title": "Congenital diaphragmatic hernia",
"default_lexical_code": "5718",
"default_lexical_title": "Congenital diaphragmatic hernia",
"score": 0.999,
"certainty": "",
"metadata": {
"mappings": {
"icd10cm": {
"codes": [
{
"code": "Q79.0",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "MAL008",
"ccsr_description": "Musculoskeletal congenital conditions"
}
],
"hcc": []
},
"map_type": "Preferred primary",
"relationship_type": "Same as",
"title": "Congenital diaphragmatic hernia"
}
]
},
"icd9cm": {
"codes": [
{
"code": "756.6",
"map_type": "Preferred primary",
"title": "Congenital anomaly of diaphragm"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "17190001",
"map_type": "Preferred primary",
"mesh_code": "D065630",
"relationship_type": "Same as",
"title": "Congenital diaphragmatic hernia"
}
]
},
"umls": {
"codes": [
{
"code": "C0235833",
"title": "Congenital diaphragmatic hernia"
}
]
}
},
"flags": {
"age_indicator": "",
"is_icd10cm_refinable": false,
"sex_indicator": ""
}
}
},
{
"lexical_code": "46216",
"lexical_title": "Diaphragmatic hernia",
"default_lexical_code": "46216",
"default_lexical_title": "Diaphragmatic hernia",
"score": 0.979,
"certainty": "",
"metadata": {
"mappings": {
"icd10cm": {
"codes": [
{
"code": "K44.9",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "DIG010",
"ccsr_description": "Abdominal hernia"
}
],
"hcc": []
},
"map_type": "Preferred primary",
"relationship_type": "Broader than",
"title": "Diaphragmatic hernia without obstruction or gangrene"
}
]
},
"icd9cm": {
"codes": [
{
"code": "553.3",
"map_type": "Preferred primary",
"title": "Diaphragmatic hernia without mention of obstruction or gangrene"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "39839004",
"map_type": "Preferred primary",
"mesh_code": "D006548",
"relationship_type": "Same as",
"title": "Diaphragmatic hernia"
}
]
},
"umls": {
"codes": [
{
"code": "C0494752",
"title": "Diaphragmatic hernia without mention of obstruction or gangrene"
},
{
"code": "C0019284",
"title": "Diaphragmatic Hernia"
}
]
}
},
"flags": {
"age_indicator": "",
"is_icd10cm_refinable": true,
"sex_indicator": ""
}
}
}
]
}
},
{
"record_id": "AABBCC01",
"domain": "Problem",
"input_term": "impaired fecundity",
"transformed_term": "infertility",
"context": {
"age": 23,
"sex": "F",
"source_text": "The patient is unable to become pregnant"
},
"response": {
"match_field": "input_term",
"domain": "problem",
"custom_mapped": false,
"transformed_term": "infertility",
"explanation": "Candidates Generation for the input term 'impaired fecundity': 3 candidates were generated: 'infertility; impaired fertility; impaired fecundity'.; Candidate term 'impaired fertility' resolved to a semantic match on 'Fertility problem' with score 0.92; Candidate term 'impaired fecundity' resolved to a semantic match on 'Sexual dysfunction in female' with score 0.88",
"items": [
{
"lexical_code": "47145",
"lexical_title": "Female infertility",
"default_lexical_code": "47145",
"default_lexical_title": "Female infertility",
"score": 0.997,
"certainty": "",
"metadata": {
"mappings": {
"icd10cm": {
"codes": [
{
"code": "N97.9",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "GEN024",
"ccsr_description": "Female infertility"
}
],
"hcc": []
},
"map_type": "Preferred primary",
"relationship_type": "Same as",
"title": "Female infertility, unspecified"
}
]
},
"icd9cm": {
"codes": [
{
"code": "628.9",
"map_type": "Preferred primary",
"title": "Female infertility of unspecified origin"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "6738008",
"map_type": "Preferred primary",
"mesh_code": "D007247",
"relationship_type": "Same as",
"title": "Female infertility"
}
]
},
"umls": {
"codes": [
{
"code": "C0021361",
"title": "Female infertility"
}
]
}
},
"flags": {
"age_indicator": "",
"is_icd10cm_refinable": false,
"sex_indicator": "F"
}
}
},
{
"lexical_code": "736021",
"lexical_title": "Fertility problem",
"default_lexical_code": "736021",
"default_lexical_title": "Fertility problem",
"score": 0.922,
"certainty": "",
"metadata": {
"mappings": {
"icd10cm": {
"codes": [
{
"code": "N97.9",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "GEN024",
"ccsr_description": "Female infertility"
}
],
"hcc": []
},
"map_type": "Preferred primary",
"relationship_type": "Narrower than",
"title": "Female infertility, unspecified"
}
]
},
"icd9cm": {
"codes": [
{
"code": "628.9",
"map_type": "Preferred primary",
"title": "Female infertility of unspecified origin"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "27034006",
"map_type": "Preferred primary",
"mesh_code": "",
"relationship_type": "Same as",
"title": "Fertility problem"
}
]
},
"umls": {
"codes": [
{
"code": "C0021361",
"title": "Female infertility"
},
{
"code": "C0278048",
"title": "Fertility problem"
}
]
}
},
"flags": {
"age_indicator": "",
"is_icd10cm_refinable": false,
"sex_indicator": "F"
}
}
},
{
"lexical_code": "83328485",
"lexical_title": "Abnormality of reproductive function in female",
"default_lexical_code": "83328485",
"default_lexical_title": "Abnormality of reproductive function in female",
"score": 0.878,
"certainty": "",
"metadata": {
"mappings": {
"icd10cm": {
"codes": [
{
"code": "N94.9",
"code_metadata": {
"ccsr": [
{
"ccsr_category": "GEN025",
"ccsr_description": "Other specified female genital disorders"
}
],
"hcc": []
},
"map_type": "Preferred primary",
"relationship_type": "Narrower than",
"title": "Unspecified condition associated with female genital organs and menstrual cycle"
}
]
},
"icd9cm": {
"codes": [
{
"code": "625.9",
"map_type": "Preferred primary",
"title": "Unspecified symptom associated with female genital organs"
}
]
},
"snomedInternational": {
"codes": [
{
"code": "67809006",
"map_type": "Preferred primary",
"mesh_code": "",
"relationship_type": "Same as",
"title": "Abnormal female reproductive function"
}
]
},
"umls": {
"codes": [
{
"code": "C0495119",
"title": "Unspecified condition associated with female genital organs and menstrual cycle"
},
{
"code": "C0278051",
"title": "Abnormal female reproductive function"
}
]
}
},
"flags": {
"age_indicator": "",
"is_icd10cm_refinable": false,
"sex_indicator": "F"
}
}
}
]
}
}
],
"preferences": {
"match_field_pref": "input_term",
"size": 3
}
}
In the response, the requests array returned one object corresponding to each normalization record supplied in the request. In each of these objects, the items array includes three child objects describing the highest scoring lexicals that were matched to the supplied input_term. For each lexical, the items.default_lexical_title states the IMO normalized text for the corresponding clinical concept, and the items.metadata.mappings array lists each of the clinical codes mapped to that lexical from all applicable code systems. Both records involved a certain amount of interpretation by the API to identify the optimal lexical matches, which was summarized in each record's response.explanation field.
For the first record, the input term of "diaphragmatic hernia" on its own would have found an exact match with lexical "46216 - Diaphragmatic hernia", but contextual analysis of the supplied source_text and age instead resulted in a very high confidence top-match with the much more specific lexical "5718 - Congenital diaphragmatic hernia", as the API was able to correctly conclude that the patient was a newborn infant.
For the second record, the API used semantic and contextual analysis to determine that the input term "impaired fecundity" would find more relevant matches as "infertility", and so reported a new transformed_term used for lexical matching. On its own, the term "infertility" would have found several matches with very general lexicals, but contextual analysis of the supplied source_text and sex enabled a very high-confidence top-match with the more specific lexical "47145 - Female infertility", as the API was able to correctly identify the patient's biological sex.
6 Error Messages
...
"requests": [
{
"record_id": "10001",
"domain": "",
"input_term": "chest pain",
"response": {
"match_field": "",
"domain": "",
"custom_mapped": false,
"explanation": "",
"error_message": [
"E003: Missing domain"
],
"items": []
}
},
...
In any response payload, the presence of a response.error_message array for a normalization record indicates that the API encountered one or more errors that either prevented normalization entirely or impacted the result. If included, each string in the error_message array describes a distinct error, stated as an error code followed by a description.
Error codes beginning with an "E", "R", or "N" indicate fatal errors that prevent normalization entirely and are always accompanied by a blank items array. Error codes beginning with a "W" indicate warnings that may impact the results, but do not in themselves prevent lexical matches from being returned. The error_message field does not appear in situations where the normalization record was valid, but the API was simply unable to find a lexical match within the request threshold.
If present, the error_message array may include any of the following values:
-
Validation Errors (E): These errors indicate a basic problem with the data supplied in the normalization record:
- E001: Missing record id - The
record_idfield was either excluded or sent blank. - E002: Missing input term - The
input_termfield was either excluded or sent blank while thematch_field_prefpreference was set to "input_term". - E003: Missing domain - The
domainfield was either excluded or sent blank. - E004: Invalid domain field <value> - The
domainfield was sent with the indicated invalid <value> instead of a recognized domain. - E005: Missing input code - The
input_codefield was either excluded or sent blank while thematch_field_prefpreference was set to "input_code". - E006: Missing input code system - The
input_code_systemfield was either excluded or sent blank while thematch_field_prefpreference was set to "input_code". - E007: Invalid code system: <value> - The
input_code_systemfield was sent with the indicated invalid <value> instead of a recognized clinical code system. - E008: Unknown error - A fallback error when the API cannot process the normalization record and no other validation error applies.
- E009: Input term exceeds the maximum recommended length of 500 characters - The
input_termfield was sent with a value greater than 500 characters while thematch_field_prefpreference was set to "input_term".
- E001: Missing record id - The
-
Retryable Errors (R): These errors likely indicate either an authentication error or a communication problem with the API. If you encounter one of these errors, ensure that your Authorization header supplies a valid Bearer token and then try again:
- R001: Authentication error: invalid token
- R002: Authentication error: invalid scope
- R003: An error occurred while submitting this record for normalization
-
Warnings (W): These errors indicate a problem with the request's
preferences.filtersarray. These errors may prevent the USCDI filters from being applied, but they do not otherwise prevent normalization from proceeding. For information on defining USCDI filter criteria, see 4.5 USCDI Filters above:- W010: Maximum number of filters exceeded. The maximum allowed is 4 - The
filtersarray included more than the maximum of 4 objects. - W011: Invalid filter field: <value> - The
filters.fieldwas sent with the indicated invalid <value> instead of a recognized USCDI field name. - W012: Access denied: filtering on field '<value>' is not allowed due to licensing restrictions - This indicates that you included the
filtersarray without having confirmed your USCDI licensing with IMO Health. See 2.1.2 USCDI Access above. - W013: Invalid filter operator: <value> - The
filters.operatorwas sent with the indicated invalid <value>. Currently, only an operator of "eq" is permitted. - W014: Failed to build filter query - A fallback error when the API cannot process the
filtersarray and no other warning applies.
- W010: Maximum number of filters exceeded. The maximum allowed is 4 - The
7 Request Rate and Response Times
In each request to the IMO Precision Normalize API, the requests array can technically contain up to 100 normalization records, but approaching this hard limit will impact response times and is not recommended. When you wish to process large batches of normalization records, for optimal performance each request payoad should include 10 to 25 normalization records. For Enrichment requests, 25 normalization records is ideal. These recommendations take into account time to access system resources and will result in a faster overall time to completion than sending the same quantity of normalization records one at a time.
The following table provides Enrichment endpoint response times for request payloads containing different quantities of normalization records. All listed response times are in milliseconds and are based on 95th percentile latency, meaning 95% of the tested requests completed within the supplied duration. Response times are dervied from term-based matching scenarios.
| Records | Response Time (ms) |
|---|---|
| 1 | 4,500 |
| 5 | 9,000 |
| 10 | 12,000 |
| 20 | 18,000 |
8 Term Refinement Workflow
Most Problem domain lexicals belong to a Refinement Group, which is a collection of related lexicals that share the same clinical topic and attributes for defining specificity. Within a given refinement group, these related lexicals are organized hierarchically from most to least specific. For example, there is a "Fracture of femur" refinement group, which stratifies its lexicals based on whether they describe laterality and encounter type. This group includes a top-level lexical "20755 - Fracture of femur", which has a much more specific descendent lexical of "1951679 - Closed fracture of shaft of left femur, initial encounter".
Refinement groups can be used to support the term refinement workflow, sometimes also referred to as "post-coordination". This workflow involves generating a session to track the normalization of an input term across multiple requests and endpoints with the goal of identifying the most specific lexical applicable to the relevant clinical concept. The term refinement workflow is particularly relevant for billing related scenarios, where it is usually ideal to supply the most specific billing code applicable to the patient's condition. When you have identified the most specific lexical that accurately describes the clinical intent of your input term, the final step of this workflow is to tell the API which lexical you selected as most applicable. By tying all of these actions together in a single session, IMO Health can analyze your usage patterns in order to improve future normalization results.
The term refinement workflow is specific to the Problem domain and is enabled by the metadata.flags.is_icd10cm_refinable boolean field returned in normalization response payloads for Problem domain lexicals. This field is set to "true" for a lexical that has more specific descendent lexicals within its refinement group, meaning it can be "refined" to another lexical representing a more granular clinical concept within the same topic. This field is set to "false" for lexicals at the lowest level of hierarchy within its refinement group, meaning it represents the most specific level of granularity available for the relevant clinical topic. In the term refinement workflow, the is_icd10cm_refinable flag helps you determine whether a followup request is required in order to identify a more specific lexical for your input term. This flag technically refers to the lexical that directly matched the request input (lexical_code/lexical_title), but the corresponding default variant (default_lexical_code/default_lexical_title) always shares the same refinability, as both variants reference the same clinical concept.
The following steps describe the term refinement workflow in detail:
- Generate a Session
- Send initial Normalization request
- Analyze initial Normalization response
- Send followup Core Search request
- Send Lexical Selection Request
8.1 Generate a Session
Before submitting your initial normalization request, use the following operation to generate a new session and retrieve a corresponding Session ID value, which you will supply in the payload of all subsequent requests for this workflow. Session IDs do not expire and there is no set expectation for how long the entire refinement workflow should take. The Session ID only exists to enable IMO Health to track a normalization record across different requests, from initial creation to final lexical selection.
GET /precision/normalize/session
The response body will include a session_id field containing the identifier for this term refinement session. For a full description of this operation, please refer to the REFERENCE DOCUMENTATION tab.
{
"session_id": "a1bc2def-g34h-5ij5-klm6-7890n2o345pq"
}
8.2 Send initial Normalization request
Use the following operation to submit a normalization request for one or more normalization records:
POST /precision/normalize/enrichment
In the request payload, the session_id field must specify the Session ID value you retrieved in 8.1 Generate a Session. The rest of the payload should define term-based matching requests for one or more normalization records, as described in 5 Enrichment Term Normalization Requests above.
As the Session ID is supplied at the request level, the same ID will apply to every normalization record included in your request. In subsequent steps of the term refinement workflow, it is important to use the same Session ID for all requests pertaining to a given normalization record, but you may process records sharing the same Session ID independently.
For example, the following normalization request payload defines an initial normalization request for two normalization records, respectively seeking normalization for the terms "femur fracture" and "knee pain, right, chronic".
{
"client_request_id": "REQ1050",
"session_id": "a1bc2def-g34h-5ij5-klm6-7890n2o345pq",
"preferences": {
"match_field_pref": "input_term"
},
"requests": [
{
"record_id": "PRLMRC10",
"domain": "Problem",
"input_term": "femur fracture"
},
{
"record_id": "PRLMRC11",
"domain": "Problem",
"input_term": "knee pain, right, chronic"
}
]
}
8.3 Analyze initial Normalization response
For each lexical returned in the response to your initial normalization request, review the values returned in the metadata.flags.is_icd10cm_refinable field. Based on the returned value, a followup Core Search request may be warranted to identify more specific lexicals:
-
If set to false, then the returned lexical represents the most specific level of granularity available for the relevant clinical topic. This lexical cannot be further refined.
-
If this field is set to true, then the returned lexical has one or more descendent lexicals within its refinement group representing more specific clinical concepts. You may wish to send a followup Core Search request to further refine this lexical.
For example, for the request provided in the previous step, consider the following response:
Initial Normalization Response
{
"summary": {
"count": 2,
"error_count": 0
},
"request_id": "4b4b4bbb-55d5-666f-h777-jj88j8888ll9",
"client_request_id": "REQ1050",
"session_id": "a1bc2def-g34h-5ij5-klm6-7890n2o345pq",
"response_time": 260,
"requests": [
{
"record_id": "PRLMRC10",
"domain": "Problem",
"input_term": "femur fracture",
"response": {
...
"items": [
{
"lexical_code": "43972",
"lexical_title": "Femur fracture",
"default_lexical_code": "20755",
"default_lexical_title": "Fracture of femur",
...
"metadata": {
"mappings": {...},
"flags": {
"is_icd10cm_refinable": true,
...
}
}
}
]
}
},
{
"record_id": "PRLMRC11",
"domain": "Problem",
"input_term": "knee pain, right, chronic",
"response": {
...
"items": [
{
"lexical_code": "41282150",
"lexical_title": "Chronic pain of right knee",
"default_lexical_code": "41282150",
"default_lexical_title": "Chronic pain of right knee",
...
"metadata": {
"mappings": {...},
"flags": {
"is_icd10cm_refinable": false,
...
}
}
}
]
}
}
]
}
For the first record, the input term "femur fracture" matched lexical "20755 - Fracture of femur", which has is_icd10cm_refinable=true. We decide that the returned lexical is not yet specific enough and we want to send a followup Core Search request to further refine this lexical.
For the second record, the input term "knee pain, right, chronic" matched lexical "41282150 - Chronic pain of right knee", which has is_icd10cm_refinable=false. We determine that this lexical represents an accurate and specific description for the clinical intent of the input term, and so take note of the lexical_code "41282150" for later use in 8.5 Send Lexical Selection Request.
8.4 Send followup Core Search request
When a normalization response payload returns an unrefined lexical with is_icd10cm_refinable=true, you may decide that you want to find a more specific lexical that better represents the clinical intent of the input term. Using the following operation from the IMO Core Search API, you can identify other lexicals from the same refinement group as the unrefined lexical returned in the initial normalization response.
POST /v2/product/{productName}/search
In the request, the payload should specify the same sessionID value you retrived in 8.1 Generate a Session and the searchTerm field should specify the lexical_title or default_lexical_title of the unrefined lexical returned in the initial normalization response. You will send a separate request for each of your unrefined lexicals. For more information on using the IMO Core Search API, please refer to the API Catalog - Core Search page.
The response will typically return several related lexicals from the same clinical topic (i.e. refinement group) representing different variations of laterality, severity, chronicity, encounter type, or any other applicable specificity attributes. Select the one lexical that best represents the clinical intent of the input term and take note of the IMO_lexical_code for use in 8.5 Send Lexical Selection Request.
For example, from the initial normalization response provided in the previous step, we decided that we wished to further refine lexical "20755 - Fracture of femur". We then send a followup Core Search request using a searchTerm of "Fracture of femur". From the lexicals returned in the response, we decide that lexical "1962872 - Closed fracture of left femur, initial encounter" represents an accurate and specific description for the clinical intent of the input term. We then take note of the IMO_lexical_code "1962872" for use in the final step of this workflow.
8.5 Send Lexical Selection Request
For each normalization record, when you have identified the one lexical that best represents the clinical intent of the input term at the appropriate level of specificity, you should then use the following operation to tell the API which lexical you selected:
POST /precision/normalize/event/selection
From the batch of normalization records supplied in the initial normalization request, you can report your selected lexicals either all at once in a single request, or gradually using multiple requests as your complete the refinement process for one or more records at a time. The only restrictions are that the request payload must report exactly one lexical selection per normalization record and that each supplied combination of session_id and record_id must correspond to the initial normalization request.
The request payload must define a JSON object with the following fields. If your selection request is properly processed, the API responds with an HTTP status code of 200 OK and an empty body:
-
session_id: This field must specify the same Session ID value that you retrieved in 8.1 Generate a Session
-
result_selected: This array contains one object for each normalization record whose selected lexical you want to report. Each object must contain the following two fields:
-
record_id: The
record_idvalue supplied for the applicable normalization record in the initial normalization request. -
imo_lexical_code: The
lexical_code,default_lexical_code, orIMO_lexical_codevalue for the lexical you selected as most appropriate for the normalization record.
-
For example, continuing from our refinement examples above, for the normalization record "PRLMRC10" we selected lexical "1962872 - Closed fracture of left femur, initial encounter" and for record "PRLMRC11" we selected lexical "41282150 - Chronic pain of right knee". We decide to report both lexical selections at once, and so we send the following selection request payload:
{
"session_id": "a1bc2def-g34h-5ij5-klm6-7890n2o345pq",
"result_selected": [
{
"record_id": "PRLMRC10",
"imo_lexical_code": "1962872"
},
{
"record_id": "PRLMRC11",
"imo_lexical_code": "41282150"
}
]
}
IMO Health Customer Support
IMO Health® Customer Support
Phone: (847) 613-6655
Email: CustomerSupport@imohealth.com
Web: www.imohealth.com
Disclaimers
Advisory Notice
While making all reasonable efforts to ensure accuracy, Intelligent Medical Objects, Inc. assumes no responsibility for errors that may appear in the IMO Health® Precision Normalize user documentation or product. In addition, Intelligent Medical Objects, Inc. assumes no liability with respect to accuracy of codes or data herein.
The information contained in the IMO Precision Normalize user guide is intended to supplement the knowledge of physicians and other health care professionals. This information is advisory only and is not intended to replace sound clinical judgment in the delivery of health care services.
Requirements for Implementation
The license agreement for the IMO Precision Normalize states that this product must be implemented according to the requirements specified in the IMO Precision Normalize documentation. In addition to the requirements set forth herein and any implementation guides or other documentation provided by IMO Health®, additional requirements for implementing IMO Precision Normalize are as follows:
-
The disclaimer notice listed in this document must be included in documentation given to the end user.
-
The copyright statement in the copyright file must be listed on all printed reports that are generated using the IMO Precision Normalize data. For example:
Copyright 2026 Intelligent Medical Objects, Inc. All rights reserved
Notices
The information inside of this guide is confidential and proprietary. Any use of this outside an agreement or engagement with IMO Health® is prohibited.
RxNorm® is a registered trademark of the National Library of Medicine.
LOINC® is a registered United States trademarks of Regenstrief Institute, Inc.
SNOMED and SNOMED CT are registered trademarks of SNOMED International. All rights reserved.
This product includes SNOMED Clinical Terms (SNOMED CT) which is used by permission of SNOMED International.
This material includes ICD-O-3 codes used by permission of WHO, from: International Classification of Diseases for Oncology, Third Edition.
Current Procedural Terminology. CPT® is a registered trademark of the American Medical Association. All rights reserved. Applicable FARS/DFARS Restrictions Apply to Government Use.
Fee schedules, relative value units, conversion factors and/or related components are not assigned by the AMA, are not part of CPT and the AMA is not recommending their use.
The AMA does not directly or indirectly practice medicine or dispense medical services.
The AMA assumes no liability for data contained or not contained herein.
The responsibility for the content of any National Correct Coding Policy included in this product is with the Centers for Medicare and Medicaid Services and no endorsement by the AMA is intended or should be implied. The AMA disclaims responsibility for any consequences or liability to or related to any use, nonuse or interpretation of information contained in this product.
Users of the IMO Behavioral Health add-on may have access to DSM-5 content. The DSM-5 content is reprinted with permission from the Diagnostic and Statistical Manual of Mental Disorders, Fifth Edition TM. Copyright © 2022 American Psychiatric Association ("APA"). All Rights Reserved.
Unless authorized in writing by the APA, DSM-5 content may be reproduced or used in a manner inconsistent with the APA's copyright. This prohibition applies to unauthorized uses or reproductions in any form.
*DSM and DSM-5 are registered trademarks of the American Psychiatric Association, and are used with permission herein. Use of these terms is prohibited without permission of the American Psychiatric Association. Use of this trademark does not constitute endorsement of this product by the American Psychiatric Association.
Use of DSM-5 Content requires appropriate End-Users licenses from the American Psychiatric Association. Additional fees may apply.
UMLS Knowledge Sources [dataset on the Internet]. Release 2024AA. Bethesda (MD): National Library of Medicine (US); 2024 May 6 [cited 2024 Jul 15]. Available from: http://www.nlm.nih.gov/research/umls/licensedcontent/umlsknowledgesources.html
© 2026. IMO Health is a trademark of Intelligent Medical Objects, Inc. All rights reserved
IMO Health® confidential information, not to be shared with third party without IMO Health® consent.