> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omophub.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mapping concepts across vocabularies

> Map concepts between OMOP vocabularies using the OMOPHub Node.js SDK - crosswalk SNOMED, ICD-10, LOINC, and RxNorm codes from TypeScript applications.

## Get Mappings for a Concept

Find how a concept maps to other vocabularies:

```ts theme={null}
const { data, error } = await client.mappings.get(201826); // Type 2 diabetes mellitus
if (error) throw new Error(error.message);

for (const mapping of data.mappings) {
  console.log(`${mapping.relationship_id}: ${mapping.target_concept_name}`);
}
```

## Filter by Target Vocabulary

```ts theme={null}
const { data } = await client.mappings.get(201826, {
  targetVocabulary: 'ICD10CM',
});

for (const mapping of data?.mappings ?? []) {
  console.log(`${mapping.target_concept_id}: ${mapping.target_concept_name}`);
}
```

## Include Invalid Mappings

```ts theme={null}
await client.mappings.get(201826, {
  targetVocabulary: 'ICD10CM',
  includeInvalid: true,
});
```

## Use Specific Vocabulary Version

```ts theme={null}
await client.mappings.get(201826, {
  targetVocabulary: 'ICD10CM',
  vocabRelease: '2025.1',
});
```

## Map Multiple Concepts

Map a batch of concept IDs to a target vocabulary:

```ts theme={null}
const { data } = await client.mappings.map({
  targetVocabulary: 'ICD10CM',
  sourceConcepts: [201826, 4329847], // Diabetes, MI
});

for (const mapping of data?.mappings ?? []) {
  console.log(`${mapping.source_concept_id} → ${mapping.target_concept_id}`);
}
```

## Map Using Vocabulary Codes

Map concepts directly using vocabulary codes instead of OMOP concept IDs:

```ts theme={null}
const { data } = await client.mappings.map({
  targetVocabulary: 'RxNorm',
  sourceCodes: [
    { vocabulary_id: 'SNOMED', concept_code: '387517004' }, // Acetaminophen
    { vocabulary_id: 'SNOMED', concept_code: '108774000' }, // Anastrozole
  ],
});

for (const mapping of data?.mappings ?? []) {
  console.log(`${mapping.source_concept_name} → ${mapping.target_concept_name}`);
}
```

<Note>
  Use `sourceCodes` when you have vocabulary-specific codes (e.g. SNOMED codes from your source system).
  Use `sourceConcepts` when you already have OMOP concept IDs.
  **You cannot use both** in the same request - the SDK enforces this at the type level via a discriminated union and re-validates at runtime so JS callers also get a structured `missing_required_field` error rather than a wire 400.
</Note>

## Map with Specific Mapping Type

Filter mappings by type:

```ts theme={null}
await client.mappings.map({
  targetVocabulary: 'ICD10CM',
  sourceConcepts: [201826, 192671],
  mappingType: 'direct', // 'direct' | 'equivalent' | 'broader' | 'narrower'
});
```

## Vocabulary Release Pinning

`vocabRelease` is sent as a query-string parameter, **not in the JSON body** - matches the Python SDK convention:

```ts theme={null}
await client.mappings.map({
  targetVocabulary: 'SNOMED',
  sourceConcepts: [201826],
  vocabRelease: '2025.1',
});
// → POST /concepts/map?vocab_release=2025.1
```

## Procedure-Domain Vocabulary Priority

For Procedure-domain sources, the API applies a fallback vocabulary priority when `targetVocabulary` is left to "best fit" semantics:

```
SNOMED → LOINC → CPT4 → HCPCS → ICD10PCS → ICD9Proc → OPCS4 → OMOP Extension
```

## Common Use Case: SNOMED → ICD-10

**Option 1: Direct mapping using vocabulary codes (recommended)**

```ts theme={null}
const { data } = await client.mappings.map({
  targetVocabulary: 'ICD10CM',
  sourceCodes: [
    { vocabulary_id: 'SNOMED', concept_code: '44054006' }, // Type 2 diabetes
  ],
});

for (const m of data?.mappings ?? []) {
  console.log(`  → ${m.target_concept_name} (${m.target_concept_code})`);
}
```

**Option 2: Using OMOP concept IDs**

```ts theme={null}
// First resolve the OMOP concept ID
const lookup = await client.concepts.getByCode('SNOMED', '44054006');
if (lookup.error || !lookup.data) throw new Error('Concept not found');

// Then map using the concept ID
const { data } = await client.mappings.get(lookup.data.concept_id, {
  targetVocabulary: 'ICD10CM',
});

console.log(`Mappings for ${lookup.data.concept_name}:`);
for (const m of data?.mappings ?? []) {
  console.log(`  → ${m.target_concept_name}`);
}
```

## Idempotency

POST endpoints (`mappings.map`) only retry on transient failures when an `Idempotency-Key` is provided:

```ts theme={null}
await client.mappings.map({
  targetVocabulary: 'SNOMED',
  sourceConcepts: [201826],
  idempotencyKey: 'my-pipeline-run-2026-05-30-batch-1',
});
```

### Parameters

| Parameter          | Type                                                  | Default                   | Description                                              |
| ------------------ | ----------------------------------------------------- | ------------------------- | -------------------------------------------------------- |
| `targetVocabulary` | string                                                | required                  | Target vocabulary ID (e.g. `'SNOMED'`, `'RxNorm'`)       |
| `sourceConcepts`   | number\[]                                             | XOR with `sourceCodes`    | OMOP concept IDs to map                                  |
| `sourceCodes`      | `{ vocabulary_id, concept_code }[]`                   | XOR with `sourceConcepts` | Native vocabulary codes                                  |
| `mappingType`      | `'direct' \| 'equivalent' \| 'broader' \| 'narrower'` | -                         | Filter mappings by type                                  |
| `includeInvalid`   | boolean                                               | false                     | Include deprecated mappings                              |
| `vocabRelease`     | string                                                | -                         | Pin to a vocabulary release (sent as query param)        |
| `idempotencyKey`   | string                                                | -                         | Per-call `Idempotency-Key` header (enables retry on 5xx) |
