> ## 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.

# FHIR ValueSet/$expand for OMOP concept sets

> Expand a FHIR ValueSet into its complete list of matching codes - hierarchy-aware, version-pinned expansions across SNOMED, LOINC, and RxNorm.

## Overview

Expands an implicit ValueSet to return a paginated list of matching codes. This powers dropdown menus, autocomplete, and template validation in EHRbase, HAPI FHIR, and other FHIR clients.

OMOPHub supports implicit ValueSets defined by code system URIs - no stored ValueSet definitions required.

## Supported Patterns

### All codes from a code system

```bash theme={null}
curl "https://fhir.omophub.com/fhir/r4/ValueSet/\$expand?\
url=http://snomed.info/sct?fhir_vs&count=5" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Descendants of a concept (is-a filter)

```bash theme={null}
curl "https://fhir.omophub.com/fhir/r4/ValueSet/\$expand?\
url=http://snomed.info/sct?fhir_vs=isa/73211009&count=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

This expands to all descendants of "Diabetes mellitus" (73211009). This is the pattern EHRbase uses in template `referenceSetUri`:

```xml theme={null}
<referenceSetUri>terminology://fhir.omophub.com/fhir/r4/ValueSet/$expand?url=http://snomed.info/sct?fhir_vs=isa/73211009</referenceSetUri>
```

### With text filter (typeahead/autocomplete)

```bash theme={null}
curl "https://fhir.omophub.com/fhir/r4/ValueSet/\$expand?\
url=http://snomed.info/sct?fhir_vs&filter=diabet&count=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Parameters

| Parameter | Type    | Required | Description                                                                                                     |
| --------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| `url`     | uri     | Yes      | Implicit ValueSet URL (e.g., `http://snomed.info/sct?fhir_vs` or `http://snomed.info/sct?fhir_vs=isa/73211009`) |
| `filter`  | string  | No       | Text filter to match against concept display names                                                              |
| `offset`  | integer | No       | Paging start position (default: 0)                                                                              |
| `count`   | integer | No       | Page size (default: 100, max: 1000)                                                                             |

## Response

```json theme={null}
{
  "resourceType": "ValueSet",
  "status": "active",
  "expansion": {
    "identifier": "urn:uuid:a1b2c3d4-...",
    "timestamp": "2026-04-12T10:00:00Z",
    "total": 247,
    "offset": 0,
    "parameter": [
      { "name": "offset", "valueInteger": 0 },
      { "name": "count", "valueInteger": 20 }
    ],
    "contains": [
      {
        "system": "http://snomed.info/sct",
        "code": "44054006",
        "display": "Type 2 diabetes mellitus"
      },
      {
        "system": "http://snomed.info/sct",
        "code": "46635009",
        "display": "Type 1 diabetes mellitus"
      }
    ]
  }
}
```

## Pagination

Use `offset` and `count` to page through large expansions. The response includes `total` for the total number of matching concepts.

```bash theme={null}
# Page 2 (items 20-39)
curl "https://fhir.omophub.com/fhir/r4/ValueSet/\$expand?\
url=http://snomed.info/sct?fhir_vs=isa/73211009&offset=20&count=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

<Note>
  **Deterministic sort order.** Concepts are sorted by OMOP `concept_id` so successive calls return the same first-page results and paginate consistently. FHIR clients that cache one expansion per ValueSet (EHRbase's composition validator, HAPI FHIR's `RemoteTerminologyServiceValidationSupport`) can rely on this - a code observed in page 0 of one call will still be in page 0 of the next call.
</Note>

<Note>
  **Double percent-encoding tolerance.** Spring-based clients (HAPI FHIR, EHRbase via `UriComponentsBuilder`) sometimes percent-encode the `url` parameter twice - once for the template `referenceSetUri` and again when building the outbound HTTP request. `$expand` detects the second encoding layer automatically and decodes it before parsing the implicit ValueSet URL, so both single- and double-encoded forms work. Malformed percent-encoding falls back to a clean 400 `OperationOutcome` instead of a 500.
</Note>

## Errors

| HTTP | Issue Code | Cause                                                                            |
| ---- | ---------- | -------------------------------------------------------------------------------- |
| 400  | `invalid`  | Missing `url` parameter, invalid ValueSet URL format, or unknown code system URI |
