

# Searching FHIR resources in AWS HealthLake
<a name="searching-fhir-resources"></a>

Use FHIR [https://hl7.org/fhir/R4/http.html#search](https://hl7.org/fhir/R4/http.html#search) interaction to search a set of FHIR resources in a HealthLake data store based on some filter criteria. The `search` interaction can be performed using either a `GET` or `POST` request. For searches that involve personally identifiable information (PII) or protected health information (PHI), it's recommended to use `POST` requests, as PII and PHI is added as part of the request body and is encrypted in transit.

**Note**  
The FHIR `search` interaction described in this chapter is built in conformance to the HL7 FHIR R4 standard for health care data exchange. Because it is a representation of a HL7 FHIR service, it is not offered through AWS CLI and AWS SDKs. For more information, see [https://hl7.org/fhir/R4/http.html#search](https://hl7.org/fhir/R4/http.html#search) in the **FHIR R4 RESTful API documentation**.

HealthLake supports a subset of FHIR R4 search parameters. For more information, see [FHIR R4 search parameters for HealthLake](reference-fhir-search-parameters.md).

**Topics**
+ [Searching with GET](searching-fhir-resources-get.md)
+ [Searching with POST](searching-fhir-resources-post.md)
+ [Search Consistency Levels](searching-fhir-consistency-levels.md)

# Searching FHIR resources with GET
<a name="searching-fhir-resources-get"></a>

You can use `GET` requests to search a HealthLake data store. When using `GET`, HealthLake supports providing search parameters as part of the URL, but not as part of a request body. For more information, see [FHIR R4 search parameters for HealthLake](reference-fhir-search-parameters.md).

**Important**  
For searches that involve personally identifiable information (PII) or protected health information (PHI), security best practices call for using `POST` requests, as PII and PHI is added as part of the request body and is encrypted in transit. For more information, see [Searching FHIR resources with POST](searching-fhir-resources-post.md).

The following procedure is followed by examples that use `GET` to search a HealthLake data store.

**To search a HealthLake data store with `GET`**  


1. Collect HealthLake `region` and `datastoreId` values. For more information, see [Getting data store properties](managing-data-stores-describe.md).

1. Determine the type of FHIR resource to search for and collect the associated `id` value. For more information, see [Resource types](reference-fhir-resource-types.md). 

1. Construct a URL for the request using the collected values for HealthLake `region` and `datastoreId`. Also include the FHIR `Resource` type and supported [search parameters](reference-fhir-search-parameters.md). To view the entire URL path in the following example, scroll over the **Copy** button.

   ```
   GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Resource{?[parameters]{&_format=[mime-type]}}
   ```

1. Send the `GET` request with either [AWS Signature Version 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) or SMART on FHIR authorization. The following `curl` example returns the total number of `Patient` resources in a HealthLake data store. To view the entire example, scroll over the **Copy** button.

------
#### [ SigV4 ]

   SigV4 authorization

   ```
   curl --request GET \
     'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Patient?_total=accurate' \   
     --aws-sigv4 'aws:amz:region:healthlake' \
     --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
     --header "x-amz-security-token:$AWS_SESSION_TOKEN" \                          
     --header 'Accept: application/json'
   ```

------
#### [ SMART on FHIR ]

   SMART on FHIR authorization example for the [https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html) data type.

   ```
   {
       "AuthorizationStrategy": "SMART_ON_FHIR",
       "FineGrainedAuthorizationEnabled": true,
       "IdpLambdaArn": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name",
       "Metadata": "{\"issuer\":\"https://ehr.example.com\", \"jwks_uri\":\"https://ehr.example.com/.well-known/jwks.json\",\"authorization_endpoint\":\"https://ehr.example.com/auth/authorize\",\"token_endpoint\":\"https://ehr.token.com/auth/token\",\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"foo\"],\"grant_types_supported\":[\"client_credential\",\"foo\"],\"registration_endpoint\":\"https://ehr.example.com/auth/register\",\"scopes_supported\":[\"openId\",\"profile\",\"launch\"],\"response_types_supported\":[\"code\"],\"management_endpoint\":\"https://ehr.example.com/user/manage\",\"introspection_endpoint\":\"https://ehr.example.com/user/introspect\",\"revocation_endpoint\":\"https://ehr.example.com/user/revoke\",\"code_challenge_methods_supported\":[\"S256\"],\"capabilities\":[\"launch-ehr\",\"sso-openid-connect\",\"client-public\",\"permission-v2\"]}"
   }
   ```

   The caller can assign permissions in the authorization lambda. For more information, see [OAuth 2.0 scopes](reference-smart-on-fhir-oauth-scopes.md).

------
#### [ AWS Console ]

**Note**  
The HealthLake Console supports only SigV4 authorization. SMART on FHIR authorization is supported through AWS CLI and AWS SDKs.

   1. Sign in to the [Run query](https://console.aws.amazon.com/healthlake/home#/crud) page on the HealthLake Console.

   2. Under the **Query settings** section, make the following selections.
   + **Data Store ID** — choose a data store ID to generate a query string.
   + **Query type** — choose `Search with GET`.
   + **Resource type** — choose the FHIR [resource type](reference-fhir-resource-types.md) to search on.
   + **Search parameters** — Select a [search parameter](reference-fhir-search-parameters.md) or combination of search parameters to focus your query on specific records.

   3. Choose **Run query**.

------

## Examples: search with GET
<a name="searching-fhir-resources-get-examples"></a>

The following tabs provide examples for searching on specific FHIR resource types with `GET`. The examples show how to specify search parameters in the request URLs.

**Note**  
The HealthLake Console supports only SigV4 authorization. SMART on FHIR authorization is supported through AWS CLI and AWS SDKs.  
HealthLake supports a subset of FHIR R4 search parameters. For more information, see [Search parameters](reference-fhir-search-parameters.md).

------
#### [ Patient (age) ]

Although age is not a defined resource type in FHIR, it is captured as an element in the [https://hl7.org/fhir/R4/patient.html](https://hl7.org/fhir/R4/patient.html) resource type. Use the following example to make a `GET`-based search request on [https://hl7.org/fhir/R4/patient.html](https://hl7.org/fhir/R4/patient.html) resource types using the [birthDate](https://hl7.org/fhir/R4/patient-definitions.html#Patient.birthDate) element and the `eq` [search comparator](reference-fhir-search-parameters.md#search-comparators) to search for individuals born in the year 1997.

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Patient?birthdate=eq1997
```

------
#### [ Condition ]

Use the following example to make a `GET` request on the [https://hl7.org/fhir/R4/condition.html](https://hl7.org/fhir/R4/condition.html) resource type. The search finds conditions in your HealthLake data store that contain the SNOMED medical code `72892002`, which translates to `Normal pregnancy`.

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Condition?code=72892002
```

------
#### [ DocumentationReference ]

The following example shows how to create a `GET` request on the [https://hl7.org/fhir/R4/documentreference.html](https://hl7.org/fhir/R4/documentreference.html) resource type for `Patient`(s) with a streptococcal diagnosis and who have also been prescribed amoxicillin.

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/DocumentReference?_lastUpdated=le2021-12-19&infer-icd10cm-entity-text-concept-score;=streptococcal|0.6&infer-rxnorm-entity-text-concept-score=Amoxicillin|0.8
```

------
#### [ Location ]

Use the following example to make a `GET` request on the [https://hl7.org/fhir/R4/location.html](https://hl7.org/fhir/R4/location.html) resource type. The following search finds locations in your HealthLake data store that contain the city name Boston as part of the address.

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Location?address=boston
```

------
#### [ Observation ]

Use the following example to make a `GET`-based search request on the [https://hl7.org/fhir/R4/observation.html](https://hl7.org/fhir/R4/observation.html) resource type. This search uses the `value-concept` [search parameter](reference-fhir-search-parameters.md) to look for medical code `266919005`, which translates to `Never smoker`.

```
GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Observation?value-concept=266919005
```

------

# Searching FHIR resources with POST
<a name="searching-fhir-resources-post"></a>

You can use the FHIR [https://hl7.org/fhir/R4/search.html](https://hl7.org/fhir/R4/search.html) interaction with `POST` requests to search a HealthLake data store. When using `POST`, HealthLake supports search parameters in either the URL or in a request body, but you cannot use both in a single request.

**Important**  
For searches that involve personally identifiable information (PII) or protected health information (PHI), security best practices call for using `POST` requests, as PII and PHI is added as part of the request body and is encrypted in transit.

The following procedure is followed by examples using FHIR R4 `search` interaction with `POST` to search a HealthLake data store. The examples show how to specify search parameters in the JSON request body.

**To search a HealthLake data store with `POST`**  


1. Collect HealthLake `region` and `datastoreId` values. For more information, see [Getting data store properties](managing-data-stores-describe.md).

1. Determine the type of FHIR resource to search for and collect the associated `id` value. For more information, see [Resource types](reference-fhir-resource-types.md). 

1. Construct a URL for the request using the collected values for HealthLake `region` and `datastoreId`. Also include the FHIR `Resource` type and `_search` interaction. To view the entire URL path in the following example, scroll over the **Copy** button.

   ```
   POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Resource/_search
   ```

1. Construct a JSON body for the request, specifying the FHIR data to search for. For the purpose of this procedure, you will search `Observation` resources to discover patients who have never smoked. To specify the medical code status `Never smoker`, set `value-concept=266919005` in the JSON request body. Save the file as `search-observation.json`.

   ```
   value-concept=266919005
   ```

1. Send the request. The FHIR `search` interaction uses the `GET` request with either [AWS Signature Version 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) or SMART on FHIR authorization.
**Note**  
When making a `POST` request with search parameters in the request body, use `Content-Type: application/x-www-form-urlencoded` as part of the header.

   The following `curl` example makes a POST-based search request on the `Observation` resource type. The request uses the [https://hl7.org/fhir/R4/observation.html#search](https://hl7.org/fhir/R4/observation.html#search) search parameter to look for medical code `266919005` which indicates value `Never smoker`. To view the entire example, scroll over the **Copy** button.

------
#### [ SigV4 ]

   SigV4 authorization

   ```
   curl --request POST \
     'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Observation/_search' \						
     --aws-sigv4 'aws:amz:region:healthlake' \
     --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
     --header "x-amz-security-token:$AWS_SESSION_TOKEN" \
     --header "Content-Type: application/x-www-form-urlencoded"							
     --header "Accept: application/json"
     --data @search-observation.json
   ```

------
#### [ SMART on FHIR ]

   SMART on FHIR authorization example for the [https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html) data type.

   ```
   {
       "AuthorizationStrategy": "SMART_ON_FHIR",
       "FineGrainedAuthorizationEnabled": true,
       "IdpLambdaArn": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name",
       "Metadata": "{\"issuer\":\"https://ehr.example.com\", \"jwks_uri\":\"https://ehr.example.com/.well-known/jwks.json\",\"authorization_endpoint\":\"https://ehr.example.com/auth/authorize\",\"token_endpoint\":\"https://ehr.token.com/auth/token\",\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"foo\"],\"grant_types_supported\":[\"client_credential\",\"foo\"],\"registration_endpoint\":\"https://ehr.example.com/auth/register\",\"scopes_supported\":[\"openId\",\"profile\",\"launch\"],\"response_types_supported\":[\"code\"],\"management_endpoint\":\"https://ehr.example.com/user/manage\",\"introspection_endpoint\":\"https://ehr.example.com/user/introspect\",\"revocation_endpoint\":\"https://ehr.example.com/user/revoke\",\"code_challenge_methods_supported\":[\"S256\"],\"capabilities\":[\"launch-ehr\",\"sso-openid-connect\",\"client-public\",\"permission-v2\"]}"
   }
   ```

   The caller can assign permissions in the authorization lambda. For more information, see [OAuth 2.0 scopes](reference-smart-on-fhir-oauth-scopes.md).

------

## Examples: search with POST
<a name="searching-fhir-resources-post-examples"></a>

The following tabs provide examples for searching on specific FHIR resource types with `POST`. The examples show how to specify a request in the URLs.

**Note**  
The HealthLake Console supports only SigV4 authorization. SMART on FHIR authorization is supported through AWS CLI and AWS SDKs.  
HealthLake supports a subset of FHIR R4 search parameters. For more information, see [Search parameters](reference-fhir-search-parameters.md).

------
#### [ Patient (age) ]

Although age is not a defined resource type in FHIR, it is captured as an element in the [https://hl7.org/fhir/R4/patient.html](https://hl7.org/fhir/R4/patient.html) resource type. Use the following example to make a `POST`-based search request on the `Patient` resource type. The following search example uses the `eq` [search comparator](reference-fhir-search-parameters.md#search-comparators) to search for individuals born in 1997.

```
POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Patient/_search
```

To specify the year 1997 in the search, add the following element to the request body.

```
birthdate=eq1997
```

------
#### [ Condition ]

Using the following to make a `POST` request on the `Condition` resource type. This search finds locations in your HealthLake data store that contain the medical code `72892002`.

You have to specify a request URL and a request body. Here is an example request URL.

```
POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Condition/_search
```

To specify the medical code you want to search, you add the following JSON element to the request body.

```
code=72892002
```

------
#### [ DocumentReference ]

To see the results of HealthLake's integrated natural language processing (NLP) when making a `POST` request on the `DocumentReference` resource type, format a request as follows.

```
POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/DocumentReference/_search
```

To specify the `DocumentReference` search parameters to reference, see [Search parameter types](reference-fhir-search-parameters.md#search-parameter-types). The following query string uses multiple search parameters to search on Amazon Comprehend Medical API operations used to generate the integrated NLP results.

```
_lastUpdated=le2021-12-19&infer-icd10cm-entity-text-concept-score;=streptococcal|0.6&infer-rxnorm-entity-text-concept-score=Amoxicillin|0.8
```

------
#### [ Location ]

Use the following example to make a `POST` request on the `Location` resource type. The search finds locations in your HealthLake data store that contain the city name Boston as part of the address.

You must specify a request URL and a request body. Here is an example request URL.

```
POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Location/_search
```

To specify `Boston` in the search, add the following element to the request body:

```
address=Boston
```

------
#### [ Observation ]

Use the following example to make a `POST`-based search request on the `Observation` resource type. The search uses the `value-concept` search parameter to look for medical code, `266919005` that indicates `Never smoker`.

```
POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Observation/_search
```

To specify the status, `Never smoker` , set `value-concept=266919005` in the body of the JSON.

```
value-concept=266919005
```

------

# FHIR Search Consistency Levels
<a name="searching-fhir-consistency-levels"></a>

AWS HealthLake's search index operates on an Eventual Consistency model for `GET` and `POST` with SEARCH operations. With eventual consistency, if there is a pending search index update for a resource, the search results exclude version N-1 of the resource until the index update completes.

 AWS HealthLake now includes the ability to select how the consistency model will behave for updated resources. Developers can include either 'Eventual Consistency', the default behavior described above or 'Strong Consistency'. Strong Consistency will allow the N-1 version of the resource for resources with pending search index updates to be included in the search results. This can be used for use case scenarios where all resources are required in the result even when the search index update has not yet completed. Customers can control this behavior using the `x-amz-fhir-history-consistency-level` request header. 

## Consistency levels
<a name="fhir-search-consistency-levels"></a>

Strong consistency  
Set `x-amz-fhir-history-consistency-level: strong` to return all matching records, including those with pending search index updates. Use this option when you need to search for resources immediately after updates.

Eventual consistency  
Set `x-amz-fhir-history-consistency-level: eventual` to return only records that have completed search index updates. This is the default behavior if no consistency level is specified.

## Usage example
<a name="fhir-search-usage"></a>

1. When updating a resource:

   ```
   POST <baseURL>/Patient
   Content-Type: application/fhir+json
   x-amz-fhir-history-consistency-level: strong
   
   {
     "resourceType": "Patient",
     "id": "123",
     "meta": {
       "profile": ["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"]
     },
     "identifier": [
       {
         "system": "http://example.org/identifiers",
         "value": "123"
       }
     ],
     "active": true,
     "name": [
       {
         "family": "Smith",
         "given": ["John"]
       }
     ],
     "gender": "male",
     "birthDate": "1970-01-01"
   }
   ```

1. Subsequent search:

   ```
   GET <baseURL>/Patient?_id=123
   ```

## Best practices
<a name="fhir-search-best-practices"></a>
+ Use strong consistency when you need to immediately search for recently updated resources
+ Use eventual consistency for general queries where immediate visibility isn't critical
+ Consider the trade-off between immediate visibility and potential performance impact

**Note**  
The consistency level setting affects how quickly updated resources appear in search results but does not impact the actual storage of the resources.  
Setting the optional `x-amz-fhir-history-consistency-level` header to 'strong' doubles the write capacity consumption per resource.  
This feature is only applicable for data stores that have version history enabled (all datastores created after Oct 25, 2024 have it enabled by default).