# KodeMed — Thesaurus Search REST API (Partner Integration) Partner-facing guide for calling KodeMed's classification search (ICD-10-GM, CHOP, ATC) from an external system (an EHR, a practice-management suite, a HIS). It returns, per hit, the **code**, its **official label**, and **where the match came from** (systematic catalogue vs. alphabetical index vs. inclusion/note text) so the caller can present or auto-complete codes with the same quality the KodeMed UI shows. > **License**: classification search is gated by the customer's KodeMed licence > (`module.thesaurus` / `module.ambulatory-icd10-search`). Confirm the target > deployment is licensed for external search before integrating. ## Base URL The DataServer, as configured per deployment. Examples: | Deployment | DataServer base | |---|---| | Docker (Caddy, IP mode) | `https://:8444` | | Docker (domain mode) | `https://data.` | | Native install | `http://:8081` | All paths below are relative to that base. ## Endpoints | Method | Path | Purpose | |---|---|---| | GET | `/api/thesaurus/search/icd10` | Search ICD-10-GM | | GET | `/api/thesaurus/search/chop` | Search CHOP | | GET | `/api/thesaurus/search` | Unified search (pass `type=ICD10\|CHOP\|ATC`) | | GET | `/api/thesaurus/children/{type}/{parent}` | Direct children of a code (hierarchy) | ### Query parameters | Param | Default | Notes | |---|---|---| | `q` | *(required)* | Search text **or** a code prefix (e.g. `Diabetes`, `E11`, `bpco`). Common medical abbreviations are expanded automatically (per language). | | `type` | — | `ICD10` / `CHOP` / `ATC` (unified `/search` only). | | `version` | `2026` | Classification year. | | `lang` | `de` | `de` / `fr` / `it`. **Note the parameter is `lang`, not `language`.** | | `codableOnly` | `false` | `true` = only billable/terminal codes (drops category/header nodes). | | `page` / `size` | `0` / `20` | Pagination (`size` max 100). | | `ageYears`, `ageDays`, `sex`, `filterPlausibility` | — | Optional patient context; with `filterPlausibility=true`, age/sex-incompatible codes are removed (see `patientContext.filteredCount`). | ## Response ```jsonc { "results": [ { "classificationType": "ICD10", "code": "E11.72", "text": "…", // matched label "textLong": "…", // full official (PREFERRED_LONG) label "textType": "PREFERRED", // PREFERRED | SYNONYM | INCLUSION | EXCLUSION | NOTE … "source": "OFFICIAL", "isCodable": true, // terminal/billable code "parentCode": "E11", "matchedText": "…", // the specific text that matched the query "matchSourceCategory": "SYSTEMATIC" // see below } ], "totalResults": 992, "page": 0, "size": 20, "totalPages": 50, "patientContext": { "ageYears": 45, "sex": "M", "filteredCount": 5 } // when age/sex passed } ``` **`matchSourceCategory`** tells the caller *why* a code matched — the "source" hint the partner asked for: | Value | Meaning | |---|---| | `SYSTEMATIC` | Matched the code's official systematic label. | | `ALPHABETICAL_INDEX` | Matched an alphabetical-index synonym. | | `INCLUSION` | Matched an Inklusivum text of the code. | | `NOTE` | Matched a note/Hinweis text. | ## Type-ahead and re-displaying saved codes Search is for the user typing. Two other endpoints matter once the integration stores what they picked. | Method | Path | Purpose | |---|---|---| | GET | `/api/thesaurus/autocomplete/{type}` | Type-ahead suggestions. `{type}` is `ICD10` / `CHOP` / `ATC`; params `q`, `version`, `lang`, `limit` (default 10). Cheaper than `/search` per keystroke. | | GET | `/api/thesaurus/code/{type}/{code}` | One code, with its full official label. | | POST | `/api/thesaurus/batch-lookup` | Many codes of **one** type, in one request. | | POST | `/api/thesaurus/batch-descriptions` | Many codes of **mixed** types (ICD-10 + CHOP + ATC), in one request. | **Use the batch endpoints when reopening a stored record.** A record holding fifteen codes needs fifteen labels; fetching them one at a time is fifteen round trips for an answer that comes back in one. ```jsonc // POST /api/thesaurus/batch-lookup { "classificationType": "ICD10", "codes": ["E11.72", "I10.00"], "version": "2026", "language": "fr" // NOTE: "language" here, NOT "lang" } ``` > ⚠ **The name of the language field differs between the two styles.** Query > parameters take **`lang`**; the JSON bodies of the two batch endpoints take > **`language`**. Sending the wrong one does not fail loudly — it silently falls back > to the default (German), so the integration looks like it works until somebody > notices French labels never arrive. The response is a map keyed by code, so a caller can look each one up directly rather than scanning a list — and a code that does not exist in that version is simply absent from the map rather than returned as an empty entry. ## Example ```bash curl -s "https://:8444/api/thesaurus/search/icd10?q=Diabetes%20Typ%202&lang=de&version=2026&size=5" ``` returns the E11.7x family (and related codes) with `isCodable`, `matchSourceCategory` and the full `textLong` label for each hit. Switching `lang=fr` and querying `q=bpco` returns the J44 (COPD) family via automatic abbreviation expansion. ## Integration notes - **Use the API port**, not the UI port: search lives on the **DataServer** (`:8444` Docker / `:8081` native), not the CodingUI (`:443`/`3000`). - `q` doubles as a code-prefix search — `q=79` (CHOP) returns the 79.x family; the API dots partial codes internally, so `790` resolves to `79.0`. - Prefer `/search/icd10` and `/search/chop` over the unified endpoint when the caller already knows the catalogue — they are simpler and skip the type dispatch. - Results are ordered best-first for text queries and in ascending code order for code prefixes; do not re-sort code-prefix results client-side. --- **Support**: support@kodemed.ch | www.kodemed.ch *KodeMed Thesaurus REST API — Partner Integration Guide v2026.10 — 2026-10-08*