Back to Blog
TechnicalMay 5, 2026

ICD-10 Code Lookup API: Search Diagnoses and Procedures Programmatically

ICD-10 has 126,000+ codes across diagnoses (CM) and procedures (PCS). Here's how to look up codes, search by description, and get FHIR codings and HCC mappings — with working TypeScript examples.

ICD-10 code lookup API tutorial

ICD-10 is the backbone of clinical coding in the US. Every diagnosis on a claim, every procedure in an EHR, every risk adjustment model — they all reference ICD-10 codes. But working with the code set programmatically is painful: CMS publishes flat files with inconsistent formatting, and the sheer volume (72,000+ CM codes, 54,000+ PCS codes) makes local lookups unwieldy.

This tutorial shows how to look up, search, and batch-process ICD-10 codes using FHIRfly's API and TypeScript SDK.

ICD-10-CM vs. ICD-10-PCS

The US uses two ICD-10 code sets:

  • ICD-10-CM (Clinical Modification) — diagnosis codes like E11.9 (Type 2 diabetes without complications). Used on all claims.
  • ICD-10-PCS (Procedure Coding System) — inpatient procedure codes like 02HA0QZ (insertion of device in heart). Used only on inpatient claims.

FHIRfly covers both in a single endpoint. The API auto-detects which code system you're querying based on the code format.

Setup

npm install @fhirfly-io/terminology
import { Fhirfly } from "@fhirfly-io/terminology";

const fhirfly = new Fhirfly({ apiKey: process.env.FHIRFLY_API_KEY! });

Free tier includes 10,000 requests/month — get your key here.

Look Up a Single Code

The most common operation: you have an ICD-10 code and need the description and metadata.

// Diagnosis code (ICD-10-CM)
const result = await fhirfly.icd10.lookup("E11.9", { shape: "standard" });

console.log(result.data.code);
// "E11.9"

console.log(result.data.type);
// "cm"

console.log(result.data.display);
// "Type 2 diabetes mellitus without complications"

console.log(result.data.chapter);
// "4"

console.log(result.data.chapter_description);
// "Endocrine, nutritional and metabolic diseases"

console.log(result.data.billable);
// true
// Procedure code (ICD-10-PCS)
const proc = await fhirfly.icd10.lookup("02HA0QZ", { shape: "standard" });

console.log(proc.data.display);
// "Insertion of Infusion Device into Heart, Open Approach"

console.log(proc.data.body_system);
// "Heart and Great Vessels"

console.log(proc.data.root_operation);
// "Insertion"

Response Shapes

ShapeFieldsBest for
compactCode, type (cm/pcs), display nameAutocomplete, search results
standard+ Chapter, section, billable flag, FHIR coding, HCC mappings, SNOMEDClaims processing, detail views
full+ Includes/excludes notes, code-first rules, effective dates, PCS componentsCompliance auditing, coding tools

FHIR-Ready Coding

Every response includes a pre-built FHIR coding:

const result = await fhirfly.icd10.lookup("J18.9", { shape: "standard" });

console.log(result.data.fhir_coding);
// {
//   system: "http://hl7.org/fhir/sid/icd-10-cm",
//   code: "J18.9",
//   display: "Pneumonia, unspecified organism"
// }

Drop this directly into a FHIR Condition.code or Encounter.reasonCode.

Search by Description

When users need to find a code from a clinical description — or when you're mapping free-text diagnoses to ICD-10:

const results = await fhirfly.icd10.search(
  { q: "type 2 diabetes", billable: true },
  { limit: 10 }
);

console.log(`Found ${results.total} billable codes matching "type 2 diabetes"`);

for (const code of results.items) {
  console.log(`${code.code} — ${code.display}`);
}
// "E11.9 — Type 2 diabetes mellitus without complications"
// "E11.65 — Type 2 diabetes mellitus with hyperglycemia"
// "E11.21 — Type 2 diabetes mellitus with diabetic nephropathy"
// ...

Search Filters

Narrow results with structured filters:

// Only diagnosis codes
await fhirfly.icd10.search({ q: "fracture femur", code_system: "CM" });

// Only billable codes (leaf nodes)
await fhirfly.icd10.search({ q: "hypertension", billable: true });

// Filter by chapter
await fhirfly.icd10.search({ q: "infection", chapter: "1" }); // Infectious diseases

// PCS: filter by body system and root operation
await fhirfly.icd10.search({
  q: "knee",
  code_system: "PCS",
  body_system: "Lower Joints",
  root_operation: "Replacement",
});

// Sort by code for organized output
await fhirfly.icd10.search(
  { q: "acute myocardial infarction" },
  { sort: "code" }
);

Pagination

let page = 1;
let hasMore = true;

while (hasMore) {
  const results = await fhirfly.icd10.search(
    { q: "neoplasm", code_system: "CM", billable: true },
    { limit: 50, page }
  );

  for (const code of results.items) {
    await processCode(code);
  }

  hasMore = results.has_more;
  page++;
}

HCC Risk Adjustment Mappings

For Medicare Advantage and risk adjustment workflows, the standard shape includes HCC (Hierarchical Condition Category) mappings:

const result = await fhirfly.icd10.lookup("E11.9", { shape: "standard" });

console.log(result.data.hcc);
// [{ cc_number: 19, model_version: "V28", model_type: "CMS-HCC" }]

This tells you that E11.9 maps to HCC 19 (Diabetes without Complication) in the CMS-HCC V28 model. Essential for risk adjustment factor (RAF) score calculations.

The full shape includes additional HCC detail like payment year and release type — useful for auditing which model version applies to a specific date of service.

SNOMED CT Cross-References

ICD-10-CM codes include SNOMED CT mappings where available:

const result = await fhirfly.icd10.lookup("I10", { shape: "standard" });

console.log(result.data.snomed);
// [{ concept_id: "38341003", term: "Hypertensive disorder" }]

Useful when you need to bridge between ICD-10 (billing) and SNOMED CT (clinical) terminologies.

Batch Lookups

Processing a claims file with hundreds of diagnosis codes? Use the batch endpoint:

const response = await fhirfly.icd10.lookupMany(
  ["E11.9", "I10", "J18.9", "Z99.99"],
  { shape: "standard" }
);

for (const result of response.results) {
  if (result.status === "ok") {
    const billable = result.data.billable ? "billable" : "header";
    console.log(`${result.input}: ${result.data.display} (${billable})`);
  } else {
    console.log(`${result.input}: ${result.status}`);
  }
}
// "E11.9: Type 2 diabetes mellitus without complications (billable)"
// "I10: Essential (primary) hypertension (billable)"
// "J18.9: Pneumonia, unspecified organism (billable)"
// "Z99.99: not_found"

Batch accepts up to 100 codes per request. You can mix CM and PCS codes in the same batch.

Coding Rules (Full Shape)

The full shape exposes ICD-10-CM coding rules that are critical for compliance:

const result = await fhirfly.icd10.lookup("E11.9", { shape: "full" });

// Excludes1: codes that can NEVER be used with this code
console.log(result.data.excludes1);
// ["E13.- drug or chemical induced diabetes mellitus"]

// Use additional: codes that should be coded additionally
console.log(result.data.use_additional);
// ["Use additional code to identify control using insulin (Z79.4)"]

These rules help build compliant coding suggestion tools — flagging invalid code combinations before claims submission.

REST API (Without the SDK)

# Single lookup
curl -H "x-api-key: $FHIRFLY_API_KEY" \
  "https://api.fhirfly.io/v1/icd10/E11.9?shape=standard"

# Search
curl -H "x-api-key: $FHIRFLY_API_KEY" \
  "https://api.fhirfly.io/v1/icd10/search?q=diabetes&billable=true&limit=10"

# Batch
curl -X POST -H "x-api-key: $FHIRFLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"codes": ["E11.9", "I10", "J18.9"]}' \
  "https://api.fhirfly.io/v1/icd10/_batch?shape=standard"

Common Use Cases

Use CaseApproach
Claims enrichmentBatch lookup with standard shape
Diagnosis search in EHRSearch with billable: true, compact shape
HCC/RAF calculationLookup with standard shape, read hcc field
Code validationBatch lookup, check for not_found status
FHIR Condition resourcesLookup, use fhir_coding field
Coding compliance checksLookup with full shape, check excludes/includes
ICD-10 to SNOMED mappingLookup with standard shape, read snomed field

Key Takeaways

  • 126K+ codes across ICD-10-CM (diagnoses) and ICD-10-PCS (procedures)
  • Auto-detection — the API knows whether your code is CM or PCS
  • Billable flag — instantly identify leaf-node codes valid for claims
  • HCC mappings — built-in risk adjustment crosswalks
  • SNOMED cross-references — bridge billing and clinical terminologies
  • FHIR coding included — ready for FHIR resources
  • Batch endpoint — up to 100 codes per request

Next Steps

  1. Get a free API key from the FHIRfly dashboard
  2. Install the SDK: npm install @fhirfly-io/terminology
  3. Try searching for codes in your domain
  4. Check the ICD-10 API docs for the complete parameter reference
Tags:icd-10tutorialsdkdiagnosis-codesapi

Written by The FHIRfly Team — a collective of healthcare data experts, AI specialists, and industry veterans building better clinical coding APIs.

Ready to get started?

Try FHIRfly free — no credit card required. Get instant access to clinical coding APIs.