Loading documentation

Access required

Your account doesn't have access to the documentation. Contact your administrator.

Sign out
Skip to main content

ICD-10-CM Search

Status: stable Category: lookup Added: 2026-10-14 Last reviewed: 2026-10-14

Summary​

Type-ahead search across the US ICD-10-CM diagnosis code set. Pass a code fragment (S62.0, s620) or plain words (heart attack) and get back matching categories, subcategories and codes, closest first. Designed to power a diagnosis picker; safe to call on every keystroke once q is at least two characters.

The code set is ICD-10-CM (the US clinical modification), not WHO ICD-10 and not ICD-10-PCS. Every response names the release it reflects (for example FY2027), because a code's validity is tied to the year.

Endpoint​

FieldValue
MethodGET
Path/api/lookup/icd10cm/search
Full URLhttps://engine.tripod-health.com/api/lookup/icd10cm/search
AuthenticationAPI key (required)
Request bodynone
Response bodyapplication/json
IdempotentYes
Rate-limitedYes

Authentication​

Send a valid API key in the apikey header. See authentication.md.

Request​

Headers​

HeaderRequiredDescription
apikeyYesConsumer API key.

Path parameters​

None.

Query parameters​

ParameterTypeRequiredDefaultDescription
qstringYes—Search text. Minimum two characters. A code-shaped value (a letter then a digit, such as S6, S62.0 or s620) is matched as a code prefix, with or without the dot and in any case. Anything else is matched word by word, as word prefixes, against the official descriptions, the inclusion terms and the alphabetic index — so heart attack finds I21.9.
billablestringNo—true returns only billable codes; false returns only non-billable headers. Omit it to get both. Any other value is a 400.
limitintNo10Maximum results to return. Range 1–50.

Results are ranked in this order: an exact code match; code-prefix matches, shorter codes first; text matches, a hit on the description above a hit on an inclusion or index term, billable codes above headers. When those return fewer than limit rows, a typo-tolerant match on the descriptions fills the remainder (diabetis still finds diabetes codes).

Chapters and sections are never returned by search. Browse them with /api/lookup/icd10cm/tree.

Body​

None.

Response​

Success — 200 OK​

Request: GET /api/lookup/icd10cm/search?q=heart%20attack&limit=5

{
"results": [
{
"code": "I21.9",
"label": "Acute myocardial infarction, unspecified",
"kind": "code",
"billable": true
},
{
"code": "I20.9",
"label": "Angina pectoris, unspecified",
"kind": "code",
"billable": true
},
{
"code": "I45.9",
"label": "Conduction disorder, unspecified",
"kind": "code",
"billable": true
},
{
"code": "R55",
"label": "Syncope and collapse",
"kind": "code",
"billable": true
},
{
"code": "F45.8",
"label": "Other somatoform disorders",
"kind": "code",
"billable": true
}
],
"release": "FY2027",
"request_id": "04b584c6-7c44-4166-b98a-3e5f525f8df3",
"timestamp": "2026-10-14T00:15:09.507Z"
}

label is always the code's official description, so a result that matched on an inclusion or index term need not repeat the words you typed.

results is always present. An empty array is a normal response (the query matched nothing), not an error.

Response fields​

FieldTypeAlways presentDescription
resultsarrayYesZero or more matches, in rank order.
results[].codestringYesThe code, always uppercase and dotted after the third character (S62.001A, R55).
results[].labelstringYesThe official long description.
results[].kindstringYescategory (three-character header), subcategory (a longer header), or code (billable).
results[].billablebooleanYestrue when the code is valid on a claim. Headers are false. Test this field, not kind.
releasestring | nullYesThe ICD-10-CM release the results reflect, e.g. FY2027.
request_idstringYesCorrelation ID. Quote in support tickets.
timestampstring (ISO 8601 UTC)YesServer time when the response was emitted.

Status codes​

CodeMeaningWhen
200OKSearch ran. results may be empty.
400ValidationErrorq missing or shorter than two characters, billable not true/false, limit out of range, or a parameter repeated. field names the offender.
401UnauthenticatedMissing or invalid API key.
429RateLimitedPer-consumer rate limit exceeded.
500InternalErrorUnexpected failure. Quote request_id in the ticket.

Examples​

curl​

curl -sS "https://engine.tripod-health.com/api/lookup/icd10cm/search?q=heart%20attack&limit=5" \
-H "apikey: $ENGINE_API_KEY"

Code prefix, billable codes only​

curl -sS "https://engine.tripod-health.com/api/lookup/icd10cm/search?q=S62.00&billable=true&limit=3" \
-H "apikey: $ENGINE_API_KEY"
{
"results": [
{
"code": "S62.001A",
"label": "Unspecified fracture of navicular [scaphoid] bone of right wrist, initial encounter for closed fracture",
"kind": "code",
"billable": true
},
{
"code": "S62.001B",
"label": "Unspecified fracture of navicular [scaphoid] bone of right wrist, initial encounter for open fracture",
"kind": "code",
"billable": true
},
{
"code": "S62.001D",
"label": "Unspecified fracture of navicular [scaphoid] bone of right wrist, subsequent encounter for fracture with routine healing",
"kind": "code",
"billable": true
}
],
"release": "FY2027",
"request_id": "af6753ff-37c0-45cd-9d9f-cbda57ffb4ed",
"timestamp": "2026-10-14T00:15:28.681Z"
}

Python (requests)​

# Uses the call() helper from quickstart.md.
from urllib.parse import quote

result = call("GET", f"/api/lookup/icd10cm/search?q={quote('heart attack')}&billable=true")
print("release:", result["release"])
for row in result["results"]:
print(f"{row['code']:9} {row['label']}")

Node.js (native fetch)​

// Uses the call() helper from quickstart.md.
const q = encodeURIComponent("heart attack");
const result = await call("GET", `/api/lookup/icd10cm/search?q=${q}&billable=true`);
for (const row of result.results) {
console.log(`${row.code.padEnd(9)} ${row.label}`);
}

TypeScript​

interface Icd10cmSearchResult {
code: string;
label: string;
kind: "category" | "subcategory" | "code";
billable: boolean;
}

interface Icd10cmSearchResponse {
results: Icd10cmSearchResult[];
release: string | null;
request_id: string;
timestamp: string;
}

const result = await call<Icd10cmSearchResponse>(
"GET",
"/api/lookup/icd10cm/search?q=S62.0&billable=true",
);

Error scenarios​

q too short​

Send:

curl -sS "https://engine.tripod-health.com/api/lookup/icd10cm/search?q=h" \
-H "apikey: $ENGINE_API_KEY" \
-w "\nHTTP %{http_code}\n"

Receive (400):

{
"timestamp": "2026-10-14T00:15:27.698Z",
"error": "ValidationError",
"message": "Query parameter 'q' must be at least 2 characters",
"field": "q",
"request_id": "a946add1-3a79-4db7-8239-713fe36d89bd"
}

Invalid billable​

Send:

curl -sS "https://engine.tripod-health.com/api/lookup/icd10cm/search?q=S62&billable=yes" \
-H "apikey: $ENGINE_API_KEY" \
-w "\nHTTP %{http_code}\n"

Receive (400):

{
"timestamp": "2026-10-14T00:15:28.327Z",
"error": "ValidationError",
"message": "Query parameter 'billable' must be true or false",
"field": "billable",
"request_id": "822b5d25-6a2b-4ac2-a3f4-a4707f299e45"
}

Intended use​

  • Diagnosis pickers and autocomplete where a user types either a code fragment or everyday words and picks a code.
  • Claim-entry forms that must only offer codes valid on a claim: pass billable=true.
  • Translating lay or index vocabulary into codes — the search covers the alphabetic index, so terms that never appear in an official description still find their code.

Mistaken use​

  • Do not use search to fetch a code you already have. Use /api/lookup/icd10cm/get — one record with its notes and every ancestor's notes.
  • Do not treat search results as coding advice. A match means the words or code fragment matched; whether the code is correct for a case depends on the coding notes. Read them via /api/lookup/icd10cm/get.
  • Do not use search to browse chapters or sections. They are never returned here. Use /api/lookup/icd10cm/tree.
  • Do not test kind to decide whether a code is billable. Use the billable field — a three-character code such as R55 is billable.

Debugging​

  1. Capture request_id. Present in every response body.
  2. 400 ValidationError with field: "q". The text was missing or shorter than two characters. UI clients should not send the request until the user has typed at least two characters.
  3. Expected code missing from results. Raise limit, or narrow q — a broad word such as fracture matches thousands of codes and only the top limit are returned. If you pass billable=true, headers such as S62 are excluded.
  4. Results reflect a different year than you expected. Check release; the code set changes every fiscal year.

Rate limits​

See rate-limits.md for the current per-consumer limits.

Change history​

DateChange
2026-10-14Initial publication.
2026-10-14The engine assigns every request ID; an X-Request-ID request header is not used.