A Guide to ICD 10 Coronary Artery Disease Codes

When documenting Coronary Artery Disease (CAD) without angina, the go-to diagnosis code is ICD-10-CM I25.10 - Atherosclerotic heart disease of native coronary artery without angina pectoris. This specific code belongs to the I20-I25 block, which covers the full spectrum of ischemic heart diseases. Getting this right is fundamental for clinical documentation, reimbursement, and large-scale health research.
The Role of Standardized CAD Coding in Healthcare

Coronary artery disease is a massive global health challenge. The numbers are staggering: it affects an estimated 315 million people worldwide and was responsible for over 9.2 million deaths in 2022. According to the Global Burden of Disease Study, it also carries the highest disability-adjusted life years (DALYs) of any disease. Codes from the I20-I25 block are how we track and measure this impact.
Why Accurate Coding Matters
On a practical level, the precise application of ICD 10 coronary artery disease codes is non-negotiable. For a single patient, it creates a clear, unambiguous clinical history that follows them across different care settings. For hospitals and clinics, it's the bedrock of accurate billing and fair reimbursement.
But the impact doesn't stop there. For those of us in health informatics and data science, consistent coding is the key to unlocking powerful analytics. When we standardize these billing codes into a research-grade framework like the OMOP Common Data Model, we can suddenly conduct multi-institutional studies on disease progression, treatment efficacy, and population health outcomes.
Making Data Access More Efficient
In the past, working with these complex medical terminologies meant maintaining a local, often cumbersome vocabulary database. That approach is quickly becoming outdated, as modern tools now provide a much more direct path.
OMOPHub provides a developer-first API that gives teams programmatic access to standardized vocabularies. This allows developers and researchers to query codes, understand concept relationships, and build mappings without the overhead of local database management.
This guide serves as a definitive reference for applying ICD-10-CM codes for CAD in a real-world setting. We'll break down how to map these codes for analytics and show how new tools can make the entire process faster and more reliable.
Expert Tips for Getting Started:
- Know the I20-I25 Block: Take the time to understand this range. It's the entire neighborhood for ischemic heart disease, covering everything from angina (I20) to old myocardial infarctions and chronic IHD (I25).
- Drill Down for Specificity: Always use the most specific code available. If the clinical notes provide enough detail, avoid defaulting to unspecified codes like I25.9. This granularity is gold for analytics.
- Map Codes to Standard Concepts: Don't just look at the ICD-10 code in isolation. Use a resource like the OMOPHub Concept Lookup to see how it translates to standard concepts like SNOMED, which is critical for harmonizing data.
A Practical Guide to Ischemic Heart Disease Codes: I20-I25

When working with data on icd 10 coronary artery disease, the I20-I25 block in ICD-10-CM is your primary reference. Think of this range as the definitive classification system for all forms of ischemic heart disease. Getting the coding right is non-negotiable, impacting everything from patient records and billing to the integrity of large-scale analytics projects.
The entire block is logically structured around the acuity and specific clinical presentation of the disease. For instance, the system makes a clear, deliberate distinction between I20 (Angina Pectoris)-which covers the symptomatic chest pain of myocardial ischemia-and I21 (Acute Myocardial Infarction), reserved for the life-threatening event of a heart attack. This separation is fundamental for both immediate patient care decisions and long-term health research.
Core Categories of Ischemic Heart Disease
To master this section of ICD-10-CM, it’s best to view the codes as a family of closely related, yet distinct, diagnoses. The most heavily used categories you'll encounter are:
- I20 - Angina Pectoris: This is where you'll find codes for transient myocardial ischemia that doesn't result in infarction. The codes here get granular, allowing you to differentiate between presentations like stable and unstable angina.
- I21 - Acute Myocardial Infarction (AMI): These codes are for documenting a current heart attack. Proper coding demands specificity, including the type of MI (like STEMI or NSTEMI) and the specific coronary artery involved.
- I25 - Chronic Ischemic Heart Disease: This is the go-to category for long-term icd 10 coronary artery disease. It’s a broad but essential group, housing codes for atherosclerotic heart disease (ASHD), old or healed myocardial infarctions, and complications related to previous coronary artery bypass grafts (CABG).
One of the most common and critical coding challenges is correctly distinguishing between an acute event (I21) and a chronic condition or history (I25). For example, a patient's history of a "healed" or "old" myocardial infarction should be coded under I25.2. Using an acute MI code in this context would misrepresent the patient's current clinical status and create significant data quality issues.
To simplify this, the following table provides a high-level overview of the main categories within the Ischemic Heart Disease block.
ICD-10-CM Categories for Ischemic Heart Disease (I20-I25)
| Code Category | Description | Common Clinical Focus |
|---|---|---|
| I20 | Angina Pectoris | Symptomatic chest pain without infarction |
| I21 | Acute Myocardial Infarction | Current heart attack event |
| I24 | Other Acute Ischemic Heart Diseases | Acute ischemia without MI (e.g., coronary thrombosis) |
| I25 | Chronic Ischemic Heart Disease | Long-term CAD, old MI, post-CABG status |
This table serves as a quick reference, but the real expertise comes from applying the codes correctly in practice.
Tips for Navigating the I20-I25 Block
Properly applying these codes means paying close attention to the details laid out in the official classification.
- Always Check the "Includes" and "Excludes" Notes: The ICD-10-CM Tabular List is packed with instructional notes that are easy to overlook but crucial for accuracy. These notes clarify code hierarchies and prevent misapplication.
- Lean on Lookup Tools for Verification: If you're ever unsure about a code's precise meaning or how it maps to other terminologies, a reliable lookup tool is indispensable. You can dive into any ICD-10 code and its relationship to other concepts using the OMOPHub Concept Lookup page.
- Automate Your Vocabulary Workflow: For data scientists and health IT developers, manually managing vocabularies is a recipe for inefficiency and error. A much better approach is to integrate directly with an API. Consider using the OMOPHub Python SDK or R SDK to programmatically query and map concepts, as detailed in the official documentation.
A Detailed Breakdown of Chronic IHD Codes in I25
When we talk about the long-term documentation of ICD 10 coronary artery disease, the I25 category, Chronic Ischemic Heart Disease, is your primary toolkit. This isn't for capturing the immediate drama of an acute event; instead, these codes tell the story of the patient's persistent, underlying condition. Getting this right is absolutely critical for tracking how the disease is progressing, justifying ongoing treatments, and ensuring your billing and analytics are on solid ground.
The real nuance within the I25 block comes down to a few key clinical details. The main differentiators are the presence or absence of angina and, crucially, whether the disease is in a native coronary artery or a bypass graft. Making the correct distinction here paints a much clearer picture of the patient’s current health status.
I25.1 Atherosclerotic Heart Disease of Native Coronary Artery
This is probably the subcategory you'll encounter most often for chronic CAD. The codes here hinge on the patient's angina symptoms.
-
I25.10 - Atherosclerotic heart disease of native coronary artery without angina pectoris: Think of this as the baseline code for a patient with confirmed ASHD who isn't experiencing chest pain. It's for the stable, asymptomatic state of the disease.
-
I25.11- Series - With Angina Pectoris: When chest pain enters the picture, you have to get more specific. For instance, I25.110 is reserved for ASHD with unstable angina, which signals a more serious situation that needs urgent evaluation. Other codes in this series drill down into different, more stable forms of angina.
I25.7 Atherosclerosis of Coronary Artery Bypass Grafts and Autologous Vein
This set of codes is essential for any patient with a history of coronary artery bypass graft (CABG) surgery. From an analytics and clinical tracking perspective, the distinction between disease in a native vessel versus a graft is not a minor detail-it's fundamental.
- I25.71- to I25.79- Series: These codes classify atherosclerosis based on the specific type of bypass graft involved (like an autologous vein or a nonautologous biological graft) and whether the patient is experiencing angina. A patient presenting with chest pain because of atherosclerosis in their saphenous vein graft requires a completely different code than someone with disease in a native artery.
A common pitfall I see is coders defaulting to an I25.1- series code for a patient who has had a CABG. You can't do that. If the atherosclerosis is in the graft itself, you absolutely must use a code from the I25.7- series. Failing to make this distinction misrepresents the patient's history and can seriously skew any downstream analytics.
Other Important I25 Codes
Beyond straightforward atherosclerosis, the I25 category also helps us document the long-term consequences of ICD 10 coronary artery disease.
-
I25.2 - Old myocardial infarction: This is the correct code for a healed heart attack. It should never be confused with the acute MI codes (I21.-). I25.2 signifies a past event, which is a major risk factor for future cardiac trouble and needs to be part of the patient's permanent record.
-
I25.9 - Chronic ischemic heart disease, unspecified: This code should be a last resort. It's really only appropriate when the documentation confirms chronic IHD but provides zero additional detail about atherosclerosis, angina, or prior procedures. Always push for more specificity if possible.
Expert Coding Tips for the I25 Category:
- Specify Angina Status: Don't leave this detail out. Always document and code the presence and type of angina, as it has huge implications for risk stratification and treatment.
- Differentiate Native vs. Grafted Arteries: Be vigilant about this. For any atherosclerosis in a bypass graft, the I25.7- series is the only correct choice. Using a generic code obscures vital clinical history.
- Cross-reference Your Codes: Before settling on a code, do a quick sanity check on its definition and any included notes. A quick search with a tool like the OMOPHub Concept Lookup can help you confirm its mapping to other standard terminologies.
- Automate for Consistency: For any development teams building clinical applications, using an API to access vocabularies is a must. The OMOPHub Python or R SDKs can ensure your system is always working with the most current and accurate code definitions. You can find more information in the official documentation.
Mapping ICD-10 CAD Codes to SNOMED and OMOP
To conduct high-quality research, raw billing data like ICD-10 codes for coronary artery disease must be translated into a standardized format. At the heart of this work is a process called semantic mapping, which ensures that data from disparate sources can be reliably combined and analyzed. The fundamental goal is to link a source code to a standard vocabulary concept-most often from SNOMED CT-within the OMOP Common Data Model.
This isn't just a technical exercise; it's the bedrock of true data interoperability. Imagine a hospital in the US records a diagnosis using ICD-10-CM I25.10. A research partner in the UK might use an entirely different code for the exact same condition. By mapping both source codes to a single, universal SNOMED CT concept for "Atherosclerotic heart disease," we can finally treat them as equivalent in any analysis.
The diagram below illustrates how a broad category like Chronic Ischemic Heart Disease (I25) branches into more specific clinical states, such as atherosclerosis, a history of myocardial infarction, or complications with grafts.

This hierarchy shows why precise mapping is so critical. Each branch represents a distinct clinical reality, and capturing that specificity accurately is essential for meaningful data analytics.
Finding the Right Standard Concept
For an ETL developer, the core task is to identify the correct OMOP Standard Concept ID for any given source code. This is what bridges the gap between messy, original data and the clean, standardized model. Frankly, trying to do this without a dedicated vocabulary exploration tool is a recipe for frustration and error.
For example, you can use the OMOPHub Concept Lookup to search for an ICD-10 coronary artery disease code and instantly see its standard mapping relationship.
This screenshot from the OMOPHub Concept Lookup demonstrates the results for a typical query.

As you can see, the tool lays it all out: the source code, its description, and its direct "Maps to" relationship with the corresponding standard SNOMED concept. It gives you the exact IDs needed to populate your ETL.
A Practical Mapping Example
Let's walk through a common, real-world scenario: mapping I25.10 (Atherosclerotic heart disease of native coronary artery without angina pectoris).
- Identify the Source Code: Your source data contains the ICD-10-CM code
I25.10. - Look Up the Mapping: Using a tool like the Concept Lookup, you find
I25.10maps to the SNOMED CT concept 443502000 (Atherosclerotic heart disease of native coronary artery without angina pectoris). - Find the Standard Concept ID: You then grab the OMOP Standard Concept ID for that SNOMED concept, which is 45952327. This is the ID you'll load into your
condition_occurrencetable.
By consistently applying this logic, you build a dataset where every diagnosis of ICD-10 coronary artery disease, regardless of its original nuance, is represented by a single, unambiguous standard concept. This step is absolutely non-negotiable for enabling reliable network studies and any kind of advanced analytics across different datasets.
Mapping Tips for ETL Developers
From an implementation standpoint, keep these points in mind:
- Trust the 'Maps to' Relationship: In the OMOP vocabulary, the
CONCEPT_RELATIONSHIPtable is your source of truth. The 'Maps to' entries are expertly curated relationships that provide the definitive link from a source code to its standard equivalent. Start there. - Document Your Logic: Always keep a log of your mapping decisions, especially when you encounter ambiguous cases or have to make a judgment call. This transparency makes your ETL process defensible and reproducible.
- Automate Vocabulary Lookups: For any production-grade ETL pipeline, manual lookups aren't scalable. Use an API to perform these lookups programmatically. The OMOPHub Python and R SDKs were built for this. You can check out the API documentation for details on how to get started.
How to Programmatically Query CAD Concepts
While looking up codes by hand works for a quick check, it's simply not a sustainable approach for any real-world application. The moment you need to build an ETL pipeline, a cohort definition for a study, or a dynamic analytics dashboard, you hit a wall. The reality is that scalable, reproducible work requires programmatic access to your terminologies.
This is where a good REST API comes in. Using a service like the one from OMOPHub means you don't have to maintain your own local copy of the ATHENA vocabularies. It frees your team from the constant cycle of downloading, loading, and validating vocabulary updates, letting you query and map ICD 10 coronary artery disease concepts directly and far more efficiently.
Using SDKs for Python and R
To make API integration even cleaner, OMOPHub provides official SDKs that abstract away the lower-level HTTP requests and authentication. For anyone working in data science or engineering, these libraries let you interact with the OMOP vocabulary using familiar, native functions.
- Python SDK: Found on GitHub at OMOPHub/omophub-python, this is a go-to for data engineers building ETL workflows and machine learning specialists who need to standardize concept mappings.
- R SDK: Available at OMOPHub/omophub-R, this library is perfectly suited for biostatisticians and health researchers who live in R for their clinical analytics and cohort building.
The GitHub page for the Python SDK shows just how simple it is to get started. You can initialize the client and run a concept search in just a couple of lines.
As you can see, finding a specific code like "I25.10" is straightforward, returning a structured object with all the details you need.
Practical Code Examples for CAD Concepts
Let's walk through a common task with Python: you have a source ICD-10 code and need to find its standard SNOMED equivalent and understand its place in the hierarchy.
First, finding the ICD-10 code itself is a basic search. This snippet queries for "I25.10," which represents atherosclerotic heart disease without angina.
from omophub.client import Client
# It is recommended to set the API key as an environment variable
# export OMOPHUB_API_KEY="YOUR_API_KEY"
client = Client()
# Search for the ICD-10-CM code
concepts = client.concepts.search(
query="I25.10",
vocabulary_id=["ICD10CM"]
)
# Print the first result as a pretty JSON
print(concepts[0].model_dump_json(indent=2))
The API returns a clean JSON object. The critical piece of information for ETL is often the relationships array, which provides the direct bridge to the standard SNOMED concept via the Maps to relationship.
{
"concept_id": 45570535,
"concept_name": "Atherosclerotic heart disease of native coronary artery without angina pectoris",
"concept_code": "I25.10",
"vocabulary_id": "ICD10CM",
"relationships": [
{
"relationship_id": "Maps to",
"concept_id": 45952327,
"concept_name": "Atherosclerotic heart disease of native coronary artery without angina pectoris",
"concept_code": "443502000",
"vocabulary_id": "SNOMED"
}
]
}
Standardizing codes this way is more than a technical exercise. The burden of ICD 10 coronary artery disease is enormous, especially in G20+ countries like China, India, and Russia, which face staggering disability-adjusted life years (DALYs) from ischemic heart disease. For the teams building EHR tools and AI models to tackle this, mapping diverse international codes into the OMOP standard is a foundational step. OMOPHub’s REST API provides the tooling to securely traverse these concepts and their relationships, enabling the large-scale research needed to combat this global health issue. You can explore more on these global trends in this detailed report.
Pro Tip: Automate your concept set creation. Instead of manually curating lists of codes, you can programmatically build comprehensive concept sets for conditions like chronic ischemic heart disease. Use the API to traverse relationships like "Subsumes" or "Is a" to discover all child concepts. To see how this works in practice, check out our guide on how to perform a SNOMED CT code lookup. This technique not only saves an immense amount of time but also produces more accurate and complete cohorts by reducing human error.
Best Practices for ETL into the OMOP CDM
Getting raw source data, like records with an ICD-10 coronary artery disease code, successfully moved into the OMOP Common Data Model is much more than a technical exercise. It’s about creating a trustworthy, analytics-ready resource. A thoughtful Extract, Transform, and Load (ETL) process is what ensures your standardized data still holds its clinical truth, and that requires a solid game plan for version management, code mapping, and meticulous documentation.
For a data engineer, building a reliable ETL pipeline means truly getting to know the source vocabularies and how they relate to the OMOP standard concepts. You're not just moving data; you're translating clinical language. You'll need a clear approach for tricky situations, like handling deprecated codes or clarifying ambiguous clinical notes. To get a better handle on the foundational principles, check out our detailed guide on the OMOP Data Model.
Develop a Robust Mapping Strategy
The heart of any OMOP ETL work is the mapping strategy. At its core, the job is to connect every source code to its proper standard concept, which is almost always a SNOMED CT concept.
- Prioritize 'Maps to' Relationships: Your primary tool here is the
CONCEPT_RELATIONSHIPtable. Look for the 'Maps to' relationship first-it's a curated, high-confidence link from a source code to its standard equivalent. - Build Complete Concept Sets: Think bigger than just one-to-one code mapping. Use the
CONCEPT_RELATIONSHIPtable to walk the hierarchies (especially 'Is a' relationships) and construct comprehensive concept sets. This is how you capture a patient’s full clinical story instead of just a list of disconnected events. - Handle Deprecated Codes: Vocabularies change. You need a process for dealing with source codes that are no longer in use. The OMOP vocabularies are great for this, as they often include 'Maps to' relationships that point from an old code to its current replacement.
This screenshot from the OMOPHub documentation shows some of the resources we provide to help guide your ETL development from start to finish.
These guides are packed with detailed examples designed to help you work through complex mapping scenarios and apply best practices that actually work.
Document and Version Everything
In research and analytics, if you can't reproduce your results, they're not reliable. Your ETL process must be completely transparent and repeatable.
Make it a rule to document every single mapping decision, no matter how small. This is especially true for ambiguous cases where you had to make a judgment call. That documentation becomes the audit trail that validates your work and gives future data scientists a clear understanding of the data's lineage.
Consider the global trends in ischemic heart disease (IHD). While deaths coded with ICD-10 I20-I25 have decreased overall since 2000, the picture is inconsistent. Mortality is actually on the rise in some developing countries. For ETL developers and biostatisticians, this highlights just how critical precise vocabulary mapping is. Using tools that support versioned vocabularies ensures that your analysis stays consistent and meaningful, even as the codes and their mappings evolve over many years. You can read more about these global IHD mortality trends.
Avoiding Common Pitfalls in CAD Coding and Analytics
Even with the best intentions, mistakes in ICD 10 coronary artery disease coding and analysis are surprisingly common. Getting the data right is critical for everything from patient care to large-scale research, but errors can creep in at multiple points-first at the clinical coding stage, and later when that data is used for analytics.
One of the most persistent issues I see is the overuse of unspecified codes. It’s all too easy to default to I25.9 (Chronic ischemic heart disease, unspecified) when a patient's chart actually contains enough detail for a much more precise diagnosis. It's a seemingly harmless shortcut that erases vital clinical details, like the presence of angina or the specific location of atherosclerosis, which are absolutely crucial for both treatment planning and any downstream analysis.
Pitfalls in Clinical Coding
Most data integrity problems start right at the source: the initial coding. Clinicians and coders really need to be on the same page to prevent misrepresenting a patient's actual condition.
- Acute vs. Chronic Confusion: A classic mix-up is applying an acute code, like one from the I21.- (Acute Myocardial Infarction) series, for a patient whose history notes a "healed" or "old" MI. The correct path here is to use I25.2 (Old myocardial infarction). This code properly flags a past event, not a current medical emergency.
- Failure to Specify Complications: You'll often see documentation that just says "angina" without clarifying its nature. Not distinguishing between stable and unstable angina (I25.110) is a major oversight that can throw off risk models and cohort definitions entirely.
A critical error we often have to clean up is the failure to distinguish between disease in a native artery versus a bypass graft. Atherosclerosis in a graft absolutely requires a code from the I25.7- series. Using an I25.1- series code here is just plain wrong and fundamentally misrepresents the patient’s surgical history.
Challenges in Data Analytics
Once the data is captured, a whole new set of challenges appears for the analysts and data engineers tasked with making sense of it. If you're not careful, these issues can completely undermine your findings.
- Analyzing Raw Source Codes: Never run analytics directly on raw source ICD-10 codes without first standardizing them to a common data model. Sticking with source codes creates data silos and makes it nearly impossible to reliably compare or merge datasets from different EHRs, systems, or even countries.
- Ignoring Concept Hierarchies: When you're building a cohort, simply grabbing a single code is rarely enough. A proper cohort definition should take advantage of concept hierarchies to pull in all relevant child concepts. For instance, any study on chronic IHD should be designed to automatically include its various, more specific sub-types.
- Overlooking Vocabulary Versions: The ICD-10-CM vocabulary is updated every year. An analysis you run today might produce different results than the same analysis run a year ago simply because code definitions or their mappings have changed.
Expert Tip: The best way to sidestep these analytics pitfalls is to consistently map your source codes to standard concepts using a reliable, version-aware tool. For those working programmatically, the OMOPHub Python SDK or R SDK can automate this entire mapping process. You can find all the details in the official OMOPHub documentation.
Frequently Asked Questions About CAD Coding
Even for seasoned professionals, certain questions about ICD 10 coronary artery disease coding come up time and again. Let's tackle some of the most common ones, tying back to the practical tools and concepts we've covered.
What Is the Most Common ICD-10 Code for CAD?
For a straightforward, documented diagnosis of coronary artery disease without any mention of symptoms like chest pain, your primary code is I25.10 - Atherosclerotic heart disease of native coronary artery without angina pectoris. Think of this as the standard for asymptomatic, chronic CAD in a native vessel.
Of course, the moment angina enters the picture, you have to get more specific. If the patient has angina, you'll need to select a code from the I25.11- series, like I25.110 for unstable angina, to accurately reflect their clinical status.
Can I Use an Acute MI Code for a Patient With a History of a Heart Attack?
Absolutely not. This is a common but significant mistake that can throw off analytics entirely. Codes from the I21.- series are reserved exclusively for a current, active acute myocardial infarction.
For a past heart attack-one that has already occurred and healed-the correct code is I25.2 - Old myocardial infarction. Getting this right is fundamental for building an accurate patient history.
Always distinguish between an acute event and a chronic condition. Using an acute code for a historical condition fundamentally misrepresents the patient's current clinical status and can severely skew data quality for research and billing purposes.
How Do I Find the Standard OMOP Concept for an ICD-10 Code?
The quickest way is to use a purpose-built vocabulary browser. The OMOPHub Concept Lookup, for instance, lets you plug in any ICD-10 code and immediately see its "Maps to" relationship, which points you directly to the standard SNOMED concept.
When you need to do this programmatically for your ETL or analytics pipelines, your best bet is to use an SDK.
- Python SDK: github.com/OMOPHub/omophub-python
- R SDK: github.com/OMOPHub/omophub-R
These libraries handle the mapping process automatically, which not only ensures your mappings are correct and consistent but also saves a tremendous amount of development work. For more on implementation, check out the official documentation.
Ready to streamline your vocabulary management and accelerate your analytics? With OMOPHub, you can get instant, programmatic access to the latest OHDSI ATHENA vocabularies via a low-latency REST API. Skip the database setup and start querying concepts in minutes. Visit https://omophub.com to generate your free API key and make your first call.


