DEV Community

easysolutions906
easysolutions906

Posted on

Adding ICD-10 Code Search to Your Healthcare Application

Adding ICD-10 Code Search to Your Healthcare Application

Every healthcare application that submits claims, generates clinical documentation, or reports quality measures needs ICD-10 codes. If you are building an EHR, a patient intake system, a billing platform, or a clinical decision support tool, you need a way to search and validate diagnosis codes. The CMS 2025 code set contains 74,260 codes. Embedding that into a searchable, fast API endpoint is not trivial.

This article walks through integrating ICD-10 code search into a patient intake form: autocomplete search as the user types, code validation on form submission, and chapter-level categorization for reporting.

The problem with existing solutions

Most healthcare developers either download the CMS text files and parse them into a database, use the bulky UMLS API (which requires a license agreement and has aggressive rate limits), or hard-code a subset of common codes. None of these are great:

  • Self-hosted databases require schema design, import scripts, and annual updates when CMS publishes new codes every October
  • UMLS/NLM APIs are slow, rate-limited, and require institutional credentials
  • Hard-coded subsets inevitably miss the code your users need

The ICD-10 API embeds all 74,260 CMS 2025 codes locally, indexes them for fast text search, and returns results in under 50ms.

Searching by symptom description

Your intake form needs an autocomplete that searches by symptom or condition name. Here is the API call:

curl "https://icd10-api-production.up.railway.app/search?q=chest+pain&limit=5"
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "query": "chest pain",
  "total": 18,
  "results": [
    {
      "code": "R07.9",
      "description": "Chest pain, unspecified",
      "chapter": 18,
      "chapterTitle": "Symptoms, signs and abnormal clinical and laboratory findings",
      "billable": true
    },
    {
      "code": "R07.1",
      "description": "Chest pain on breathing",
      "chapter": 18,
      "chapterTitle": "Symptoms, signs and abnormal clinical and laboratory findings",
      "billable": true
    },
    {
      "code": "R07.89",
      "description": "Other chest pain",
      "chapter": 18,
      "chapterTitle": "Symptoms, signs and abnormal clinical and laboratory findings",
      "billable": true
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The billable field tells you whether the code is specific enough for claims submission. Non-billable codes (category headers) need to be drilled down further.

Building the autocomplete in JavaScript

Here is a React-style autocomplete component that searches as the user types:

const searchICD10 = async (query) => {
  if (query.length < 2) return [];

  const res = await fetch(
    `https://icd10-api-production.up.railway.app/search?q=${encodeURIComponent(query)}&limit=10`
  );
  const data = await res.json();

  return data.results.map((r) => ({
    code: r.code,
    label: `${r.code} - ${r.description}`,
    billable: r.billable,
  }));
};

// Debounced search on keystroke
let timeout;
const onInputChange = (value) => {
  clearTimeout(timeout);
  timeout = setTimeout(async () => {
    const results = await searchICD10(value);
    renderSuggestions(results);
  }, 300);
};
Enter fullscreen mode Exit fullscreen mode

Validating codes on form submission

Before submitting a claim, validate that the selected code exists and is billable:

const validateDiagnosisCode = async (code) => {
  const res = await fetch(
    `https://icd10-api-production.up.railway.app/validate?code=${encodeURIComponent(code)}`
  );
  const data = await res.json();

  if (!data.valid) {
    return { ok: false, error: `Invalid ICD-10 code: ${code}` };
  }

  if (!data.billable) {
    return {
      ok: false,
      error: `${code} is a category header, not a billable code. Please select a more specific code.`,
    };
  }

  return { ok: true, code: data.code, description: data.description };
};

// On form submission
const handleSubmit = async (formData) => {
  const diagnosisValidation = await validateDiagnosisCode(formData.diagnosisCode);

  if (!diagnosisValidation.ok) {
    showError(diagnosisValidation.error);
    return;
  }

  await submitClaim({
    ...formData,
    diagnosisCode: diagnosisValidation.code,
    diagnosisDescription: diagnosisValidation.description,
  });
};
Enter fullscreen mode Exit fullscreen mode

Looking up a specific code

When you have a code and need its details:

curl "https://icd10-api-production.up.railway.app/lookup?code=E11.9"
Enter fullscreen mode Exit fullscreen mode
{
  "code": "E11.9",
  "description": "Type 2 diabetes mellitus without complications",
  "formatted": "E11.9",
  "chapter": 4,
  "chapterTitle": "Endocrine, nutritional and metabolic diseases",
  "chapterRange": "E00-E89",
  "billable": true,
  "valid": true
}
Enter fullscreen mode Exit fullscreen mode

This is useful for displaying human-readable diagnosis names in patient records, discharge summaries, and encounter histories.

Batch validation for claims processing

If your billing system processes batches of claims, validate all diagnosis codes at once:

curl -X POST https://icd10-api-production.up.railway.app/validate/batch \
  -H 'Content-Type: application/json' \
  -d '{"codes": ["E11.9", "J06.9", "INVALID", "M54.5"]}'
Enter fullscreen mode Exit fullscreen mode

The response tells you which codes are valid, which are invalid, and which are non-billable category headers -- before you submit to the payer and get rejections.

Using the MCP server for clinical workflows

The healthcare MCP server (@easysolutions906/mcp-healthcare) includes ICD-10 as one of 10 tools alongside NPI lookup, NDC drug search, and DEA validation. Install it for Claude Desktop:

{
  "mcpServers": {
    "healthcare": {
      "command": "npx",
      "args": ["-y", "@easysolutions906/mcp-healthcare"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then ask Claude: "What is the ICD-10 code for type 2 diabetes with diabetic retinopathy?" It will search the full code set and return the specific billable code. This is useful for clinical coders, medical billers, and developers testing their integrations without memorizing code ranges.

Data freshness

The ICD-10 code set is updated annually by CMS every October. The API embeds the CMS 2025 code set (74,260 codes) and will update when the 2026 set is published. Hit the /data-info endpoint to check the build date and record count at any time.

Getting started

  1. Search codes: GET /search?q=diabetes&limit=10
  2. Look up a code: GET /lookup?code=E11.9
  3. Validate a code: GET /validate?code=E11.9
  4. Batch validate: POST /validate/batch with {"codes": [...]}
  5. MCP server: npx @easysolutions906/mcp-healthcare

No API key required. The dataset is public CMS data, and the API is free to use.

Top comments (0)