├── .gitignore ├── LICENSE ├── README.md ├── _gencontinuous.bat ├── _gencontinuous.sh ├── _genonce.bat ├── _genonce.sh ├── _updatePublisher.bat ├── _updatePublisher.sh ├── ig.ini ├── input ├── fsh │ ├── aliases.fsh │ ├── codesystems │ │ └── IncludeAssociatedDataCodeSystem.fsh │ ├── extensions │ │ └── OperationNotSupported.fsh │ ├── instances │ │ ├── bulk-data.fsh │ │ ├── export.fsh │ │ ├── group-export.fsh │ │ └── patient-export.fsh │ ├── profiles │ │ └── group.fsh │ └── valuesets │ │ └── IncludeAssociatedDataValueSet.fsh ├── ignoreWarnings.txt ├── images-source │ ├── bulk-flow.plantuml │ └── processing-model.plantuml ├── images │ └── security-risk-assessment-report.pdf └── pagecontent │ ├── abbreviations.md │ ├── authorization.md │ ├── changes.md │ ├── downloads.xml │ ├── export.md │ ├── group.md │ └── index.md ├── package-list.json ├── smart-template ├── content │ └── assets │ │ └── images │ │ └── smart-logo.png ├── includes │ ├── _append.fragment-header.html │ └── fragment-pageend.html └── package │ └── package.json └── sushi-config.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | /fsh-generated 4 | /input-cache 5 | /output 6 | /temp 7 | /template 8 | FHIR-bulkdata.xml 9 | .index.db 10 | .index.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, HL7 2 | 3 | This document is licensed under the terms of HL7's FHIR license. 4 | http://hl7.org/fhir/license.html 5 | 6 | Creative Commons "No Rights Reserved" (CC0) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FHIR Bulk Data Access Implementation Guide 2 | 3 | The FHIR Bulk Data Access Implementation Guide defines a standardized, FHIR based approach for exporting bulk data from a FHIR server to a pre-authorized client. 4 | 5 | ### View 6 | 7 | * Official Publication: https://hl7.org/fhir/uv/bulkdata/ 8 | * CI Build: https://build.fhir.org/ig/HL7/bulk-data/ 9 | 10 | ### Build 11 | 12 | To build this Implementation Guide, please see the [IG Publisher documentation](https://confluence.hl7.org/pages/viewpage.action?pageId=175618322) 13 | 14 | ### Contribute 15 | 16 | If you have suggestions or need to discuss potential substantive changes, please: 17 | * Join the conversation in [`#bulk-data` on chat.fhir.org](https://chat.fhir.org/#narrow/stream/179250-bulk-data) 18 | * Submit change requests or issues through the [HL7 JIRA](https://jira.hl7.org/) 19 | 20 | -------------------------------------------------------------------------------- /_gencontinuous.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | CALL ./_genonce.bat -watch -------------------------------------------------------------------------------- /_gencontinuous.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./_genonce.sh -watch 3 | -------------------------------------------------------------------------------- /_genonce.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | SET publisher_jar=publisher.jar 3 | SET input_cache_path=%CD%\input-cache 4 | 5 | ECHO Checking internet connection... 6 | PING tx.fhir.org -4 -n 1 -w 1000 | FINDSTR TTL && GOTO isonline 7 | ECHO We're offline... 8 | SET txoption=-tx n/a 9 | GOTO igpublish 10 | 11 | :isonline 12 | ECHO We're online 13 | SET txoption= 14 | 15 | :igpublish 16 | 17 | SET JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 18 | 19 | IF EXIST "%input_cache_path%\%publisher_jar%" ( 20 | JAVA -jar "%input_cache_path%\%publisher_jar%" -ig . %txoption% %* 21 | ) ELSE If exist "..\%publisher_jar%" ( 22 | JAVA -jar "..\%publisher_jar%" -ig . %txoption% %* 23 | ) ELSE ( 24 | ECHO IG Publisher NOT FOUND in input-cache or parent folder. Please run _updatePublisher. Aborting... 25 | ) 26 | 27 | PAUSE 28 | -------------------------------------------------------------------------------- /_genonce.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | publisher_jar=publisher.jar 3 | input_cache_path=./input-cache/ 4 | echo Checking internet connection... 5 | curl -sSf tx.fhir.org > /dev/null 6 | 7 | if [ $? -eq 0 ]; then 8 | echo "Online" 9 | txoption="" 10 | else 11 | echo "Offline" 12 | txoption="-tx n/a" 13 | fi 14 | 15 | echo "$txoption" 16 | 17 | export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Dfile.encoding=UTF-8" 18 | 19 | publisher=$input_cache_path/$publisher_jar 20 | if test -f "$publisher"; then 21 | java -jar $publisher -ig . $txoption $* 22 | 23 | else 24 | publisher=../$publisher_jar 25 | if test -f "$publisher"; then 26 | java -jar $publisher -ig . $txoption $* 27 | else 28 | echo IG Publisher NOT FOUND in input-cache or parent folder. Please run _updatePublisher. Aborting... 29 | fi 30 | fi 31 | -------------------------------------------------------------------------------- /_updatePublisher.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SETLOCAL 4 | 5 | SET dlurl=https://github.com/HL7/fhir-ig-publisher/releases/latest/download/publisher.jar 6 | SET publisher_jar=publisher.jar 7 | SET input_cache_path=%CD%\input-cache\ 8 | SET skipPrompts=false 9 | 10 | SET scriptdlroot=https://raw.githubusercontent.com/HL7/ig-publisher-scripts/main 11 | SET update_bat_url=%scriptdlroot%/_updatePublisher.bat 12 | SET gen_bat_url=%scriptdlroot%/_genonce.bat 13 | SET gencont_bat_url=%scriptdlroot%/_gencontinuous.bat 14 | SET gencont_sh_url=%scriptdlroot%/_gencontinuous.sh 15 | SET gen_sh_url=%scriptdlroot%/_genonce.sh 16 | SET update_sh_url=%scriptdlroot%/_updatePublisher.sh 17 | 18 | IF "%~1"=="/f" SET skipPrompts=y 19 | 20 | 21 | ECHO. 22 | ECHO Checking internet connection... 23 | PING tx.fhir.org -4 -n 1 -w 1000 | FINDSTR TTL && GOTO isonline 24 | ECHO We're offline, nothing to do... 25 | GOTO end 26 | 27 | :isonline 28 | ECHO We're online 29 | 30 | 31 | :processflags 32 | SET ARG=%1 33 | IF DEFINED ARG ( 34 | IF "%ARG%"=="-f" SET FORCE=true 35 | IF "%ARG%"=="--force" SET FORCE=true 36 | SHIFT 37 | GOTO processflags 38 | ) 39 | 40 | FOR %%x IN ("%CD%") DO SET upper_path=%%~dpx 41 | 42 | ECHO. 43 | IF NOT EXIST "%input_cache_path%%publisher_jar%" ( 44 | IF NOT EXIST "%upper_path%%publisher_jar%" ( 45 | SET jarlocation="%input_cache_path%%publisher_jar%" 46 | SET jarlocationname=Input Cache 47 | ECHO IG Publisher is not yet in input-cache or parent folder. 48 | REM we don't use jarlocation below because it will be empty because we're in a bracketed if statement 49 | GOTO create 50 | ) ELSE ( 51 | ECHO IG Publisher FOUND in parent folder 52 | SET jarlocation="%upper_path%%publisher_jar%" 53 | SET jarlocationname=Parent folder 54 | GOTO upgrade 55 | ) 56 | ) ELSE ( 57 | ECHO IG Publisher FOUND in input-cache 58 | SET jarlocation="%input_cache_path%%publisher_jar%" 59 | SET jarlocationname=Input Cache 60 | GOTO upgrade 61 | ) 62 | 63 | :create 64 | IF DEFINED FORCE ( 65 | MKDIR "%input_cache_path%" 2> NUL 66 | GOTO download 67 | ) 68 | 69 | IF "%skipPrompts%"=="y" ( 70 | SET create=Y 71 | ) ELSE ( 72 | SET /p create="Ok? (Y/N) " 73 | ) 74 | IF /I "%create%"=="Y" ( 75 | ECHO Will place publisher jar here: %input_cache_path%%publisher_jar% 76 | MKDIR "%input_cache_path%" 2> NUL 77 | GOTO download 78 | ) 79 | GOTO done 80 | 81 | :upgrade 82 | IF "%skipPrompts%"=="y" ( 83 | SET overwrite=Y 84 | ) ELSE ( 85 | SET /p overwrite="Overwrite %jarlocation%? (Y/N) " 86 | ) 87 | 88 | IF /I "%overwrite%"=="Y" ( 89 | GOTO download 90 | ) 91 | GOTO done 92 | 93 | :download 94 | ECHO Downloading most recent publisher to %jarlocationname% - it's ~100 MB, so this may take a bit 95 | 96 | FOR /f "tokens=4-5 delims=. " %%i IN ('ver') DO SET VERSION=%%i.%%j 97 | IF "%version%" == "10.0" GOTO win10 98 | IF "%version%" == "6.3" GOTO win8.1 99 | IF "%version%" == "6.2" GOTO win8 100 | IF "%version%" == "6.1" GOTO win7 101 | IF "%version%" == "6.0" GOTO vista 102 | 103 | ECHO Unrecognized version: %version% 104 | GOTO done 105 | 106 | :win10 107 | CALL POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%dlurl%\",\"%jarlocation%\") } else { Invoke-WebRequest -Uri "%dlurl%" -Outfile "%jarlocation%" } 108 | 109 | GOTO done 110 | 111 | :win7 112 | rem this may be triggering the antivirus - bitsadmin.exe is a known threat 113 | rem CALL bitsadmin /transfer GetPublisher /download /priority normal "%dlurl%" "%jarlocation%" 114 | 115 | rem this didn't work in win 10 116 | rem CALL Start-BitsTransfer /priority normal "%dlurl%" "%jarlocation%" 117 | 118 | rem this should work - untested 119 | call (New-Object Net.WebClient).DownloadFile('%dlurl%', '%jarlocation%') 120 | GOTO done 121 | 122 | :win8.1 123 | :win8 124 | :vista 125 | GOTO done 126 | 127 | 128 | 129 | :done 130 | 131 | 132 | 133 | 134 | ECHO. 135 | ECHO Updating scripts 136 | IF "%skipPrompts%"=="y" ( 137 | SET updateScripts=Y 138 | ) ELSE ( 139 | SET /p updateScripts="Update scripts? (Y/N) " 140 | ) 141 | IF /I "%updateScripts%"=="Y" ( 142 | GOTO scripts 143 | ) 144 | GOTO end 145 | 146 | 147 | :scripts 148 | 149 | REM Download all batch files (and this one with a new name) 150 | 151 | SETLOCAL DisableDelayedExpansion 152 | 153 | 154 | 155 | :dl_script_1 156 | ECHO Updating _updatePublisher.sh 157 | call POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%update_sh_url%\",\"_updatePublisher.new.sh\") } else { Invoke-WebRequest -Uri "%update_sh_url%" -Outfile "_updatePublisher.new.sh" } 158 | if %ERRORLEVEL% == 0 goto upd_script_1 159 | echo "Errors encountered during download: %errorlevel%" 160 | goto dl_script_2 161 | :upd_script_1 162 | start copy /y "_updatePublisher.new.sh" "_updatePublisher.sh" ^&^& del "_updatePublisher.new.sh" ^&^& exit 163 | 164 | 165 | :dl_script_2 166 | ECHO Updating _genonce.bat 167 | call POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%gen_bat_url%\",\"_genonce.new.bat\") } else { Invoke-WebRequest -Uri "%gen_bat_url%" -Outfile "_genonce.bat" } 168 | if %ERRORLEVEL% == 0 goto upd_script_2 169 | echo "Errors encountered during download: %errorlevel%" 170 | goto dl_script_3 171 | :upd_script_2 172 | start copy /y "_genonce.new.bat" "_genonce.bat" ^&^& del "_genonce.new.bat" ^&^& exit 173 | 174 | :dl_script_3 175 | ECHO Updating _gencontinuous.bat 176 | call POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%gencont_bat_url%\",\"_gencontinuous.new.bat\") } else { Invoke-WebRequest -Uri "%gencont_bat_url%" -Outfile "_gencontinuous.bat" } 177 | if %ERRORLEVEL% == 0 goto upd_script_3 178 | echo "Errors encountered during download: %errorlevel%" 179 | goto dl_script_4 180 | :upd_script_3 181 | start copy /y "_gencontinuous.new.bat" "_gencontinuous.bat" ^&^& del "_gencontinuous.new.bat" ^&^& exit 182 | 183 | 184 | :dl_script_4 185 | ECHO Updating _genonce.sh 186 | call POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%gen_sh_url%\",\"_genonce.new.sh\") } else { Invoke-WebRequest -Uri "%gen_sh_url%" -Outfile "_genonce.sh" } 187 | if %ERRORLEVEL% == 0 goto upd_script_4 188 | echo "Errors encountered during download: %errorlevel%" 189 | goto dl_script_5 190 | :upd_script_4 191 | start copy /y "_genonce.new.sh" "_genonce.sh" ^&^& del "_genonce.new.sh" ^&^& exit 192 | 193 | :dl_script_5 194 | ECHO Updating _gencontinuous.sh 195 | call POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%gencont_sh_url%\",\"_gencontinuous.new.sh\") } else { Invoke-WebRequest -Uri "%gencont_sh_url%" -Outfile "_gencontinuous.sh" } 196 | if %ERRORLEVEL% == 0 goto upd_script_5 197 | echo "Errors encountered during download: %errorlevel%" 198 | goto dl_script_6 199 | :upd_script_5 200 | start copy /y "_gencontinuous.new.sh" "_gencontinuous.sh" ^&^& del "_gencontinuous.new.sh" ^&^& exit 201 | 202 | 203 | 204 | :dl_script_6 205 | ECHO Updating _updatePublisher.bat 206 | call POWERSHELL -command if ('System.Net.WebClient' -as [type]) {(new-object System.Net.WebClient).DownloadFile(\"%update_bat_url%\",\"_updatePublisher.new.bat\") } else { Invoke-WebRequest -Uri "%update_bat_url%" -Outfile "_updatePublisher.new.bat" } 207 | if %ERRORLEVEL% == 0 goto upd_script_6 208 | echo "Errors encountered during download: %errorlevel%" 209 | goto end 210 | :upd_script_6 211 | start copy /y "_updatePublisher.new.bat" "_updatePublisher.bat" ^&^& del "_updatePublisher.new.bat" ^&^& exit 212 | 213 | 214 | :end 215 | 216 | 217 | IF "%skipPrompts%"=="true" ( 218 | PAUSE 219 | ) 220 | -------------------------------------------------------------------------------- /_updatePublisher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pubsource=https://github.com/HL7/fhir-ig-publisher/releases/latest/download/ 3 | publisher_jar=publisher.jar 4 | dlurl=$pubsource$publisher_jar 5 | 6 | input_cache_path=$PWD/input-cache/ 7 | 8 | scriptdlroot=https://raw.githubusercontent.com/HL7/ig-publisher-scripts/main 9 | update_bat_url=$scriptdlroot/_updatePublisher.bat 10 | gen_bat_url=$scriptdlroot/_genonce.bat 11 | gencont_bat_url=$scriptdlroot/_gencontinuous.bat 12 | gencont_sh_url=$scriptdlroot/_gencontinuous.sh 13 | gen_sh_url=$scriptdlroot/_genonce.sh 14 | update_sh_url=$scriptdlroot/_updatePublisher.sh 15 | 16 | skipPrompts=false 17 | FORCE=false 18 | 19 | if ! type "curl" > /dev/null; then 20 | echo "ERROR: Script needs curl to download latest IG Publisher. Please install curl." 21 | exit 1 22 | fi 23 | 24 | while [ "$#" -gt 0 ]; do 25 | case $1 in 26 | -f|--force) FORCE=true ;; 27 | -y|--yes) skipPrompts=true ; FORCE=true ;; 28 | *) echo "Unknown parameter passed: $1. Exiting"; exit 1 ;; 29 | esac 30 | shift 31 | done 32 | 33 | echo "Checking internet connection" 34 | curl -sSf tx.fhir.org > /dev/null 35 | 36 | if [ $? -ne 0 ] ; then 37 | echo "Offline (or the terminology server is down), unable to update. Exiting" 38 | exit 1 39 | fi 40 | 41 | if [ ! -d "$input_cache_path" ] ; then 42 | if [ $FORCE != true ]; then 43 | echo "$input_cache_path does not exist" 44 | message="create it?" 45 | read -r -p "$message" response 46 | else 47 | response=y 48 | fi 49 | fi 50 | 51 | if [[ $response =~ ^[yY].*$ ]] ; then 52 | mkdir ./input-cache 53 | fi 54 | 55 | publisher="$input_cache_path$publisher_jar" 56 | 57 | if test -f "$publisher" ; then 58 | echo "IG Publisher FOUND in input-cache" 59 | jarlocation="$publisher" 60 | jarlocationname="Input Cache" 61 | upgrade=true 62 | else 63 | publisher="../$publisher_jar" 64 | upgrade=true 65 | if test -f "$publisher"; then 66 | echo "IG Publisher FOUND in parent folder" 67 | jarlocation="$publisher" 68 | jarlocationname="Parent Folder" 69 | upgrade=true 70 | else 71 | echo "IG Publisher NOT FOUND in input-cache or parent folder" 72 | jarlocation=$input_cache_path$publisher_jar 73 | jarlocationname="Input Cache" 74 | upgrade=false 75 | fi 76 | fi 77 | 78 | if [[ $skipPrompts == false ]]; then 79 | 80 | if [[ $upgrade == true ]]; then 81 | message="Overwrite $jarlocation? (Y/N) " 82 | else 83 | echo Will place publisher jar here: "$jarlocation" 84 | message="Ok (enter 'y' or 'Y' to continue, any other key to cancel)?" 85 | fi 86 | read -r -p "$message" response 87 | else 88 | response=y 89 | fi 90 | if [[ $skipPrompts == true ]] || [[ $response =~ ^[yY].*$ ]]; then 91 | 92 | echo "Downloading most recent publisher to $jarlocationname - it's ~100 MB, so this may take a bit" 93 | curl -L $dlurl -o "$jarlocation" --create-dirs 94 | else 95 | echo cancelled publisher update 96 | fi 97 | 98 | if [[ $skipPrompts != true ]]; then 99 | message="Update scripts? (enter 'y' or 'Y' to continue, any other key to cancel)?" 100 | read -r -p "$message" response 101 | fi 102 | 103 | if [[ $skipPrompts == true ]] || [[ $response =~ ^[yY].*$ ]]; then 104 | echo "Downloading most recent scripts " 105 | 106 | curl -L $update_bat_url -o /tmp/_updatePublisher.new 107 | cp /tmp/_updatePublisher.new _updatePublisher.bat 108 | rm /tmp/_updatePublisher.new 109 | 110 | curl -L $gen_bat_url -o /tmp/_genonce.new 111 | cp /tmp/_genonce.new _genonce.bat 112 | rm /tmp/_genonce.new 113 | 114 | curl -L $gencont_bat_url -o /tmp/_gencontinuous.new 115 | cp /tmp/_gencontinuous.new _gencontinuous.bat 116 | rm /tmp/_gencontinuous.new 117 | 118 | curl -L $gencont_sh_url -o /tmp/_gencontinuous.new 119 | cp /tmp/_gencontinuous.new _gencontinuous.sh 120 | chmod +x _gencontinuous.sh 121 | rm /tmp/_gencontinuous.new 122 | 123 | curl -L $gen_sh_url -o /tmp/_genonce.new 124 | cp /tmp/_genonce.new _genonce.sh 125 | chmod +x _genonce.sh 126 | rm /tmp/_genonce.new 127 | 128 | curl -L $update_sh_url -o /tmp/_updatePublisher.new 129 | cp /tmp/_updatePublisher.new _updatePublisher.sh 130 | chmod +x _updatePublisher.sh 131 | rm /tmp/_updatePublisher.new 132 | fi 133 | -------------------------------------------------------------------------------- /ig.ini: -------------------------------------------------------------------------------- 1 | [IG] 2 | ig = fsh-generated/resources/ImplementationGuide-hl7.fhir.uv.bulkdata.json 3 | template = #smart-template -------------------------------------------------------------------------------- /input/fsh/aliases.fsh: -------------------------------------------------------------------------------- 1 | Alias: $m49.htm = http://unstats.un.org/unsd/methods/m49/m49.htm -------------------------------------------------------------------------------- /input/fsh/codesystems/IncludeAssociatedDataCodeSystem.fsh: -------------------------------------------------------------------------------- 1 | CodeSystem: IncludeAssociatedDataCodeSystem 2 | Id: include-associated-data 3 | Title: "Include Associated Data Code System" 4 | Description: "Metadata inclusion options for Bulk Data Access Export Operation includeAssociatedData parameter" 5 | * ^version = "2.0.0" 6 | * ^status = #active 7 | * ^date = "2021-07-29" 8 | * ^experimental = false 9 | * ^jurisdiction = $m49.htm#001 "World" 10 | * ^caseSensitive = true 11 | * ^valueSet = Canonical(IncludeAssociatedDataValueSet) 12 | * ^content = #complete 13 | * #LatestProvenanceResources "LatestProvenanceResources" "Export will include the most recent Provenance resources associated with each of the non-provenance resources being returned. Other Provenance resources will not be returned." 14 | * #RelevantProvenanceResources "RelevantProvenanceResources" "Export will include all Provenance resources associated with each of the non-provenance resources being returned." -------------------------------------------------------------------------------- /input/fsh/extensions/OperationNotSupported.fsh: -------------------------------------------------------------------------------- 1 | Extension: OperationNotSupported 2 | Id: operation-not-supported 3 | Title: "Operation Not Supported" 4 | Description: "Used to indicate that the parent resource type or search parameter is not supported for use in a bulk data export operation." 5 | Context: "CapabilityStatement.rest.resource | CapabilityStatement.rest.resource.searchParam" 6 | * value[x] only canonical 7 | * ^short = "Canonical URL for unsupported operation" -------------------------------------------------------------------------------- /input/fsh/instances/bulk-data.fsh: -------------------------------------------------------------------------------- 1 | Instance: bulk-data 2 | InstanceOf: CapabilityStatement 3 | Usage: #definition 4 | * url = "http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data" 5 | * version = "2.0.0" 6 | * name = "BulkDataIGCapabilityStatement" 7 | * title = "FHIR Bulk Data Access Implementation Guide" 8 | * status = #active 9 | * experimental = false 10 | * date = "2021-07-29" 11 | * description = "The expected capabilities of a Bulk Data Provider actor (e.g., EHR systems, data warehouses, and other clinical and administrative systems that aim to interoperate by sharing large FHIR datasets) which is responsible for providing responses to the queries submitted by a FHIR Bulk Data Client actor. Systems implementing this capability statement should meet the requirements set by the Bulk Data Access Implementation Guide. A FHIR Bulk Data Client has the option of choosing from this list to access necessary data based on use cases and other contextual requirements." 12 | * jurisdiction = $m49.htm#001 "World" 13 | * kind = #requirements 14 | * instantiates = "http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data" 15 | * fhirVersion = #4.0.1 16 | * format = #json 17 | * implementationGuide = "http://hl7.org/fhir/uv/bulkdata/ImplementationGuide/hl7.fhir.uv.bulkdata" 18 | * rest 19 | * mode = #server 20 | * documentation = "These FHIR Operations initiate the generation of data to which the client is authorized -- whether that be all patients, a subset (defined group) of patients, or all available data contained in a FHIR server.\n\nThe FHIR server SHALL limit the data returned to only those FHIR resources for which the client is authorized.\n\nThe FHIR server SHALL support invocation of this operation using the [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html). Servers SHALL support GET requests and MAY support POST requests that supply parameters using the FHIR [Parameters Resource](https://www.hl7.org/fhir/parameters.html)." 21 | * resource[0] 22 | * type = #Group 23 | * operation 24 | * extension 25 | * url = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation" 26 | * valueCode = #SHOULD 27 | * name = "export" 28 | * definition = "http://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export" 29 | * documentation = "FHIR Operation to obtain a detailed set of FHIR resources of diverse resource types pertaining to all patients in specified [Group](https://www.hl7.org/fhir/group.html).\n\nIf a FHIR server supports Group-level data export, it SHOULD support reading and searching for `Group` resource. This enables clients to discover available groups based on stable characteristics such as `Group.identifier`.\n\nThe [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html) SHOULD be used as a point of reference for recommended resources to be returned and, where applicable, Patient resources SHOULD be returned. Other resources outside of the patient compartment that are helpful in interpreting the patient data (such as Organization and Practitioner) MAY also be returned." 30 | * resource[+] 31 | * type = #Patient 32 | * operation 33 | * extension 34 | * url = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation" 35 | * valueCode = #SHOULD 36 | * name = "export" 37 | * definition = "http://hl7.org/fhir/uv/bulkdata/OperationDefinition/patient-export" 38 | * documentation = "FHIR Operation to obtain a detailed set of FHIR resources of diverse resource types pertaining to all patients.\n\nThe [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html) SHOULD be used as a point of reference for recommended resources to be returned and, where applicable, Patient resources SHOULD be returned. Other resources outside of the patient compartment that are helpful in interpreting the patient data (such as Organization and Practitioner) MAY also be returned." 39 | * operation 40 | * extension 41 | * url = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation" 42 | * valueCode = #SHOULD 43 | * name = "export" 44 | * definition = "http://hl7.org/fhir/uv/bulkdata/OperationDefinition/export" 45 | * documentation = "FHIR Operation to export data from a FHIR server, whether or not it is associated with a patient. This supports use cases like backing up a server, or exporting terminology data by restricting the resources returned using the `_type` parameter." 46 | * security.description = "Servers SHOULD implement OAuth 2.0 access management in accordance with the [SMART Backend Services: Authorization Guide](authorization.html). Implementations MAY include non-RESTful services that use authorization schemes other than OAuth 2.0, such as mutual-TLS or signed URLs." -------------------------------------------------------------------------------- /input/fsh/instances/export.fsh: -------------------------------------------------------------------------------- 1 | Instance: export 2 | InstanceOf: OperationDefinition 3 | Usage: #definition 4 | * url = "http://hl7.org/fhir/uv/bulkdata/OperationDefinition/export" 5 | * version = "2.0.0" 6 | * name = "BulkDataExport" 7 | * title = "FHIR Bulk Data System Level Export" 8 | * status = #active 9 | * kind = #operation 10 | * date = "2021-07-29" 11 | * jurisdiction = $m49.htm#001 "World" 12 | * description = "FHIR Operation to export data from a FHIR server whether or not it is associated with a patient. This supports use cases like backing up a server, or exporting terminology data by restricting the resources returned using the _type parameter. The FHIR server SHALL support invocation of this operation using the [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html)" 13 | * code = #export 14 | * system = true 15 | * type = false 16 | * instance = false 17 | * parameter[0] 18 | * name = #_outputFormat 19 | * use = #in 20 | * min = 0 21 | * max = "1" 22 | * documentation = "Support is required for a server, optional for a client.\n\nThe format for the requested Bulk Data files to be generated as per [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html). Defaults to `application/fhir+ndjson`. The server SHALL support [Newline Delimited JSON](http://ndjson.org), but MAY choose to support additional output formats. The server SHALL accept the full content type of `application/fhir+ndjson` as well as the abbreviated representations `application/ndjson` and `ndjson`." 23 | * type = #string 24 | * parameter[+] 25 | * name = #_since 26 | * use = #in 27 | * min = 0 28 | * max = "1" 29 | * documentation = "Support is required for a server, optional for a client.\n\nResources will be included in the response if their state has changed after the supplied time (e.g., if `Resource.meta.lastUpdated` is later than the supplied `_since` time). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the `_since` value supplied by a client." 30 | * type = #instant 31 | * parameter[+] 32 | * name = #_until 33 | * use = #in 34 | * min = 0 35 | * max = "1" 36 | * documentation = "Resources will be included in the response if their state has changed before the supplied time (e.g., if `Resource.meta.lastUpdated` is earlier than the supplied `_until` time). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the `_until` value supplied by a client." 37 | * type = #instant 38 | * parameter[+] 39 | * name = #_type 40 | * use = #in 41 | * min = 0 42 | * max = "*" 43 | * documentation = "Support is optional for server and a client.\n\nA string of comma-delimited FHIR resource types.\n\nThe response SHALL be filtered to only include resources of the specified resource types(s).\n\nIf this parameter is omitted, the server SHALL return all supported resources within the scope of the client authorization, though implementations MAY limit the resources returned to specific subsets of FHIR, such as those defined in the [US Core Implementation Guide](http://www.hl7.org/fhir/us/core/).\n\nA server that is unable to support `_type` SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `_type` parameter. If the client explicitly asks for export of resources that the Bulk Data server doesn't support, or asks for only resource types that are outside the Patient Compartment, the server SHOULD return details via a FHIR `OperationOutcome` resource in an error response to the request. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error.\n\nFor example `_type=Observation` could be used to filter a given export response to return only FHIR `Observation` resources." 44 | * type = #string 45 | * parameter[+] 46 | * name = #_elements 47 | * use = #in 48 | * min = 0 49 | * max = "*" 50 | * documentation = "Experimental - support is optional for a server and a client.\n\nString of comma-delimited FHIR Elements.\n\nWhen provided, the server SHOULD omit unlisted, non-mandatory elements from the resources returned. Elements SHOULD be of the form `[resource type].[element name]` (e.g., `Patient.id`) or `[element name]` (e.g., `id`) and only root elements in a resource are permitted. If the resource type is omitted, the element SHOULD be returned for all resources in the response where it is applicable. \n\nA server is not obliged to return just the requested elements. A server SHOULD always return mandatory elements whether they are requested or not. A server SHOULD mark the resources with the tag `SUBSETTED` to ensure that the incomplete resource is not actually used to overwrite a complete resource.\n\nA server that is unable to support `_elements` SHOULD return an error and a FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `_elements` parameter. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error." 51 | * type = #string 52 | * parameter[+] 53 | * name = #includeAssociatedData 54 | * use = #in 55 | * min = 0 56 | * max = "*" 57 | * documentation = "Experimental - support is optional for a server and a client.\n\nString of comma-delimited values.\n\nWhen provided, a server with support for the parameter and requested values SHALL return or omit a pre-defined set of FHIR resources associated with the request.\n\nA server that is unable to support the requested `includeAssociatedData` values SHOULD return an error and a FHIR `OperationOutcome` resource so the client can re-submit a request that omits those values (for example, if a server does not retain provenance data). When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error.\n\nIf multiple conflicting values are included, the server SHALL apply the least restrictive value (value that will return the largest dataset)." 58 | * type = #code 59 | * binding 60 | * strength = #extensible 61 | * valueSet = Canonical(IncludeAssociatedDataValueSet) 62 | * parameter[+] 63 | * name = #_typeFilter 64 | * use = #in 65 | * min = 0 66 | * max = "*" 67 | * type = #string 68 | * documentation = """ 69 | Support is optional for a server and a client. 70 | 71 | String of a FHIR REST search query. 72 | 73 | When provided, a server with support for the parameter and requested search queries SHALL filter the data in the response for resource types referenced in the typeFilter expression to only include resources that meet the specified criteria. FHIR search result parameters such as `_include` and `_sort` SHALL NOT be used and a query in the `_typeFilter` parameter SHALL have the search context of a single FHIR Resource Type. 74 | 75 | A server unable to support the requested `_typeFilter` queries SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request that omits those queries. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error. 76 | """ 77 | * parameter[+] 78 | * name = #organizeOutputBy 79 | * use = #in 80 | * min = 0 81 | * max = "1" 82 | * documentation = """ 83 | Support is optional for a server and a client. 84 | 85 | String of a FHIR resource type 86 | 87 | When provided, a server with support for the parameter SHALL organize the resources in output files by instances of the specified resource type, including a header for each resource of the type specified in the parameter, followed by the resource and resources in the output that contain references to that resource. When omitted, servers SHALL organize each output file with resources of only single type. 88 | 89 | A server unable to structure output by the requested organizeOutputBy resource SHOULD return an error and FHIR OperationOutcome resource. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 90 | """ 91 | * type = #string 92 | * parameter[+] 93 | * name = #allowPartialManifests 94 | * use = #in 95 | * min = 0 96 | * max = "1" 97 | * documentation = """ 98 | Support is optional for a server and a client. 99 | 100 | When provided, a server with support for the parameter MAY distribute the bulk data output files among multiple manifests, providing links for clients to page through the manifests. Prior to all of the files in the export being available, the server MAY return a manifest with files that are available along with a `202 Accepted` HTTP response status, and subsequently update the manifest with a paging link to a new manifest when additional files are ready for download. 101 | """ 102 | * type = #boolean -------------------------------------------------------------------------------- /input/fsh/instances/group-export.fsh: -------------------------------------------------------------------------------- 1 | Instance: group-export 2 | InstanceOf: OperationDefinition 3 | Usage: #definition 4 | * url = "http://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export" 5 | * version = "2.0.0" 6 | * name = "GroupLevelExport" 7 | * title = "FHIR Bulk Data Group Level Export" 8 | * status = #active 9 | * kind = #operation 10 | * date = "2020-07-29" 11 | * jurisdiction = $m49.htm#001 "World" 12 | * description = "FHIR Operation to obtain a detailed set of FHIR resources of diverse resource types pertaining to all members of the specified [Group](https://www.hl7.org/fhir/group.html). The FHIR server SHALL support invocation of this operation using the [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html)" 13 | * code = #export 14 | * resource = #Group 15 | * system = false 16 | * type = false 17 | * instance = true 18 | * parameter[0] 19 | * name = #_outputFormat 20 | * use = #in 21 | * min = 0 22 | * max = "1" 23 | * documentation = "Support is required for a server, optional for a client.\n\nThe format for the requested Bulk Data files to be generated as per [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html). Defaults to `application/fhir+ndjson`. The server SHALL support [Newline Delimited JSON](http://ndjson.org), but MAY choose to support additional output formats. The server SHALL accept the full content type of `application/fhir+ndjson` as well as the abbreviated representations `application/ndjson` and `ndjson`." 24 | * type = #string 25 | * parameter[+] 26 | * name = #_since 27 | * use = #in 28 | * min = 0 29 | * max = "1" 30 | * documentation = "Support is required for a server, optional for a client.\n\nResources will be included in the response if their state has changed after the supplied time (e.g., if `Resource.meta.lastUpdated` is later than the supplied `_since` time). A server MAY return additional resources modified prior to the supplied time if the resources belong to the patient compartment of a patient added to the group after the supplied time (this behavior SHOULD be clearly documented by the server). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the `_since` value supplied by a client." 31 | * type = #instant 32 | * parameter[+] 33 | * name = #_until 34 | * use = #in 35 | * min = 0 36 | * max = "1" 37 | * documentation = "Resources will be included in the response if their state has changed before the supplied time (e.g., if `Resource.meta.lastUpdated` is earlier than the supplied `_until` time). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the `_until` value supplied by a client." 38 | * type = #instant 39 | * parameter[+] 40 | * name = #_type 41 | * use = #in 42 | * min = 0 43 | * max = "*" 44 | * documentation = "Support is optional for a server and a client.\n\nA string of comma-delimited FHIR resource types.\n\nThe response SHALL be filtered to only include resources of the specified resource types(s).\n\nIf this parameter is omitted, the server SHALL return all supported resources within the scope of the client authorization, though implementations MAY limit the resources returned to specific subsets of FHIR, such as those defined in the [US Core Implementation Guide](http://www.hl7.org/fhir/us/core/). For groups of patients, the [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html) SHOULD be used as a point of reference for recommended resources to be returned. However, other resources outside of the Patient Compartment that are referenced by the resources being returned and would be helpful in interpreting the patient data MAY also be returned (such as Organization and Practitioner). When this behavior is supported, a server SHOULD document this support (for example, as narrative text, or by including a [GraphDefinition Resource](https://www.hl7.org/fhir/graphdefinition.html)).\n\nA server that is unable to support `_type` SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `_type` parameter. If the client explicitly asks for export of resources that the Bulk Data server doesn't support, or asks for only resource types that are outside the Patient Compartment, the server SHOULD return details via a FHIR `OperationOutcome` resource in an error response to the request. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error.\n\nFor example `_type=Observation` could be used to filter a given export response to return only FHIR `Observation` resources." 45 | * type = #string 46 | * parameter[+] 47 | * name = #_elements 48 | * use = #in 49 | * min = 0 50 | * max = "*" 51 | * documentation = "Experimental - support is optional for a server and a client.\n\nString of comma-delimited FHIR Elements.\n\nWhen provided, the server SHOULD omit unlisted, non-mandatory elements from the resources returned. Elements SHOULD be of the form `[resource type].[element name]` (e.g., `Patient.id`) or `[element name]` (e.g., `id`) and only root elements in a resource are permitted. If the resource type is omitted, the element SHOULD be returned for all resources in the response where it is applicable. \n\nA server is not obliged to return just the requested elements. A server SHOULD always return mandatory elements whether they are requested or not. A server SHOULD mark the resources with the tag `SUBSETTED` to ensure that the incomplete resource is not actually used to overwrite a complete resource.\n\nA server that is unable to support `_elements` SHOULD return an error and a FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `_elements` parameter. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error." 52 | * type = #string 53 | * parameter[+] 54 | * name = #patient 55 | * use = #in 56 | * min = 0 57 | * max = "*" 58 | * documentation = "Experimental - support is optional for a server and a client.\n\nThis parameter is only valid in kickoff requests initiated through a HTTP POST request. When provided, the server SHALL NOT return resources in the patient compartments belonging to patients outside of this list. If a client requests patients who are not present on the server or are not members of the requested group, the server SHOULD return details via a FHIR `OperationOutcome` resource in an error response to the request.\n\nA server that is unable to support the `patient` parameter SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `patient` parameter. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error." 59 | * type = #Reference 60 | * targetProfile = "http://hl7.org/fhir/StructureDefinition/Patient" 61 | * parameter[+] 62 | * name = #includeAssociatedData 63 | * use = #in 64 | * min = 0 65 | * max = "*" 66 | * documentation = "Experimental - support is optional for a server and a client.\n\nString of comma-delimited values.\n\nWhen provided, a server with support for the parameter and requested values SHALL return or omit a pre-defined set of FHIR resources associated with the request.\n\nA server that is unable to support the requested `includeAssociatedData` values SHOULD return an error and a FHIR `OperationOutcome` resource so the client can re-submit a request that omits those values (for example, if a server does not retain provenance data). When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error.\n\nIf multiple conflicting values are included, the server SHALL apply the least restrictive value (value that will return the largest dataset)." 67 | * type = #code 68 | * binding 69 | * strength = #extensible 70 | * valueSet = Canonical(IncludeAssociatedDataValueSet) 71 | * parameter[+] 72 | * name = #_typeFilter 73 | * use = #in 74 | * min = 0 75 | * max = "*" 76 | * type = #string 77 | * documentation = """ 78 | Support is optional for a server and a client. 79 | 80 | String of a FHIR REST search query. 81 | 82 | When provided, a server with support for the parameter and requested search queries SHALL filter the data in the response for resource types referenced in the typeFilter expression to only include resources that meet the specified criteria. FHIR search result parameters such as `_include` and `_sort` SHALL NOT be used and a query in the `_typeFilter` parameter SHALL have the search context of a single FHIR Resource Type. 83 | 84 | A server unable to support the requested `_typeFilter` queries SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request that omits those queries. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error. 85 | """ 86 | * parameter[+] 87 | * name = #organizeOutputBy 88 | * use = #in 89 | * min = 0 90 | * max = "1" 91 | * documentation = """ 92 | Support is optional for a server and a client. 93 | 94 | String of a FHIR resource type 95 | 96 | When provided, a server with support for the parameter SHALL organize the resources in output files by instances of the specified resource type, including a header for each resource of the type specified in the parameter, followed by the resource and resources in the output that contain references to that resource. When omitted, servers SHALL organize each output file with resources of only single type. 97 | 98 | A server unable to structure output by the requested organizeOutputBy resource SHOULD return an error and FHIR OperationOutcome resource. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 99 | """ 100 | * type = #string 101 | * parameter[+] 102 | * name = #allowPartialManifests 103 | * use = #in 104 | * min = 0 105 | * max = "1" 106 | * documentation = """ 107 | Support is optional for a server and a client. 108 | 109 | When provided, a server with support for the parameter MAY distribute the bulk data output files among multiple manifests, providing links for clients to page through the manifests. Prior to all of the files in the export being available, the server MAY return a manifest with files that are available along with a `202 Accepted` HTTP response status, and subsequently update the manifest with a paging link to a new manifest when additional files are ready for download. 110 | """ 111 | * type = #boolean -------------------------------------------------------------------------------- /input/fsh/instances/patient-export.fsh: -------------------------------------------------------------------------------- 1 | Instance: patient-export 2 | InstanceOf: OperationDefinition 3 | Usage: #definition 4 | * url = "http://hl7.org/fhir/uv/bulkdata/OperationDefinition/patient-export" 5 | * version = "2.0.0" 6 | * name = "PatientLevelExport" 7 | * title = "FHIR Bulk Data Patient Level Export" 8 | * status = #active 9 | * kind = #operation 10 | * date = "2021-07-29" 11 | * jurisdiction = $m49.htm#001 "World" 12 | * description = "FHIR Operation to obtain a detailed set of FHIR resources of diverse resource types pertaining to all patients. The FHIR server SHALL support invocation of this operation using the [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html)" 13 | * code = #export 14 | * resource = #Patient 15 | * system = false 16 | * type = true 17 | * instance = false 18 | * parameter[0] 19 | * name = #_outputFormat 20 | * use = #in 21 | * min = 0 22 | * max = "1" 23 | * documentation = "Support is required for a server, optional for a client.\n\nThe format for the requested Bulk Data files to be generated as per [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html). Defaults to `application/fhir+ndjson`. The server SHALL support [Newline Delimited JSON](http://ndjson.org), but MAY choose to support additional output formats. The server SHALL accept the full content type of `application/fhir+ndjson` as well as the abbreviated representations `application/ndjson` and `ndjson`." 24 | * type = #string 25 | * parameter[+] 26 | * name = #_since 27 | * use = #in 28 | * min = 0 29 | * max = "1" 30 | * documentation = "Support is required for a server, optional for a client.\n\nResources will be included in the response if their state has changed after the supplied time (e.g., if `Resource.meta.lastUpdated` is later than the supplied `_since` time). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the `_since` value supplied by a client." 31 | * type = #instant 32 | * parameter[+] 33 | * name = #_until 34 | * use = #in 35 | * min = 0 36 | * max = "1" 37 | * documentation = "Resources will be included in the response if their state has changed before the supplied time (e.g., if `Resource.meta.lastUpdated` is earlier than the supplied `_until` time). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the `_until` value supplied by a client." 38 | * type = #instant 39 | * parameter[+] 40 | * name = #_type 41 | * use = #in 42 | * min = 0 43 | * max = "*" 44 | * documentation = "Support is optional for a server and a client.\n\nA string of comma-delimited FHIR resource types.\n\nThe response SHALL be filtered to only include resources of the specified resource types(s).\n\nIf this parameter is omitted, the server SHALL return all supported resources within the scope of the client authorization, though implementations MAY limit the resources returned to specific subsets of FHIR, such as those defined in the [US Core Implementation Guide](http://www.hl7.org/fhir/us/core/). For groups of patients, the [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html) SHOULD be used as a point of reference for recommended resources to be returned. However, other resources outside of the Patient Compartment that are referenced by the resources being returned and would be helpful in interpreting the patient data MAY also be returned (such as Organization and Practitioner). When this behavior is supported, a server SHOULD document this support (for example, as narrative text, or by including a [GraphDefinition Resource](https://www.hl7.org/fhir/graphdefinition.html)).\n\nA server that is unable to support `_type` SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `_type` parameter. If the client explicitly asks for export of resources that the Bulk Data server doesn't support, or asks for only resource types that are outside the Patient Compartment, the server SHOULD return details via a FHIR `OperationOutcome` resource in an error response to the request. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error.\n\nFor example `_type=Observation` could be used to filter a given export response to return only FHIR `Observation` resources." 45 | * type = #string 46 | * parameter[+] 47 | * name = #_elements 48 | * use = #in 49 | * min = 0 50 | * max = "*" 51 | * documentation = "Experimental - support is optional for a server and a client.\n\nString of comma-delimited FHIR Elements.\n\nWhen provided, the server SHOULD omit unlisted, non-mandatory elements from the resources returned. Elements SHOULD be of the form `[resource type].[element name]` (e.g., `Patient.id`) or `[element name]` (e.g., `id`) and only root elements in a resource are permitted. If the resource type is omitted, the element SHOULD be returned for all resources in the response where it is applicable. \n\nA server is not obliged to return just the requested elements. A server SHOULD always return mandatory elements whether they are requested or not. A server SHOULD mark the resources with the tag `SUBSETTED` to ensure that the incomplete resource is not actually used to overwrite a complete resource.\n\nA server that is unable to support `_elements` SHOULD return an error and a FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `_elements` parameter. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error." 52 | * type = #string 53 | * parameter[+] 54 | * name = #patient 55 | * use = #in 56 | * min = 0 57 | * max = "*" 58 | * documentation = "Experimental - support is optional for a server and a client.\n\nThis parameter is only valid in kickoff requests initiated through a HTTP POST request. When provided, the server SHALL NOT return resources in the patient compartments belonging to patients outside of this list. If a client requests patients who are not present on the server or are not members of the requested group, the server SHOULD return details via a FHIR `OperationOutcome` resource in an error response to the request.\n\nA server that is unable to support the `patient` parameter SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request omitting the `patient` parameter. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error." 59 | * type = #Reference 60 | * targetProfile = "http://hl7.org/fhir/StructureDefinition/Patient" 61 | * parameter[+] 62 | * name = #includeAssociatedData 63 | * use = #in 64 | * min = 0 65 | * max = "*" 66 | * documentation = "Experimental - support is optional for a server and a client.\n\nString of comma-delimited values.\n\nWhen provided, a server with support for the parameter and requested values SHALL return or omit a pre-defined set of FHIR resources associated with the request.\n\nA server that is unable to support the requested `includeAssociatedData` values SHOULD return an error and a FHIR `OperationOutcome` resource so the client can re-submit a request that omits those values (for example, if a server does not retain provenance data). When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error.\n\nIf multiple conflicting values are included, the server SHALL apply the least restrictive value (value that will return the largest dataset)." 67 | * type = #code 68 | * binding 69 | * strength = #extensible 70 | * valueSet = Canonical(IncludeAssociatedDataValueSet) 71 | * parameter[+] 72 | * name = #_typeFilter 73 | * use = #in 74 | * min = 0 75 | * max = "*" 76 | * type = #string 77 | * documentation = """ 78 | Support is optional for a server and a client. 79 | 80 | String of a FHIR REST search query. 81 | 82 | When provided, a server with support for the parameter and requested search queries SHALL filter the data in the response for resource types referenced in the typeFilter expression to only include resources that meet the specified criteria. FHIR search result parameters such as `_include` and `_sort` SHALL NOT be used and a query in the `_typeFilter` parameter SHALL have the search context of a single FHIR Resource Type. 83 | 84 | A server unable to support the requested `_typeFilter` queries SHOULD return an error and FHIR `OperationOutcome` resource so the client can re-submit a request that omits those queries. When a `Prefer: handling=lenient` header is included in the request, the server MAY process the request instead of returning an error. 85 | """ 86 | * parameter[+] 87 | * name = #organizeOutputBy 88 | * use = #in 89 | * min = 0 90 | * max = "1" 91 | * documentation = """ 92 | Support is optional for a server and a client. 93 | 94 | String of a FHIR resource type 95 | 96 | When provided, a server with support for the parameter SHALL organize the resources in output files by instances of the specified resource type, including a header for each resource of the type specified in the parameter, followed by the resource and resources in the output that contain references to that resource. When omitted, servers SHALL organize each output file with resources of only single type. 97 | 98 | A server unable to structure output by the requested organizeOutputBy resource SHOULD return an error and FHIR OperationOutcome resource. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 99 | """ 100 | * type = #string 101 | * parameter[+] 102 | * name = #allowPartialManifests 103 | * use = #in 104 | * min = 0 105 | * max = "1" 106 | * documentation = """ 107 | Support is optional for a server and a client. 108 | 109 | When provided, a server with support for the parameter MAY distribute the bulk data output files among multiple manifests, providing links for clients to page through the manifests. Prior to all of the files in the export being available, the server MAY return a manifest with files that are available along with a `202 Accepted` HTTP response status, and subsequently update the manifest with a paging link to a new manifest when additional files are ready for download. 110 | """ 111 | * type = #boolean -------------------------------------------------------------------------------- /input/fsh/profiles/group.fsh: -------------------------------------------------------------------------------- 1 | ValueSet: GroupTypeSubset 2 | Id: group-type-subset 3 | Title: "Person and Practitioner from GroupType Value Set" 4 | Description: "Valuset to constrain the type element in a Group to just person and practitioner" 5 | * ^experimental = false 6 | * ^jurisdiction = $m49.htm#001 "World" 7 | * ^immutable = true 8 | * http://hl7.org/fhir/group-type#person 9 | * http://hl7.org/fhir/group-type#practitioner 10 | 11 | 12 | Extension: MemberFilter 13 | Id: member-filter 14 | Title: "Member Filter" 15 | Description: """ 16 | Extension to define the population of the group using FHIR REST API parameters. For example, the following extension would limit the population of the group to patients with an ambulatory encounter in January 2024: 17 | ``` 18 | "modifierExtension" : [{ 19 | "url" : "http://hl7.org/fhir/uv/bulkdata/StructureDefinition/member-filter", 20 | "valueExpression" : { 21 | "language" : "application/x-fhir-query", 22 | "expression" : "Encounter?class=http://terminology.hl7.org/CodeSystem/v3-ActCode|AMB&date=ge2024-01-01&date=le2024-01-31" 23 | } 24 | }] 25 | ``` 26 | """ 27 | Context: Group 28 | * . ^isModifier = true 29 | * . ^isModifierReason = "Filters members of group to a subset" 30 | * value[x] only Expression 31 | * language = #application/x-fhir-query 32 | 33 | 34 | Extension: MembersRefreshed 35 | Id: members-refreshed 36 | Title: "Members Refreshed" 37 | Description: "Extension used by a server to indicate to a client when the members in a dynamic group were last updated" 38 | Context: Group 39 | * value[x] only dateTime 40 | 41 | 42 | Profile: BulkCohortGroup 43 | Parent: Group 44 | Id: bulk-cohort-group 45 | Title: "Bulk Cohort Group" 46 | Description: "Group that provides characteristic based cohorts through coarse-grained, REST search expression based filters to support constraining bulk export requests" 47 | * type from GroupTypeSubset (required) 48 | * ^definition = """ 49 | A client SHALL populate this element with `person` when creating a group of Patients, or `practitioner` when creating a group of Practitioners. 50 | """ 51 | * member 52 | * ^definition = """ 53 | A server MAY support the inclusion of one or more `member` elements that contain an `entity` element with a reference to a Patient resource, Practitioner resource, or Group resource that is a group of Patient resources or Practitioner resources. When members are provided, the expression in the `member-filter` extension for the Group SHALL only be applied to the referenced resources and the compartments of the referenced resources, or those of the members of referenced Group resources. When members are not provided and the Group's `type` element is set to `person`, the expression in the `member-filter` extension SHALL be applied to all of the Patient resources and Patient compartments the client is authorized to access. When members are not provided and the Group's `type` element is set to `practitioner`, the expression in the `member-filter` extension SHALL be applied to all of the Practitioner resources and Practitioner compartments the client is authorized to access. 54 | """ 55 | * modifierExtension contains MemberFilter named member-filter 1..* 56 | * ^short = "Filter for members of this group" 57 | * ^definition = """ 58 | A server SHALL support the inclusion of one or more `member-filter` modifier extensions containing a `valueExpression` with a language of `application/x-fhir-query` and an `expression` populated with a FHIR REST API query for a Patient or Practitioner resource or a resource type included in the Patient or Practitioner compartment. If multiple `member-filter` extensions are provided, servers SHALL filter the group to only include Patients or Practitioners whose resources and resources in their compartments meet the conditions in all of the expressions. A server MAY also support other expression languages such as `text/cql`. When more than one language is supported by a server a client SHALL use a single language type for all of the member-filter expressions included in a single Group. 59 | 60 | FHIR [search result parameters](https://www.hl7.org/fhir/search.html#modifyingresults) (such as _sort, _include, and _elements) SHALL NOT be used as `member-filter` criteria. Additionally, a query in the `member-filter` parameter SHALL have the search context of a single FHIR Resource Type. The contexts "all resource types" and "a specified compartment" are not allowed. Clients should consult the server's capability statement to identify supported search parameters. Servers SHALL reject Group creation requests that include unsupported search parameters in a `member-filter` expression. Implementation guides that reference the Bulk Cohort API, should specify required search parameters must be supported for their use case. Other implementations guides that incorporate the Bulk Export operation MAY provide a set of core search parameters that servers implementing the guide need to support. 61 | """ 62 | * extension contains MembersRefreshed named members-refreshed 0..1 63 | * ^short = "when membership in this group was updated" 64 | * ^definition = """ 65 | If a groups membership is calculated periodically from the `member-filter` criteria, a server SHALL populate a `valueDateTime` with the date the group's membership was last updated. When a `date` element is populated for the Group, the `valueDateTime` element SHALL NOT be later than the date in that element, but may be the same datetime or an earlier datetime. If members are calculated dynamically for the group (for example, when a Bulk Export operation is kicked off) this value SHALL be omitted. The server's refresh cycle capabilities and relevant configuration options SHOULD be described in the server's documentation. 66 | """ 67 | * name 1..1 68 | * characteristic 0..0 69 | * ^short = "This element is not used for in groups complying with this profile" 70 | * actual 71 | * ^short = "True if the member element is populated, otherwise false." 72 | * ^definition = "True if the member element is populated, otherwise false." 73 | 74 | Instance: BulkCohortGroupExample 75 | InstanceOf: BulkCohortGroup 76 | Title: "Bulk Cohort Group Example" 77 | Description: "Blue cross plan member group with members filtered to patients that have an active diagnosis of diabetes on their problem list and an ambulatory encounter in January 2024" 78 | Usage: #example 79 | * meta.extension[0].url = "http://hl7.org/fhir/StructureDefinition/instance-name" 80 | * meta.extension[0].valueString = "Bulk Cohort Group Profile Example" 81 | * meta.extension[1].url = "http://hl7.org/fhir/StructureDefinition/instance-description" 82 | * meta.extension[1].valueMarkdown = "Blue cross plan member group with members filtered to patients that have an active diagnosis of diabetes on their problem list and an ambulatory encounter in January 2024" 83 | * name = "DM Dx and Jan. 2024 Ambulatory Encounter" 84 | * member.entity = Reference("http://example.org/fhir/Group/blue-cross-members) 85 | * extension[members-refreshed].valueDateTime = "2024-08-22T10:00:00Z" 86 | * modifierExtension[member-filter][0].valueExpression.expression = "Condition?category=http://terminology.hl7.org/CodeSystem/condition-category|problem-list-item&clinical-status=http://terminology.hl7.org/CodeSystem/condition-clinical|active&code=http://hl7.org/fhir/sid/icd-10-cm|E11.9" 87 | * modifierExtension[member-filter][1].valueExpression.expression = "Encounter?class=http://terminology.hl7.org/CodeSystem/v3-ActCode|AMB&date=ge2024-01-01&date=le2024-01-31" 88 | * type = #person 89 | * actual = true -------------------------------------------------------------------------------- /input/fsh/valuesets/IncludeAssociatedDataValueSet.fsh: -------------------------------------------------------------------------------- 1 | ValueSet: IncludeAssociatedDataValueSet 2 | Id: include-associated-data 3 | Title: "Include Associated Data Value Set" 4 | Description: "Metadata inclusion options for Bulk Data Access Export Operation includeAssociatedData parameter" 5 | * ^version = "2.0.0" 6 | * ^status = #active 7 | * ^date = "2021-07-29" 8 | * ^experimental = false 9 | * ^jurisdiction = $m49.htm#001 "World" 10 | * ^immutable = true 11 | * include codes from system IncludeAssociatedDataCodeSystem -------------------------------------------------------------------------------- /input/ignoreWarnings.txt: -------------------------------------------------------------------------------- 1 | == Suppressed Messages == -------------------------------------------------------------------------------- /input/images-source/bulk-flow.plantuml: -------------------------------------------------------------------------------- 1 | @startuml 2 | participant APP as "Bulk Data Client" 3 | box Bulk Data Provider 4 | participant "FHIR Authorization Server" as AUTH 5 | participant "FHIR Resource Server" as FHIR 6 | participant "Output File Server" as FILE 7 | end box 8 | opt Precondition: SMART Backend Services Registration 9 | APP -> AUTH: Registration 10 | return client_id 11 | end 12 | opt Precondition: SMART Backend Services Authorization 13 | APP -> AUTH: Signed token request 14 | return Short lived token 15 | end 16 | APP -> FHIR: Kick-off request 17 | activate FHIR #eee 18 | FHIR --> APP: Status polling location 19 | loop Check export status (repeat 1..n) 20 | APP -> FHIR: Status request 21 | FHIR --> APP: In-progress status 22 | end 23 | FHIR -> FILE: Generated files 24 | deactivate FHIR 25 | activate FILE 26 | APP -> FHIR: Status request 27 | FHIR --> APP: Complete status (JSON manifest) 28 | loop Retrieve files and errors (repeat 0..n) 29 | APP -> FILE: Bulk Data output file request 30 | FILE --> APP: Bulk Data file 31 | end 32 | loop Retrieve attachments (repeat 0..n) 33 | APP -> FILE: Bulk Data attachment file request 34 | FILE --> APP: Attachment file 35 | end 36 | deactivate FILE #eee 37 | @enduml -------------------------------------------------------------------------------- /input/images-source/processing-model.plantuml: -------------------------------------------------------------------------------- 1 | @startuml 2 | start 3 | :All resources available for Bulk Export; 4 | :Exclude unauthorized resources 5 | (based on OAuth scopes and business logic); 6 | if (group export) then (yes) 7 | :Exclude resources for patients outside group; 8 | else (no) 9 | endif 10 | if (`_type` parameter?) then (yes) 11 | :Exclude resource of types not listed in `_type` parameter; 12 | else (no) 13 | endif 14 | if (`_since` parameter?) then (yes) 15 | :Exclude resources updated prior to `_since` timestamp*; 16 | else (no) 17 | endif 18 | if (`_typeFilter` parameter?) then (yes) 19 | repeat :for each resource type in export; 20 | if (has `_typeFilter` criteria) then (yes) 21 | :Exclude resources of this resource type 22 | that don't meet criteria in at least one 23 | of the `_typeFilter` parameters; 24 | else (no) 25 | :Retain all resources for this resource type; 26 | endif 27 | repeat while (additional resource types in export?); 28 | endif 29 | if (`includeAssociatedData` parameter) then (yes) 30 | :Add associated resources for resources in export; 31 | else (no) 32 | endif 33 | :Add other related resources to provide context to those in export; 34 | :Output resources; 35 | stop 36 | @enduml -------------------------------------------------------------------------------- /input/images/security-risk-assessment-report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HL7/bulk-data/b666e58153a2f0a18dc85bf6b9c96595f829d492/input/images/security-risk-assessment-report.pdf -------------------------------------------------------------------------------- /input/pagecontent/abbreviations.md: -------------------------------------------------------------------------------- 1 | This page contains a list of abbreviations mentioned in this implementation guide. 2 | 3 | ### Healthcare Abbreviations 4 | * CQL - Clinical Quality Language 5 | * DSTU - Draft Standard for Trial Use 6 | * EHR - Electronic Health Record 7 | * HL7 - Health Layer 7 8 | * IG - Implementation Guide 9 | * FHIR - Fast Healthcare Interoperability Resources 10 | * PHI - Protected Health Information 11 | * PTSD - Post Traumatic Stress Disorder 12 | * RIM - Reference Information Model 13 | * SMART - Substitutable Medical Apps, Reusable Technology 14 | * STU - Standard for Trial Use 15 | 16 | ### External 17 | * API - Application Programming Interface 18 | * HTTP - Hypertext Transfer Protocol 19 | * HTTPS - Hypertext Transfer Protocol Secure 20 | * JSON - JavaScript Object Notation 21 | * JWT - JSON Web Token 22 | * JWK - JSON Web Keys 23 | * MIT - Massachusetts Institute of Technology 24 | * NDJSON - Newline Delimited JavaScript Object Notation 25 | * OID - Object Identifier 26 | * REST - Representational State Transfer 27 | * RFC - Request for Comments 28 | * RSA - Rivest, Shamir, and Adelman (inventors of the RSA public-key encryption algorithm) 29 | * TLS - Transport Layer Security 30 | * URL - Uniform Resource Locator 31 | * URI - Universal Resource Identifier 32 | * UTF - Unicode Transformation Format 33 | * XML - Extensible Markup Language 34 | -------------------------------------------------------------------------------- /input/pagecontent/authorization.md: -------------------------------------------------------------------------------- 1 | Bulk Data Providers implementing the Bulk Data Export Operation SHOULD implement OAuth 2.0 access management in accordance with the [SMART Backend Services Authorization Profile](http://www.hl7.org/fhir/smart-app-launch/backend-services.html). 2 | 3 | Note that that to reduce duplication, documentation for the SMART Backend Services Authorization Profile that was previously included in this IG and has been migrated and integrated into the SMART [App Launch Implementation Guide](http://www.hl7.org/fhir/smart-app-launch). -------------------------------------------------------------------------------- /input/pagecontent/changes.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | ### STU2 - v2.0.0 7 | 8 | #### Export Kickoff Request 9 | * Permitted server support for kickoff requests via HTTP `POST` of a Parameters Resource 10 | * Documented required and optional status of kickoff parameters for server implementors 11 | * Documented guidance on use and interpretation of repeated parameters 12 | * Expanded definition of `_since` parameter in Group level kickoff requests to permit servers to return resources that have an earlier `lastUpdated` date for patients that were added to the group after the supplied date 13 | * Clarified which resources should be returned in scenarios where `_type` is populated 14 | * Added optional `_elements` kickoff parameter to filter resource data elements in the response 15 | * Added optional `patient` kickoff parameter to filter resources in the response by patient id 16 | * Added optional `includeAssociatedData` kickoff parameter and ValueSet for clients to indicate a set of pre-defined resources to omit or include with the response 17 | * Provided guidance on server handling of unsupported kickoff parameters when a `prefer: handling=lenient header` is or is not provided 18 | * Added recommended approach for clients to obtain historical data on new group members when not automatically included by server in Group level requests 19 | * Clarified that resources associated with groups containing non-patient members (e.g., groups of practitioners or groups of devices) may be exported using a group-level bulk export request 20 | * Updated the `Accept` and `Prefer` header requirements from required to recommended for clients, with servers having discretion on whether to return an error or presume a default if omitted 21 | * Clarified server behavior in cases where the modification date of resources is not tracked and a `_since` parameter is provided by a client 22 | 23 | #### Export Status Response 24 | * Provided guidance for servers to return a transient error code in an `OperationOutcome` response when the error indicates a failure to obtain a status rather than a failure of the underlying job 25 | * Permitted an error response that does not contain an `OperationOutcome` in the body when servers are unable to provide this 26 | 27 | #### Export Complete Status Response 28 | * Permitted clients to send a HTTP `DELETE` request the the status endpoint following a complete status to signal to the server that it no longer needs to retain the output files 29 | * Clarified that the `output.url` field in the complete status response should be an absolute path 30 | * Clarified that the `error` field of the complete status response may include files containing `OperationOutcome` resources that are informational in nature 31 | * Added `deleted` field in complete status response where servers can list resources that should be removed from downstream systems 32 | 33 | #### Export - Data 34 | * Clarified that resource references in the response may be relative or absolute 35 | * Provided guidance for servers and clients to send and retrieve `Binary` resources and `Attachment` elements 36 | * Changed requirement to populate `Attachment.contentType` in Attachments from a requirement to a recommendation to align with the core FHIR spec 37 | 38 | #### Export - Other 39 | * Added recommendations on server capability documentation 40 | 41 | #### Backend Services Authorization 42 | * Migrated and integrated documentation into the SMART App Launch Implementation Guide 43 | * Clarified that servers must support clients that provide a URL pointing to a JWKS Set on registration, as well as those that provide a JWKS Set directly on registration 44 | * Clarified authorization requirements for status and data requests 45 | * Clarified the algorithm for verifying a client's public key 46 | * Clarified scopes language and described optional support for SMART v2 scope 47 | 48 | 49 | ### STU1 Technical Correction - v1.0.1 50 | 51 | * Updated the CapabilityStatement to move the Patient and Group level export operations from the `rest.operation` element to `rest.resource.operation` elements and correct the OperationDefinition URLs 52 | * Corrected conformance URL 53 | * Added note on export complete status extension field description to clarify that extensions may be placed under to any field in the export complete status response and not just at the root level of the response 54 | 55 | 56 | ### STU1 - v1.0.0 57 | 58 | * Initial release 59 | -------------------------------------------------------------------------------- /input/pagecontent/downloads.xml: -------------------------------------------------------------------------------- 1 |
2 | {% assign excludexml = site.data.info.excludexml | downcase | slice: 0 %} 3 | {% assign excludejson = site.data.info.excludejson | downcase | slice: 0 %} 4 | {% assign excludettl = site.data.info.excludettl | downcase | slice: 0 %} 5 |

6 | Download the entire implementation guide here 7 |

8 | 9 | 10 | 11 | 12 | {% unless excludexml == 'y' %} 13 | 16 | {% endunless %} 17 | {% unless excludejson == 'y' %} 18 | 21 | {% endunless %} 22 | {% unless excludettl == 'y' %} 23 | 26 | {% endunless %} 27 | 28 | 29 |
Artifact Definitions 14 | XML 15 | 19 | JSON 20 | 24 | Turtle 25 |
30 |
-------------------------------------------------------------------------------- /input/pagecontent/export.md: -------------------------------------------------------------------------------- 1 | ### Audience and Scope 2 | 3 | This implementation guide is intended to be used by developers of backend services (clients) and FHIR Resource Servers (e.g., EHR systems, data warehouses, and other clinical and administrative systems) that aim to interoperate by sharing large FHIR datasets. The guide defines the application programming interfaces (APIs) through which an authenticated and authorized client may request a Bulk Data Export from a server, receive status information regarding progress in the generation of the requested files, and retrieve these files. It also includes recommendations regarding the FHIR resources that might be exposed through the export interface. 4 | 5 | The scope of this document does NOT include: 6 | 7 | * A legal framework for sharing data between partners, such as Business Associate Agreements, Service Level Agreements, and Data Use Agreements, though these may be required for some use cases. 8 | * Real-time data exchange 9 | * Data transformations that may be required by the client 10 | * Patient matching (although identifiers may be included in the exported FHIR resources) 11 | * Management of FHIR groups (although some Bulk Data operations require a FHIR Group id, this guide does not specify how Group resources are created and maintained within a system) 12 | 13 | ### Underlying Standards 14 | 15 | * [HL7 FHIR](https://www.hl7.org/fhir/) 16 | * [Newline-delimited JSON](https://github.com/ndjson/ndjson-spec) 17 | * [RFC5246, Transport Layer Security (TLS) Protocol Version 1.2](https://tools.ietf.org/html/rfc5246) 18 | * [RFC6749, The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749) 19 | * [RFC6750, The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750) 20 | * [RFC7159, The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159) 21 | * [RFC7240, Prefer Header for HTTP](https://tools.ietf.org/html/rfc7240) 22 | 23 | ### Terminology 24 | 25 | This profile inherits terminology from the standards referenced above. 26 | The key words "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this specification are to be interpreted as described in [RFC2119](https://tools.ietf.org/html/rfc2119). 27 | 28 | ### Privacy and Security Considerations 29 | 30 | All exchanges described herein between a client and a server SHALL be secured using [Transport Layer Security (TLS) Protocol Version 1.2 (RFC5246)](https://tools.ietf.org/html/rfc5246) or a more recent version of TLS. Use of mutual TLS is OPTIONAL. 31 | 32 | With each of the requests described herein, implementers SHOULD implement OAuth 2.0 access management in accordance with the [SMART Backend Services Authorization Profile](authorization.html). When SMART Backend Services Authorization is used, Bulk Data Status Request and Bulk Data Output File Requests with `requiresAccessToken=true` SHALL be protected the same way the Bulk Data Kick-off Request, including an access token with scopes that cover all resources being exported. A server MAY additionally restrict Bulk Data Status Request and Bulk Data Output File Requests by limiting them to the client that originated the export. Implementations MAY include endpoints that use authorization schemes other than OAuth 2.0, such as mutual-TLS or signed URLs. 33 | 34 | This implementation guide does not address protection of a server from potential compromise. An adversary who successfully captures administrative rights to the server will have full control over that server and can use those rights to undermine the server's security protections. In the Bulk Data Export workflow, the file server will be a particularly attractive target, as it holds highly sensitive and valued PHI. An adversary who successfully takes control of a file server may choose to continue to deliver files in response to client requests, so that neither the client nor the FHIR server is aware of the take-over. Meanwhile, the adversary is able to put the PHI to use for its own malicious purposes. 35 | 36 | Healthcare organizations have an imperative to protect PHI persisted in file servers in both cloud and data-center environments. A range of existing and emerging approaches can be used to accomplish this, not all of which would be visible at the API level. This specification does not dictate a particular approach at this time, though it does support the use of an `Expires` header to limit the time period a file will be available for client download (removal of the file from the server is left up to the server implementer). A server SHOULD NOT delete files from a Bulk Data response that a client is actively in the process of downloading regardless of the pre-specified expiration time. 37 | 38 | Data access control obligations can be met with a combination of in-band restrictions (e.g., OAuth scopes), and out-of-band restrictions, where the server limits the data returned to a specific client in accordance with local considerations (e.g. policies or regulations). The FHIR server SHALL limit the data returned to only those FHIR resources for which the client is authorized. Implementers SHOULD incorporate technology that preserves and respects an individual's wishes to share their data with desired privacy protections. For example, some clients are authorized to access sensitive mental health information and some aren't; this authorization is defined out-of-band, but when a client requests a full data set, filtering is automatically applied by the server, restricting the data that the client receives. 39 | 40 | Bulk Data Export can be a resource-intensive operation. Server developers SHOULD consider and mitigate the risk of intentional or inadvertent denial-of-service attacks though the details are beyond the scope of this specification. For example, transactional systems may wish to provide Bulk Data access to a read-only mirror of the database or may distribute processing over time to avoid loads that could impact clinical operations. 41 | 42 | ### Bulk Data Export Operation Request Flow 43 | 44 | This implementation guide builds on the [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html), and in some places may extend the pattern. 45 | 46 | #### Roles 47 | 48 | There are two primary roles involved in a Bulk Data transaction: 49 | 50 | 1. **Bulk Data Provider** - consists of: 51 | 52 | a. **FHIR Authorization Server** - server that issues access tokens in response to valid token requests from client. 53 | 54 | b. **FHIR Resource Server** - server that accepts kick-off request and provides job status and completion manifest. 55 | 56 | c. **Output File Server** - server that returns FHIR Bulk Data files and attachments in response to urls in the completion manifest. This may be built into the FHIR Server, or may be independently hosted. 57 | 58 | 2. **Bulk Data Client** - system that requests and receives access tokens and Bulk Data files 59 | 60 | #### Sequence Overview 61 | 62 |
63 | {% include bulk-flow.svg %} 64 |
Diagram showing an overview of the Bulk Data Export operation request flow
65 |
66 | 67 | #### Bulk Data Kick-off Request 68 | 69 | The Bulk Data Export Operation initiates the asynchronous generation of a requested export dataset - whether that be data for all patients, data for a subset (defined group) of patients, or all FHIR data in the server. 70 | 71 | As discussed in See [Privacy and Security Considerations](#privacy-and-security-considerations) above, a server SHALL limit the data returned to only those FHIR resources for which the client is authorized. 72 | 73 | The Resource FHIR server SHALL support invocation of this operation using the [FHIR Asynchronous Request Pattern](http://hl7.org/fhir/R4/async.html). A server SHALL support GET requests and MAY support POST requests that supply parameters using the FHIR [Parameters Resource](https://www.hl7.org/fhir/parameters.html). 74 | 75 | A client MAY repeat kick-off parameters that accept comma delimited values multiple times in a kick-off request. The server SHALL treat the values provided as if they were comma delimited values within a single instance of the parameter. Note that we will be soliciting feedback on the use of comma delimited values within parameters, and depending on the response may consider deprecating this input approach in favor of repeating parameters in a future version of this IG. 76 | 77 | For Patient-level requests and Group-level requests associated with groups of patients, the [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html) SHOULD be used as a point of reference for recommended resources to be returned and, where applicable, Patient resources SHOULD be returned. Other resources outside of the patient compartment that are helpful in interpreting the patient data (such as Organization and Practitioner) MAY also be returned. 78 | 79 | Binary Resources whose content is associated with an individual patient SHALL be serialized as DocumentReference Resources with the `content.attachment` element populated as described in the [Attachments](#attachments) section below. Binary Resources not associated with an individual patient MAY be included in a System Level export. 80 | 81 | References in the resources returned MAY be relative URLs with the format <resource type>/<id>, or MAY be absolute URLs with the same structure rooted in the base URL for the server from which the export was performed. 82 | 83 | ##### Endpoint - All Patients 84 | 85 | `[fhir base]/Patient/$export` 86 | 87 | [View table of parameters for Patient Export](OperationDefinition-patient-export.html) 88 | 89 | FHIR Operation to obtain a detailed set of FHIR resources of diverse resource types pertaining to all patients. 90 | 91 | ##### Endpoint - Group of Patients 92 | 93 | `[fhir base]/Group/[id]/$export` 94 | 95 | [View table of parameters for Group Export](OperationDefinition-group-export.html) 96 | 97 | FHIR Operation to obtain a detailed set of FHIR resources of diverse resource types pertaining to all members of a specified [Group](https://www.hl7.org/fhir/group.html). 98 | 99 | If a FHIR server supports Group-level data export, it SHOULD support reading and searching for `Group` resource. This enables clients to discover available groups based on stable characteristics such as `Group.identifier`. 100 | 101 | Note: How these Groups are defined is specific to each FHIR system's implementation. For example, a payer may send a healthcare institution a roster file that can be imported into their EHR to create or update a FHIR group. Group membership could be based upon explicit attributes of the patient, such as age, sex or a particular condition such as PTSD or Chronic Opioid use, or on more complex attributes, such as a recent inpatient discharge or membership in the population used to calculate a quality measure. FHIR-based group management is out of scope for the current version of this implementation guide. 102 | 103 | ##### Endpoint - System Level Export 104 | 105 | `[fhir base]/$export` 106 | 107 | [View table of parameters for Export](OperationDefinition-export.html) 108 | 109 | Export data from a FHIR server, whether or not it is associated with a patient. This supports use cases like backing up a server, or exporting terminology data by restricting the resources returned using the `_type` parameter. 110 | 111 | ##### Headers 112 | 113 | - `Accept` (string) 114 | 115 | Specifies the format of the optional FHIR `OperationOutcome` resource response to the kick-off request. Currently, only `application/fhir+json` is supported. A client SHOULD provide this header. If omitted, the server MAY return an error or MAY process the request as if `application/fhir+json` was supplied. 116 | 117 | - `Prefer` (string) 118 | 119 | Specifies whether the response is immediate or asynchronous. Currently, only a value of respond-async is supported. A client SHOULD provide this header. If omitted, the server MAY return an error or MAY process the request as if respond-async was supplied. 120 | 121 | ##### Query Parameters 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 233 | 234 | 235 |
Query ParameterOptionality for ServerOptionality for ClientCardinalityTypeDescription
_outputFormatrequiredoptional0..1StringThe format for the requested Bulk Data files to be generated as per FHIR Asynchronous Request Pattern. Defaults to application/fhir+ndjson. The server SHALL support Newline Delimited JSON, but MAY choose to support additional output formats. The server SHALL accept the full content type of application/fhir+ndjson as well as the abbreviated representations application/ndjson and ndjson.
_sincerequiredoptional0..1FHIR instantResources will be included in the response if their state has changed after the supplied time (e.g., if Resource.meta.lastUpdated is later than the supplied _since time). In the case of a Group level export, the server MAY return additional resources modified prior to the supplied time if the resources belong to the patient compartment of a patient added to the Group after the supplied time (this behavior SHOULD be clearly documented by the server). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the _since value supplied by a client.
_untiloptionaloptional0..1FHIR instantResources will be included in the response if their state has changed before the supplied time (e.g., if Resource.meta.lastUpdated is earlier than the supplied _until time). The server MAY return resources that are referenced by the resources being returned regardless of when the referenced resources were last updated. For resources where the server does not maintain a last updated time, the server MAY include these resources in a response irrespective of the _until value supplied by a client.
_typeoptionaloptional0..*string of comma-delimited FHIR resource typesThe response SHALL be filtered to only include resources of the specified resource types(s).

164 | If this parameter is omitted, the server SHALL return all supported resources within the scope of the client authorization, though implementations MAY limit the resources returned to specific subsets of FHIR, such as those defined in the US Core Implementation Guide. For Patient- and Group-level requests, the Patient Compartment SHOULD be used as a point of reference for recommended resources to be returned. However, other resources outside of the Patient Compartment that are referenced by the resources being returned and would be helpful in interpreting the patient data MAY also be returned (such as Organization and Practitioner). When this behavior is supported, a server SHOULD document this support (for example, as narrative text, or by including a GraphDefinition Resource).

165 | A server that is unable to support _type SHOULD return an error and FHIR OperationOutcome resource so the client can re-submit a request omitting the _type parameter. If the client explicitly asks for export of resources that the Bulk Data server doesn't support, or asks for only resource types that are outside the Patient Compartment, the server SHOULD return details via a FHIR OperationOutcome resource in an error response to the request. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error.

166 | For example _type=Observation could be used to filter a given export response to return only FHIR Observation resources.
_elementsoptional, experimentaloptional0..*string of comma-delimited FHIR ElementsWhen provided, the server SHOULD omit unlisted, non-mandatory elements from the resources returned. Elements SHOULD be of the form [resource type].[element name] (e.g., Patient.id) or [element name] (e.g., id) and only root elements in a resource are permitted. If the resource type is omitted, the element SHOULD be returned for all resources in the response where it is applicable.

175 | A server is not obliged to return just the requested elements. A server SHOULD always return mandatory elements whether they are requested or not. A server SHOULD mark the resources with the tag SUBSETTED to ensure that the incomplete resource is not actually used to overwrite a complete resource.

176 | A server that is unable to support _elements SHOULD return an error and FHIR OperationOutcome resource so the client can re-submit a request omitting the _elements parameter. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 177 |
patient
(POST requests only)
optionaloptional0..*FHIR ReferenceNot applicable to system level export requests. When provided, the server SHALL NOT return resources in the patient compartments belonging to patients outside of this list. If a client requests patients who are not present on the server (or in the case of a group level export, who are not members of the group), the server SHOULD return details via a FHIR OperationOutcome resource in an error response to the request.

186 | A server that is unable to support patient SHOULD return an error and FHIR OperationOutcome resource so the client can re-submit a request omitting the patient parameter. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 187 |
includeAssociatedData
optional, experimentaloptional0..*string of comma delimited valuesWhen provided, a server with support for the parameter and requested values SHALL return or omit a pre-defined set of FHIR resources associated with the request.

196 | A server that is unable to support the requested includeAssociatedData values SHOULD return an error and FHIR OperationOutcome resource so the client can re-submit a request that omits those values (for example, if a server does not retain provenance data). When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error.

197 | A client MAY include one or more of the following values. If multiple conflicting values are included, the server SHALL apply the least restrictive value (value that will return the largest dataset). 198 |
    199 |
  • LatestProvenanceResources: Export will include the most recent Provenance resources associated with each of the non-provenance resources being returned. Other Provenance resources will not be returned.
  • 200 |
  • RelevantProvenanceResources: Export will include all Provenance resources associated with each of the non-provenance resources being returned.
  • 201 |
  • _[custom value]: A server MAY define and support custom values that are prefixed with an underscore (e.g., _myCustomPreset).
  • 202 |
203 |
_typeFilter
optionaloptional0..*string of a FHIR REST API queryWhen provided, a server with support for the parameter and the requested search parameters SHALL filter the data in the response for resource types referenced in the typeFilter expression to only include resources that meet the specified criteria. FHIR search result parameters such as _include and _sort SHALL NOT be used. See details below.

212 | A server unable to support the requested _typeFilter queries SHOULD return an error and FHIR OperationOutcome resource so the client can re-submit a request that omits those queries. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 213 |
organizeOutputBy
optionaloptional0..1string of a FHIR resource typeWhen provided, a server with support for the parameter SHALL organize the resources in output files by instances of the specified resource type, including a header for each resource of the type specified in the parameter, followed by the resource and resources in the output that contain references to that resource. When omitted, servers SHALL organize each output file with resources of only single type. See details below.

222 | A server unable to structure output by the requested organizeOutputBy resource SHOULD return an error and FHIR OperationOutcome resource. When a Prefer: handling=lenient header is included in the request, the server MAY process the request instead of returning an error. 223 |
allowPartialManifests
optionaloptional0..1booleanWhen provided, a server with support for the parameter MAY distribute the bulk data output files among multiple manifests, providing links for clients to page through the manifests (see details below). Prior to all of the files in the export being available, the server MAY return a manifest with files that are available along with a 202 Accepted HTTP response status, and subsequently update the manifest with a paging link to a new manifest when additional files are ready for download (see details below). 232 |
236 | 237 | *Note*: Implementations MAY limit the resources returned to specific subsets of FHIR, such as those defined in the [US Core Implementation Guide](http://www.hl7.org/fhir/us/core/). If the client explicitly asks for export of resources that the Bulk Data server doesn't support, the server SHOULD return details via a FHIR `OperationOutcome` resource in an error response to the request. 238 | 239 | If an includeAssociatedValue value relevant to provenance is not specified, or if this parameter is not supported by a server, the server SHALL include all available Provenance resources whose `Provenance.target` is a resource in the Patient compartment in a patient level export request, and all available Provenance resources in a system level export request unless a specific resource set is specified using the _type parameter and this set does not include Provenance. 240 | 241 | ##### Group Membership Request Pattern 242 | 243 | To obtain new and updated resources for patients in a group, as well as all data for patients who have joined the group since a prior query, a client can use following pattern: 244 | 245 | - Initial Query (e.g., on January 1, 2020): 246 | 247 | - Client submits a group export request: 248 | 249 | `[baseurl]/Group/[id]/$export` 250 | 251 | - Client retrieves response data 252 | - Client retains a list of the patient ids returned 253 | - Client retains the transactionTime value from the response 254 | 255 | - Subsequent Queries (e.g., on February 1, 2020): 256 | - Client submits a group export request to obtain a patient list: 257 | 258 | `[baseurl]/Group/[id]/$export?_type=Patient&_elements=id` 259 | 260 | - Client retains a list of patient ids returned 261 | - Client compares response to patient ids from first query request and identifies new patient ids 262 | - Client submits a group export request via POST for patients who are new members of the group: 263 | 264 | ``` 265 | POST [baseurl]/Group/[id]/$export 266 | 267 | {"resourceType" : "Parameters", 268 | "parameter" : [{ 269 | "name" : "patient", 270 | "valueReference" : {reference: "Patient/123"} 271 | },{ 272 | "name" : "patient", 273 | "valueReference" : {reference: "Patient/456"} 274 | ... 275 | }] 276 | } 277 | ``` 278 | 279 | - Client submits a group export request for updated group data: 280 | 281 | `[baseurl]/Group/[id]/$export?_since=[initial transaction time]` 282 | 283 | Note that data returned from this request may overlap with that returned from the prior step. 284 | 285 | - Client retains the transactionTime value from the response. 286 | 287 | ##### `_typeFilter` Query Parameter 288 | 289 | The `_typeFilter` parameter enables finer-grained filtering out of resources in the bulk data export response that would have otherwise been returned. For example, a client may want to retrieve only active prescriptions rather than all prescriptions and only laboratory observations rather than all observations. When using `_typeFilter`, each resource type is filtered independently. For example, filtering `Patient` resources to people born after the year 2000 will not filter `Encounter` resources for patients born before the year 2000 from the export. 290 | 291 | The value of the `_typeFilter` parameter is a FHIR REST API query. Resources with a resource type specified in this query that do not meet the criteria in the search expression in the query SHALL NOT be returned, with the exception of related resources being included by a server to provide context about the resources being exported (see [processing model](#processing-model)). A client MAY repeat the `_typeFilter` parameter multiple times in a kick-off request. When more than one `_typeFilter` parameter is provided with a query for the same resource type, the server SHALL include resources of that resource type that meet the criteria in any of the parameters (a logical "or"). 292 | 293 | FHIR [search result parameters](https://www.hl7.org/fhir/search.html#modifyingresults) (such as _sort, _include, and _elements) SHALL NOT be used as `_typeFilter` criteria. Additionally, a query in the `_typeFilter` parameter SHALL have the [search context](https://hl7.org/fhir/search.html#searchcontexts) of a single FHIR Resource Type. The contexts "all resource types" and "a specified compartment" are not allowed. Clients should consult the server's capability statement to identify supported search parameters (see [server capability documentation](#server-capability-documentation)). Since support for `_typeFilter` is OPTIONAL for a FHIR server, clients SHOULD be robust to servers that ignore `_typeFilter`. 294 | 295 |
296 | Chained parameters used in a typeFilter query are an experimental feature, and when supported by a server, the set of exported resources resulting from the interactions between the _typeFilter parameter and other kickoff parameters may be surprising. We are soliciting feedback on the use of chained parameters, and depending on the response may consider deprecating this capability in a future version of this IG. 297 |
298 | 299 | **Example Request** 300 | 301 | The following is an export request for `MedicationRequest` resources, where the client would further like to restrict the MedicationRequests to those that are `active`, or else `completed` after July 1, 2018. This can be accomplished with two `_typeFilter` query parameters and an `_type ` query parameter: 302 | 303 | 304 | * `MedicationRequest?status=active` 305 | * `MedicationRequest?status=completed&date=gt2018-07-01T00:00:00Z` 306 | 307 | ``` 308 | $export? 309 | _type= 310 | MedicationRequest 311 | &_typeFilter= 312 | MedicationRequest%3Fstatus%3Dactive 313 | &_typeFilter= 314 | MedicationRequest%3Fstatus%3Dcompleted%26date%3Dgt2018-07-01T00%3A00%3A00Z 315 | ``` 316 | 317 | _Note that newlines and spaces have been added above for clarity, and would not be included in a real request._ 318 | 319 | ##### Processing Model 320 | 321 | The following steps outline a logical model of how a server should process a bulk export request. The actual operations a server performs and the order in which they're performed may differ. Additionally, as documented elsewhere in this implementation guide, depending on the values and headers provided, some requests may cause a server to return an error rather than continuing to process the request. 322 | 323 |
324 | {% include processing-model.svg %} 325 |
Diagram outlining a logical model of how a server should process a bulk export request.
326 |
327 |
328 | _* In the case of a Group level export, the server may retain resources modified prior to _since timestamp if the resources belong to the patient compartment of a patient added to the Group after the supplied time and this behavior is documented by the server._ 329 | 330 | ##### Response - Success 331 | 332 | - HTTP Status Code of `202 Accepted` 333 | - `Content-Location` header with the absolute URL of an endpoint for subsequent status requests (polling location) 334 | - Optionally, a FHIR `OperationOutcome` resource in the body in JSON format 335 | 336 | ##### Response - Error (e.g., unsupported search parameter) 337 | 338 | - HTTP Status Code of `4XX` or `5XX` 339 | - The body SHALL be a FHIR `OperationOutcome` resource in JSON format 340 | 341 | If a server wants to prevent a client from beginning a new export before an in-progress export is completed, it SHOULD respond with a `429 Too Many Requests` status and a [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header, following the rate-limiting advice for "Bulk Data Status Request" below. 342 | 343 | --- 344 | #### Bulk Data Delete Request 345 | 346 | After a Bulk Data request has been started, a client MAY send a DELETE request to the URL provided in the `Content-Location` header to cancel the request as described in the [FHIR Asynchronous Request Pattern](https://www.hl7.org/fhir/R4/async.html). If the request has been completed, a server MAY use the request as a signal that a client is done retrieving files and that it is safe for the sever to remove those from storage. Following the delete request, when subsequent requests are made to the polling location, the server SHALL return a `404 Not Found` error and an associated FHIR `OperationOutcome` in JSON format. 347 | 348 | ##### Endpoint 349 | 350 | `DELETE [polling content location]` 351 | 352 | ##### Response - Success 353 | 354 | - HTTP Status Code of `202 Accepted` 355 | - Optionally a FHIR `OperationOutcome` resource in the body in JSON format 356 | 357 | ##### Response - Error Status 358 | 359 | - HTTP status code of `4XX` or `5XX` 360 | - The body SHALL be a FHIR `OperationOutcome` resource in JSON format 361 | 362 | --- 363 | #### Bulk Data Status Request 364 | 365 | After a Bulk Data request has been started, the client MAY poll the status URL provided in the `Content-Location` header as described in the [FHIR Asynchronous Request Pattern](https://www.hl7.org/fhir/R4/async.html). 366 | 367 | Clients SHOULD follow an [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) approach when polling for status. A server SHOULD supply a [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header with a with a delay time in seconds (e.g., `120` to represent two minutes) or a http-date (e.g., `Fri, 31 Dec 1999 23:59:59 GMT`). When provided, clients SHOULD use this information to inform the timing of future polling requests. The server SHOULD keep an accounting of status queries received from a given client, and if a client is polling too frequently, the server SHOULD respond with a `429 Too Many Requests` status code in addition to a `Retry-After` header, and optionally a FHIR `OperationOutcome` resource with further explanation. If excessively frequent status queries persist, the server MAY return a `429 Too Many Requests` status code and terminate the session. Other standard HTTP `4XX` as well as `5XX` status codes may be used to identify errors as mentioned. 368 | 369 | When requesting status, the client SHOULD use an `Accept` header indicating a content type of `application/json`. In the case that errors prevent the export from completing, the server SHOULD respond with a FHIR `OperationOutcome` resource in JSON format. 370 | 371 | ##### Endpoint 372 | 373 | `GET [polling content location]` 374 | 375 | **Responses** 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 390 | 391 | 392 | 393 | 394 | 410 | 411 | 412 | 413 | 414 | 442 | 443 | 444 |
Response TypeDescriptionExample Response Headers + Body
In-ProgressReturned by the server while it is processing the $export request.
Status: 202 Accepted
388 | X-Progress: “50% complete”
389 | Retry-After: 120
ErrorReturned by the server if the export operation fails.
Status: 500 Internal Server Error
395 | Content-Type: application/fhir+json
396 | 
397 | {
398 |  "resourceType": "OperationOutcome",
399 |  "id": "1",
400 |  "issue": [
401 |   {
402 |    "severity": "error",
403 |    "code": "processing",
404 |    "details": {
405 |     "text": "An internal timeout has occurred"
406 |    }
407 |   }
408 |  ]
409 | }
CompleteReturned by the server when the export operation has completed.
Status: 200 OK
415 | Expires: Mon, 22 Jul 2019 23:59:59 GMT
416 | Content-Type: application/json
417 | 
418 | {
419 |  "transactionTime": "2021-01-01T00:00:00Z",
420 |  "request" : "https://example.com/fhir/Patient/$export?_type=Patient,Observation",
421 |  "requiresAccessToken" : true,
422 |  "output" : [{
423 |   "type" : "Patient",
424 |   "url" : "https://example.com/output/patient_file_1.ndjson"
425 |  },{
426 |   "type" : "Patient",
427 |   "url" : "https://example.com/output/observation_file_1.ndjson"
428 |  },{
429 |   "type" : "Observation",
430 |   "url" : "https://example.com/output/observation_file_2.ndjson"
431 |  }],
432 |  "deleted" : [{
433 |   "type" : "Bundle",
434 |   "url" : "https://example.com/output/del_file_1.ndjson"
435 |  }],
436 |  "error" : [{
437 |   "type" : "OperationOutcome",
438 |   "url" : "https://example.com/output/err_file_1.ndjson"
439 |  }],
440 |  "extension":{"https://example.com/extra-property": true}
441 | }
445 | 446 | ##### Response - In-Progress Status 447 | 448 | - HTTP Status Code of `202 Accepted` 449 | - Optionally, the server MAY return an `X-Progress` header with a text description of the status of the request that is less than 100 characters. The format of this description is at the server's discretion and MAY be a percentage complete value, or MAY be a more general status such as "in progress". The client MAY parse the description, display it to the user, or log it. 450 | - When the `allowPartialManifests` kickoff parameter is `true`, the server MAY return a `Content-Type` header of `application/json` and a body containing an output manifest in the format [described below](#response---output-manifest), populated with a partial set of output files for the export. When provided, a manifest SHALL only contain files that are available for retrieval by the client. Once returned, the server SHALL NOT alter a manifest when it is returned in subsequent requests, with the exception of optionally adding a `link` field pointing to a manifest with additional output files or updating output file URLs that have expired. The output files referenced in the manifest SHALL NOT be altered once they have been included in a manifest that has been returned to a client. 451 | 452 | ##### Response - Error Status 453 | 454 | - HTTP status code of `4XX` or `5XX` 455 | - `Content-Type` header of `application/fhir+json` when body is a FHIR `OperationOutcome` resource 456 | - The body of the response SHOULD be a FHIR `OperationOutcome` resource in JSON format. If this is not possible (for example, the infrastructure layer returning the error is not FHIR aware), the server MAY return an error message in another format and include a corresponding value for the `Content-Type` header. 457 | 458 | In the case of a polling failure that does not indicate failure of the export job, a server SHOULD use a [transient code](https://www.hl7.org/fhir/codesystem-issue-type.html#issue-type-transient) from the [IssueType valueset](https://www.hl7.org/fhir/codesystem-issue-type.html) when populating the FHIR `OperationOutcome` resource's `issue.code` element to indicate to the client that it should retry the request at a later time. 459 | 460 | *Note*: Even if some of the requested resources cannot successfully be exported, the overall export operation MAY still succeed. In this case, the `Response.error` array of the completion response body SHALL be populated with one or more files in ndjson format containing FHIR `OperationOutcome` resources to indicate what went wrong (see below). In the case of a partial success, the server SHALL use a `200` status code instead of `4XX` or `5XX`. The choice of when to determine that an export job has failed in its entirety (error status) vs. returning a partial success (complete status) is left up to the server implementer. 461 | 462 | ##### Response - Complete Status 463 | 464 | - HTTP status of `200 OK` 465 | - `Content-Type` header of `application/json` 466 | - The server SHOULD return an `Expires` header indicating when the files listed will no longer be available for access. 467 | - A body containing the output manifest described below. 468 | 469 | ##### Response - Output Manifest 470 | 471 | The output manifest is a JSON object providing metadata and links to the generated Bulk Data files. The files SHALL be accessible to the client at the URLs advertised. These URLs MAY be served by file servers other than a FHIR-specific server. 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 530 | 531 | 532 | 533 | 534 | 535 | 556 | 557 | 558 | 559 | 560 | 561 | 568 | 569 | 570 | 571 | 572 | 573 | 578 | 579 | 580 | 581 | 582 | 583 | 588 | 589 | 590 |
FieldOptionalityTypeDescription
transactionTimerequiredFHIR instantIndicates the server's time when the query is run. The response SHOULD NOT include any resources modified after this instant, and SHALL include any matching resources modified up to and including this instant. 486 |
487 |
488 | Note: To properly meet these constraints, a FHIR server might need to wait for any pending transactions to resolve in its database before starting the export process. 489 |
requestrequiredStringThe full URL of the original Bulk Data kick-off request. In the case of a POST request, this URL will not include the request parameters. Note: this field may be removed in a future version of this IG.
requiresAccessTokenrequiredBooleanIndicates whether downloading the generated files requires the same authorization mechanism as the $export operation itself. 502 |
503 |
504 | Value SHALL be true if both the file server and the FHIR API server control access using OAuth 2.0 bearer tokens. Value MAY be false for file servers that use access-control schemes other than OAuth 2.0, such as downloads from Amazon S3 bucket URLs or verifiable file servers within an organization's firewall. 505 |
outputOrganizedByrequired when organizeOutputBy was populatedStringThe organizeOutputBy value from the Bulk Data kick-off request when populated and supported.
outputrequiredJSON arrayAn array of file items with one entry for each generated file. If no resources are returned from the kick-off request, the server SHOULD return an empty array. 518 |
519 |
520 | The url field SHALL be populated for each output item. When a resource type is not specified in the organizeOutputBy kick-off parameter, the type field SHALL also be populated for each item. When a resource type is specified in the organizeOutputBy kick-off parameter and resources related to a resource of this type continue into another output file, the continuesInFile field SHALL be populated with the URL of that output file. 521 |
522 |
523 |
    524 |
  • type - the FHIR resource type that is contained in the file.
  • 525 |
  • url - the absolute path to the file. The format of the file SHOULD reflect that requested in the _outputFormat parameter of the initial kick-off request.
  • 526 |
  • continuesInFile - url of the output file when resources associated with a FHIR resource of the type specified in the organizeOutputBy kick-off parameter in this file continue into another file. See details below.
  • 527 |
  • count (optional) - the number of resources in the file, represented as a JSON number.
  • 528 |
529 |
deletedoptionalJSON arrayAn array of deleted file items following the same structure as the output array. 536 |
537 |
538 | The ability to convey deleted resources is important in cases when a server may have previously exported data and wishes to indicate that these data should be removed from downstream systems. When a _since timestamp is supplied in the export request, this array SHOULD be populated with output files containing FHIR Transaction Bundles that indicate which FHIR resources match the kick-off request criteria, but have been deleted subsequent to the _since date. If no resources have been deleted, or the _since parameter was not supplied, or the server has other reasons to avoid exposing these data, the server MAY omit this key or MAY return an empty array. Resources that appear in the 'deleted' section of an export manifest SHALL NOT appear in the 'output' section of the manifest. 539 |
540 |
541 | Each line in the output file SHALL contain a FHIR Bundle with a type of transaction which SHALL contain one or more entry items that reflect a deleted resource. In each entry, the request.url and request.method elements SHALL be populated. The request.method element SHALL be set to DELETE. 542 |
543 |
544 | Example deleted resource bundle (represents one line in output file): 545 |
{
546 |  "resourceType": "Bundle",
547 |  "id": "bundle-transaction",
548 |  "meta": {"lastUpdated: "2020-04-27T02:56:00Z},
549 |  "type": "transaction",
550 |  "entry":[{
551 |   "request": {"method": "DELETE", "url": "Patient/123"}
552 |   ...
553 |  }]
554 | }
555 |
errorrequiredArrayArray of message file items following the same structure as the output array. 562 |
563 |
564 | Error, warning, and information messages related to the export SHOULD be included here (not in output). If there are no relevant messages, the server SHOULD return an empty array. Only the FHIR OperationOutcome resource type is currently supported, so the server SHALL generate files in the same format as Bulk Data output files that contain FHIR OperationOutcome resources.

565 | If the request contained invalid or unsupported parameters along with a Prefer: handling=lenient header and the server processed the request, the server SHOULD include a FHIR OperationOutcome resource for each of these parameters. 566 |

Note: this field may be renamed in a future version of this IG to reflect the inclusion of FHIR OperationOutcome resources with severity levels other than error. 567 |
linkoptionalJSON array 574 | When the allowPartialManifests kickoff parameter is true, the manifest MAY include a link array with a single object containing a relation field with a value of next, and a url field pointing to the location of another manifest. All fields in the linked manifest SHALL be populated with the same values as the manifest with the link, apart from the output, deleted and link arrays. 575 |

576 | In response to a request to a next link, a server MAY return an error as described Error Status section above. For non-transient errors, a client MAY process resources that have already retrieved prior to re-running the export job or MAY discard them. 577 |
extensionoptionalJSON objectTo support extensions, this implementation guide reserves the name extension and will never define a field with that name, allowing server implementations to use it to provide custom behavior and information. For example, a server may choose to provide a custom extension that contains a decryption key for encrypted ndjson files. The value of an extension element SHALL be a pre-coordinated JSON object. 584 |
585 |
586 | Note: In addition to extensions being supported on the root object level, extensions may also be included within the fields above (e.g., in the 'output' object). 587 |
591 | 592 | Example manifest, `organizeOutputBy` kickoff parameter is not populated: 593 | 594 | ```json 595 | { 596 | "transactionTime": "2021-01-01T00:00:00Z", 597 | "request" : "https://example.com/fhir/Patient/$export?_type=Patient,Observation", 598 | "requiresAccessToken" : true, 599 | "output" : [{ 600 | "type" : "Patient", 601 | "url" : "https://example.com/output/patient_file_1.ndjson" 602 | },{ 603 | "type" : "Observation", 604 | "url" : "https://example.com/output/observation_file_1.ndjson" 605 | },{ 606 | "type" : "Observation", 607 | "url" : "https://example.com/output/observation_file_2.ndjson" 608 | }], 609 | "deleted": [{ 610 | "type" : "Bundle", 611 | "url" : "https://example.com/output/del_file_1.ndjson" 612 | }], 613 | "error" : [{ 614 | "type" : "OperationOutcome", 615 | "url" : "https://example.com/output/err_file_1.ndjson" 616 | }], 617 | "extension":{"https://example.com/extra-property": true} 618 | } 619 | ``` 620 | 621 | Example manifest, `organizeOutputBy` kickoff parameter is `Patient`, and `allowPartialManifests` kickoff parameter is `true`: 622 | 623 | ```json 624 | { 625 | "transactionTime": "2021-01-01T00:00:00Z", 626 | "request" : "https://example.com/fhir/Patient/$export?_type=Patient,Observation", 627 | "requiresAccessToken" : true, 628 | "outputOrganizedBy": "Patient", 629 | "output" : [{ 630 | "url" : "https://example.com/output/file_1.ndjson" 631 | },{ 632 | "url" : "https://example.com/output/file_2.ndjson", 633 | "continuesInFile": "https://example.com/output/file_3.ndjson" 634 | },{ 635 | "url" : "https://example.com/output/file_3.ndjson" 636 | }], 637 | "deleted": [{ 638 | "type" : "Bundle", 639 | "url" : "https://example.com/output/del_file_1.ndjson" 640 | }], 641 | "error" : [{ 642 | "type" : "OperationOutcome", 643 | "url" : "https://example.com/output/err_file_1.ndjson" 644 | }], 645 | "extension":{"https://example.com/extra-property": true}, 646 | "link": [{ 647 | "relation": "next", 648 | "url": "https://example.com/output/manifest-2.json" 649 | }] 650 | } 651 | ``` 652 | 653 | --- 654 | #### Bulk Data Output File Organization 655 | 656 | Output files may be organized by resource type, or by instances of a resource type specified in the `organizeOutputBy` kickoff parameter. 657 | 658 | When the `organizeOutputBy` kickoff parameter is not populated, each output file SHALL contain resources of only one type, and a server MAY create more than one file for each resource type returned. The number of resources contained in a file MAY vary between servers and files. 659 | 660 | When the `organizeOutputBy` kickoff parameter is populated with a resource type, the output files SHALL be populated with blocks consisting of a header `Parameters` resource containing a parameter named `header` with a reference to a resource of the type in the kickoff parameter, followed by the resource referenced in this header and resources that reference the resource referenced in the header (together a "resource block"). Each output file MAY contain multiple resource blocks and, when possible, a single resource's block SHOULD NOT be split across files. If a resource block does span more than one file, the header SHALL be repeated at the start of each file where the block continues, and the association between these files SHALL be documented in the manifest using the `continuesInFile` field in the relevant `output` array items. 661 | 662 | Resources that would otherwise be included in the export, but do not have references to the resource type specified in the `organizeOutputBy` parameter, MAY be included in a resource blocks that contain resources they reference, MAY be repeated in every resource block, or MAY be omitted from the export. 663 | 664 |
665 | When the organizeOutputBy parameter is set Patient, servers SHOULD use the Patient Compartment Definition to determine a base set of related resources to include in a resource block, though other resources may also be included. 666 | 667 | For other resource types, we are soliciting feedback on the best approach for documenting the set of resources in a resource block. Implementation Guides MAY reference a Compartment Definition, populate a GraphDefinition Resource, include narrative text, or use another approach. 668 |
669 | 670 | Example header for `Patient` resource: 671 | ```json 672 | { 673 | "resourceType" : "Parameters", 674 | "parameter" : [{ 675 | "name": "header", 676 | "valueReference": {"reference": "Patient/123"} 677 | }] 678 | } 679 | ``` 680 | 681 | #### Bulk Data Output File Request 682 | 683 | Using the URLs supplied by the FHIR server in the manifest, a client MAY download the generated Bulk Data files (one or more per resource type) within the time period specified in the `Expires` header (if present). A client MAY re-fetch the output manifest if output links have expired, and a server MAY provide updated links and/or an updated timestamp in the `Expires` header in the response. 684 | 685 | As long as a server is following relevant security guidance, it MAY generate output manifests where the `requiresAccessToken` field is `true` or `false`; this applies even for servers available on the public internet. 686 | 687 | If the `requiresAccessToken` field in the manifest is set to `true`, the request SHALL include a valid access token. See [Privacy and Security Considerations](#privacy-and-security-considerations) above. 688 | 689 | If the `requiresAccessToken` field is set to `false` and no additional authorization-related extensions are present in the manifest's output entry, then the output URLs SHALL be dereferenceable directly (a "capability URL"), and SHALL follow expiration timing requirement that have been documented for bearer tokens in SMART Backend Services. A client SHALL NOT provide a SMART Backend Services access token when dereferencing an output URL where `requiresAccessToken` is `false`. 690 | 691 | The exported data SHALL include only the most recent version of any exported resources unless the client explicitly requests different behavior in a fashion supported by the server (e.g., via a new query parameter yet to be defined). Inclusion of the `Resource.meta` information in the resources is at the discretion of the server (as it is for all FHIR interactions). 692 | 693 | A client SHOULD provide an `Accept-Encoding` header when requesting output files and SHOULD include `gzip` compression as one of the encoding options in the header. A server SHALL provide output files as uncompressed, with `gzip` compression, or with another compression format from the `Accept-Encoding` header. When compression is used, a server SHALL communicate this to the client by including a `Content-Encoding` header in the response. A client SHALL accept files that are uncompressed or encoded with `gzip` compression, and MAY accept files encoded with other compression formats. 694 | 695 | Example NDJSON output file: 696 | ``` 697 | {"id":"5c41cecf-cf81-434f-9da7-e24e5a99dbc2","name":[{"given":["Brenda"],"family":["Jackson"]}],"gender":"female","birthDate":"1956-10-14T00:00:00.000Z","resourceType":"Patient"} 698 | {"id":"3fabcb98-0995-447d-a03f-314d202b32f4","name":[{"given":["Bram"],"family":["Sandeep"]}],"gender":"male","birthDate":"1994-11-01T00:00:00.000Z","resourceType":"Patient"} 699 | {"id":"945e5c7f-504b-43bd-9562-a2ef82c244b2","name":[{"given":["Sandy"],"family":["Hamlin"]}],"gender":"female","birthDate":"1988-01-24T00:00:00.000Z","resourceType":"Patient"} 700 | ``` 701 | 702 | ##### Endpoint 703 | 704 | `GET [url from status request output field]` 705 | 706 | ##### Headers 707 | 708 | - `Accept` (optional, defaults to `application/fhir+ndjson`) 709 | 710 | Specifies the format of the file being requested. 711 | 712 | ##### Response - Success 713 | 714 | - HTTP status of `200 OK` 715 | - `Content-Type` header that matches the file format being delivered. For files in ndjson format, SHALL be `application/fhir+ndjson` 716 | - Body of FHIR resources in newline delimited json - [ndjson](http://ndjson.org/) or other requested format 717 | 718 | ##### Response - Error 719 | 720 | - HTTP Status Code of `4XX` or `5XX` 721 | 722 | ##### Attachments 723 | 724 | If resources in an output file contain elements of the type `Attachment`, the server SHOULD populate the `Attachment.contentType` code as well as either the `data` element or the `url` element. When populated, the `url` element SHALL be an absolute url that can be de-referenced to the attachment's content. 725 | 726 | When the `url` element is populated with an absolute URL and the `requiresAccessToken` field in the Complete Status body is set to `true`, the url location must be accessible by a client with a valid access token, and SHALL NOT require the use of additional authentication credentials. When the `url` element is populated and the `requiresAccessToken` field in the Complete Status body is set to `false`, the url location must be accessible by a client without an access token. 727 | 728 | Note that if a server copies files to the Bulk Data output endpoint or proxies requests to facilitate access from this endpoint, it may need to modify the `Attachment.url` element when generating the Bulk Data output files. 729 | 730 | ### Server Capability Documentation 731 | 732 | This implementation guide is structured to support a wide variety of Bulk Data Export use cases and server architectures. To provide clarity to developers on which capabilities are implemented in a particular server, server providers SHALL ensure that their Capability Statement accurately reflects the implemented Bulk Data Operations. Additionally, the server's Capability Statement SHOULD list the resource types available for export in the `rest.resource` element, and SHOULD list the search parameters that can be used in the `_typeFilter` parameter in `rest.resource.searchParam` elements. 733 | 734 | Servers SHOULD indicate resource types and search parameters that are accessible on the server with the REST API, but not available using the Bulk Export operation, with one or more extensions that have a URL of `http://hl7.org/fhir/uv/bulkdata/Extension/operation-not-supported` and a `valueCanonical` with the canonical URL for the [OperationDefinition](artifacts.html#behavior-operation-definitions) of the bulk operation that is not supported. Alternatively, the extension may be populated with the canonical URL for the FHIR Bulk Data Access Implementation Guide [CapabilityStatement](artifacts.html#behavior-capability-statements) when none of the bulk operations are supported. 735 | 736 | Server providers SHOULD also ensure that their documentation addresses the topics below. Future versions of this IG may define a computable format for this information as well. 737 | 738 | - Does the server restrict responses to a specific profile like the [US Core Implementation Guide](http://www.hl7.org/fhir/us/core/) or the [Blue Button Implementation Guide](http://hl7.org/fhir/us/carin-bb/)? 739 | - What approach does the server take to divide datasets into multiple files (e.g., single file per single resource type, limit file size to 100MB, limit number of resources per file to 100,000)? 740 | - Are additional supporting resources such as `Practitioner` or `Organization` included in the export and under what circumstances? 741 | - Does the server support system-wide (or all-patients, or Group-level) export? What parameters are supported for each request type? Note that this should also be captured in the server's CapabilityStatement. 742 | - What `outputFormat` values does this server support? 743 | - In the case of a Group level export, does the `_since` parameter return additional resources modified prior to the supplied time if the resources belong to the patient compartment of a patient added to the Group after the supplied time? 744 | - What `includeAssociatedData` values does this server support? 745 | -------------------------------------------------------------------------------- /input/pagecontent/group.md: -------------------------------------------------------------------------------- 1 | ### Bulk Exporting Data for a Group 2 | 3 | The [Group Level Bulk Export Operation](export.html#endpoint---group-of-patients) scopes the data returned in an export to the population defined by a FHIR Group resource on the server. Depending on the capabilities exposed by the server, a client may be able to retrieve a list of the Group resources it has access to, search for Group resource based on their attributes, read the contents of individual Group resources, and perform other FHIR operations such as creating new Groups, adding and removing members from a Group, or deleting previously created Group resources. 4 | 5 | ### Group Types 6 | 7 | When considering Bulk Export use cases, the community has identified three common patterns of group related server capabilities. A server may support one or more of these patterns. 8 | 9 | 1. Read-only groups: Cohorts of patients are managed entirely by the server and are exposed to the client as a set of Group FHIR ids for use in a Bulk Export operation. The server may also provide an API to view, list, and/or search for Group resources on the server, but does not offer clients the ability to create, update or delete Group resources. Examples include a roster provided by a payer organization to a provider organization using negotiated data from another system and a list of patients configured using a registry tool in an EHR system. 10 | 11 | 2. Member based groups: Cohorts are managed by the client by specifying individual members using a FHIR API with the ability to add and remove members in Group resources, and/or as create and delete Group resources themselves. Depending on the server capabilities exposed, a client may add members based on their FHIR ids or using characteristics such as a subscriber number. Adding Group resources or adding patients to a group may trigger automated or manual approval workflows on the server. Examples include a patient roster managed using the [DaVinci ATR API](https://hl7.org/fhir/us/davinci-atr/) or a Group created with using member FHIR ids located using the FHIR [patient match operation](https://hl7.org/fhir/patient-operation-match.html). 12 | 13 | 3. Criteria based groups: Cohorts of patients on the server are managed by the client with a FHIR API that includes the ability to define Group resources based on a set of patient characteristics. These characteristics are then used by the server to associate members with the group. Examples would be a client that uses a FHIR API to create a cohort of patients who are assigned to a specific practitioner, or a cohort of patients with a problem list condition of diabetes and a visit in the past month. A group may represent a subset of another "read-only group" or "member based group", and could be point in time snapshot based on membership at the time of creation or dynamically update as new patients meet the specified criteria. The Bulk Cohort API described below represents one approach to defining criteria based groups. 14 | 15 | ### Bulk Cohort API 16 | 17 | Servers supporting the Bulk Data Access IG MAY support the Bulk Cohort API which consists of an asynchronous Group creation REST interaction and a profile on the Group resource. The intent is to support the creation of characteristic based cohorts using coarse-grained filters to more efficiently export data on sets of patients from a source system. Post export, the client can use the FHIR resources returned for these cohorts for finer grained filtering to support use cases such as measure calculation or analytics that may necessitate more complex filter criteria. 18 | 19 | #### REST Interactions 20 | 21 | When the Bulk Cohort API is supported, the server SHALL accept FHIR Group create requests that use the [FHIR Asynchronous Interaction Request](https://hl7.org/fhir/async-bundle.html) pattern and provide a valid FHIR Group resource that complies with the [Bulk Cohort Group Profile](#group-profile). Servers MAY also accept synchronous FHIR Group create requests, but since not all servers can create groups in this way (for example, some systems require a manual group approval step), clients should not expect this to be universally available. After group creation, a server MAY subsequently make the new Group resource available to authorized clients or MAY reject resource creation request and returning a relevant error. Servers SHOULD support read, search, delete, and Bulk Export operations on created Group resources, and SHOULD support the `name` search parameter in search requests for these resources. Servers MAY support other FHIR REST API operations and other search parameters. 22 | 23 | Servers MAY support Group update requests. When update requests are supported, servers SHALL accept update requests that use the [FHIR Asynchronous Interaction Request](https://hl7.org/fhir/async-bundle.html) pattern and MAY accept synchronous update requests. 24 | 25 | #### Group Profile 26 | 27 | **[Full Bulk Cohort Profile](StructureDefinition-bulk-cohort-group.html)** 28 | 29 | 30 | ##### Key Elements 31 | 32 | {% sqlToData elements 33 | WITH elements AS ( 34 | SELECT 35 | element.parent, 36 | MAX(CASE WHEN element.key = 'id' THEN atom END) AS el_id, 37 | MAX(CASE WHEN element.key = 'definition' THEN atom END) AS el_def, 38 | MAX(CASE WHEN element.key = 'path' THEN atom END) AS el_path, 39 | MAX(CASE WHEN element.key = 'min' THEN atom END) AS el_min, 40 | MAX(CASE WHEN element.key = 'max' THEN atom END) AS el_max 41 | FROM Resources, 42 | json_tree(Resources.Json, '$.snapshot.element') AS element 43 | WHERE Resources.Id = 'bulk-cohort-group' 44 | GROUP BY 1 45 | ) 46 | SELECT *, 47 | el_min || '..' || el_max AS cardinality 48 | FROM elements 49 | %} 50 | 51 | {% assign element = elements | find: 'el_id', 'Group.member' %} 52 | {{ '
member (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 53 | 54 | {% assign element = elements | find: 'el_id', 'Group.modifierExtension' %} 55 | {{ '
member-filter ModifierExtension (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 56 | 57 | {% assign element = elements | find: 'el_id', 'Group.extension' %} 58 | {{ '
members-refreshed Extension (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 59 | 60 | {% assign element = elements | find: 'el_id', 'Group.type' %} 61 | {{ '
type (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 62 | 63 | {% assign element = elements | find: 'el_id', 'Group.name' %} 64 | {{ '
name (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 65 | 66 | {% assign element = elements | find: 'el_id', 'Group.characteristic' %} 67 | {{ '
characteristic (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 68 | 69 | {% assign element = elements | find: 'el_id', 'Group.actual' %} 70 | {{ '
actual (' | append: element.cardinality | append: ')
' | append: element.el_def | markdownify }} 71 | 72 | #### Example 73 | 74 | Group with plan members filtered to patients with diabetes on their problem list and an ambulatory encounter in January 2024. 75 | 76 | {% fragment Group/BulkCohortGroupExample JSON ELIDE:id|meta|text %} 77 | 78 | [View Example](Group-BulkCohortGroupExample.json.html) 79 | 80 | ### Server Capability Documentation 81 | To provide clarity to developers on which capabilities are implemented in a particular server, server providers SHALL ensure that their Capability Statement accurately reflects the Bulk Cohort profile as a `rest.resource.supportedProfile` of Group. Server providers SHOULD also ensure that their documentation addresses when and how often are Bulk Cohort group membership is updated and which search parameters are supported in `member-filter` expressions. 82 | -------------------------------------------------------------------------------- /input/pagecontent/index.md: -------------------------------------------------------------------------------- 1 | Providers and organizations accountable for managing the health of populations often need to efficiently access large volumes of information on a group of individuals. For example, a health system may want to periodically retrieve updated clinical data from an EHR to a research database, a provider may want to send clinical data on a roster of patients to their ACO to calculate quality measures, or an EHR may want to display claims data to help close gaps in care. The data exchange often involves extracting a specific subset of fields from the source system, mapping the fields into a structured file format like CSV, and persisting the files in a server from which the requester can then download them into the target system. This multi-step process increases the cost of integration projects and can act as a counter-incentive to data liquidity. 2 | 3 | Existing FHIR APIs work well for accessing small amounts of data, but large exports can require hundreds of thousands of requests. This implementation guide defines a standardized, FHIR based approach for exporting bulk data from a FHIR server to a pre-authorized client. 4 | 5 | ### Conformance 6 | To declare conformance with this IG, a server should include the following URL in its `CapabilityStatement.instantiates`: `http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data` 7 | 8 | 9 | ### Use Cases 10 | 11 | This implementation guide is designed to support sharing any data that can be represented in FHIR. This means that the IG should be useful for such diverse systems as: 12 | 13 | * "Native" FHIR servers that store FHIR resources directly 14 | * EHR systems and population health tools implementing FHIR as an interoperability layer 15 | * Financial systems implementing FHIR as an interoperability layer 16 | 17 | #### US Core Data for Interoperability 18 | *Applies to: EHR systems that support the US Core Data for Interoperability.* 19 | 20 | This use case exports all resources needed for the [US Core Data for Interoperability](https://www.healthit.gov/isa/united-states-core-data-interoperability-uscdi), as profiled by the [HL7 Argonaut FHIR Accelerator](https://confluence.hl7.org/display/AP/Argonaut+Project+Home). For a full list of these resources and profiles, see [http://www.hl7.org/fhir/us/core/](http://www.hl7.org/fhir/us/core/). 21 | 22 | #### Common Financial Data Set 23 | *Applies to: Financial systems that support FHIR-based interoperability.* 24 | 25 | This use case exports all resources needed to convey a patient's healthcare financial history, including Patient, ExplanationOfBenefit, Coverage, and Claim. While FHIR profiles are still being developed and standardized, see [https://bluebutton.cms.gov/developers/#core-resources](https://bluebutton.cms.gov/developers/#core-resources) for a full-fledged example. 26 | 27 | #### Additional Use Cases 28 | * Terminology data - export CodeSystem and ValueSet resources from a terminology server 29 | * Provider data - export a system's Practitioner, Location, and Organization lists 30 | * Public health surveillance that does not require real-time exchange of data, such as aggregate situational awareness data reporting 31 | * Electronic Case Reporting (data from initial export may be filtered or summarized before submitting) 32 | 33 | ### Additional Documentation 34 | * [Overview Presentation](https://docs.google.com/presentation/d/14ZHmam9hwz6-SsCG1YqUIQnJ56bvSqEatebltgEVR6c/edit?usp=sharing) 35 | * [Discussion Group (FHIR Zulip "Bulk Data" Track)](https://chat.fhir.org/#narrow/stream/bulk.20data) 36 | * [Argonaut Project: Bulk Data Export Security Risk Assessment Report](security-risk-assessment-report.pdf) 37 | * [Implementation Guide Change Log](changes.html) -------------------------------------------------------------------------------- /package-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "package-id" : "hl7.fhir.uv.bulkdata", 3 | "title" : "FHIR Bulk Data Access (Flat FHIR)", 4 | "canonical" : "http://hl7.org/fhir/uv/bulkdata", 5 | "category": "EHR Access", 6 | "list" : [{ 7 | "version" : "current", 8 | "date" : "n/a", 9 | "desc" : "Continuous Integration Build (latest in version control)", 10 | "path" : "http://build.fhir.org/ig/HL7/bulk-data", 11 | "status" : "ci-build" 12 | },{ 13 | "version": "2.0.0", 14 | "date": "2021-10-30", 15 | "desc": "STU 2 Publcation", 16 | "changes": "/changes.html", 17 | "path": "http://hl7.org/fhir/uv/bulkdata/STU2", 18 | "sequence": "STU 2", 19 | "fhirversion": "4.0.1", 20 | "status": "trial-use", 21 | "current": true 22 | },{ 23 | "version": "1.1.0", 24 | "date": "2021-04-16", 25 | "desc": "STU 2 Ballot #1", 26 | "changes": "http://hl7.org/fhir/uv/bulkdata/2021May/changes.html", 27 | "path": "http://hl7.org/fhir/uv/bulkdata/2021May", 28 | "sequence": "STU 2 (FHIR R4)", 29 | "fhirversion": "4.0.1", 30 | "status": "ballot" 31 | },{ 32 | "version": "1.0.1", 33 | "date": "2020-11-06", 34 | "desc": "STU 1 with technical errata comprising the following changes:\n* Updated the CapabilityStatement to move the Patient and Group level export operations from the 'rest.operation' element to 'rest.resource.operation' elements and correct the OperationDefinition URLs\n* Corrected conformance URL\n* Added note on export complete status extension field description to clarify that extensions may be placed under to any field in the export complete status response and not just at the root level of the response", 35 | "path": "http://hl7.org/fhir/uv/bulkdata/STU1", 36 | "sequence": "STU 1 + Technical Correction (FHIR R4)", 37 | "fhirversion": "4.0.1", 38 | "status": "trial-use" 39 | },{ 40 | "version": "1.0.0", 41 | "date": "2019-08-20", 42 | "desc": "STU 1", 43 | "path": "http://hl7.org/fhir/uv/bulkdata/STU1", 44 | "sequence": "STU 1 (FHIR R4)", 45 | "fhirversion": "4.0.0", 46 | "status": "trial-use" 47 | },{ 48 | "version": "0.1.0", 49 | "date": "xxx", 50 | "desc": "STU #1 1st Ballot", 51 | "path": "http://hl7.org/fhir/us/bulkdata/2019May", 52 | "status": "ballot", 53 | "sequence": "STU1" 54 | }] 55 | } 56 | -------------------------------------------------------------------------------- /smart-template/content/assets/images/smart-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HL7/bulk-data/b666e58153a2f0a18dc85bf6b9c96595f829d492/smart-template/content/assets/images/smart-logo.png -------------------------------------------------------------------------------- /smart-template/includes/_append.fragment-header.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /smart-template/includes/fragment-pageend.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% if includetabscripts %} 9 | 10 | {% endif %} 11 | 12 | 13 | 53 | 54 | 58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 72 | 73 | -------------------------------------------------------------------------------- /smart-template/package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hl7.smart.template", 3 | "version": "0.0.1", 4 | "type": "fhir.template", 5 | "license": "CC0-1.0", 6 | "description": "HL7 SMART joint Template - for use with HL7/SMART jointly published FHIR IGs", 7 | "author": "http://hl7.org/fhir", 8 | "canonical": "http://github.com/HL7/ig-template-smart", 9 | "base": "hl7.fhir.template", 10 | "dependencies": { 11 | "hl7.fhir.template": "current" 12 | } 13 | } -------------------------------------------------------------------------------- /sushi-config.yaml: -------------------------------------------------------------------------------- 1 | id: hl7.fhir.uv.bulkdata 2 | canonical: http://hl7.org/fhir/uv/bulkdata 3 | name: BulkDataAccessIG 4 | title: Bulk Data Access IG 5 | description: FHIR based approach for exporting large data sets from a FHIR server to a client application 6 | status: active 7 | version: 2.0.0 8 | fhirVersion: 4.0.1 9 | copyrightYear: 2021+ 10 | releaseLabel: ci-build # ci-build | draft | qa-preview | ballot | trial-use | release | update | normative+trial-use 11 | license: CC0-1.0 # https://www.hl7.org/fhir/valueset-spdx-license.html 12 | jurisdiction: http://unstats.un.org/unsd/methods/m49/m49.htm#001 13 | publisher: 14 | name: HL7 International / FHIR Infrastructure 15 | url: http://www.hl7.org/Special/committees/fiwg 16 | email: fhir@lists.HL7.org 17 | 18 | pages: 19 | index.md: 20 | title: Home 21 | export.md: 22 | title: Export 23 | group.md: 24 | title: Groups 25 | authorization.md: 26 | title: SMART Backend Services Authorization 27 | abbreviations.md: 28 | title: Abbreviations 29 | changes.md: 30 | title: IG Change History 31 | downloads.html: 32 | title: Downloads 33 | 34 | parameters: 35 | excludettl: true 36 | excludexml: true 37 | excludemap: true 38 | 39 | menu: 40 | Home: index.html 41 | Export: export.html 42 | Groups: group.html 43 | Authorization: authorization.html 44 | FHIR Artifacts: artifacts.html 45 | Downloads: downloads.html 46 | Abbreviations: abbreviations.html 47 | 48 | resources: 49 | CapabilityStatement/bulk-data: 50 | name: Capability Statement 51 | OperationDefinition/export: 52 | name: System Level Export Operation Definition 53 | OperationDefinition/group-export: 54 | name: Group Level Export Operation Definition 55 | OperationDefinition/patient-export: 56 | name: Patient Level Export Operation Definition 57 | ValueSet/include-associated-data: 58 | name: Include Associated Data Value Set 59 | CodeSystem/include-associated-data: 60 | name: Include Associated Data Code System 61 | 62 | extension: 63 | - url: http://hl7.org/fhir/StructureDefinition/structuredefinition-wg 64 | valueCode: fhir 65 | - url: http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status 66 | valueCode: trial-use --------------------------------------------------------------------------------