Connecting to External FHIR Servers | Medplum
On this page
When building an application, you many need to query or write data to an external FHIR server as part of your application's workflow. For example:
- When a new patient is created, see if that patient already exists in another server
- When an encounter is finalized, synchronize the encounter documentation to another FHIR server
- On a bi-weekly basis, pull new FHIR data from a partner using a Bulk FHIR API
To enable these scenarios, you will need a clientId or clientSecret to access the system you want to connect to. Please note that different systems have different levels of functionality, and so the commands in the CLI are not guaranteed to work.
The examples below use the CLI optional flags.
Setting up your credentials [](/content/docs/cli/external-fhir-servers#setting-up-your-credentials "Direct link to Setting up your credentials"/index.html)
Medplum CLI stores credentials to be used in a future period without needing it to be entered in every command. By using the profile command, this helps with the ability to work with multiple FHIR servers.
Setting a Profile [](/content/docs/cli/external-fhir-servers#setting-a-profile "Direct link to Setting a Profile"/index.html)
In this example, we will set up a profile using medplum profile set <profileName> with the flags below:
- --auth-type
- --client-id
- --client-secret
- --base-url
- --token-url
- --authorize-url
- --fhir-url-path
Syntax [](/content/docs/cli/external-fhir-servers#syntax "Direct link to Syntax"/index.html)
medplum profile set <profileName> \
--auth-type <auth-type> \
--base-url <base-url> \
--fhir-url-path <fhir-url-path> \
--token-url <token-url> \
--client-id <client-id> \
--client-secret <client-secret>
| Accepted Auth Type |
|---|
| basic |
| client-credentials |
| authorization-code |
| jwt-bearer |
The profile will now be stored in a file directory in ~.medplum/<profileName>.json
Once you have a profile, you can connect with external FHIR servers with your profile using the -p flag.
Example: Basic Auth [](/content/docs/cli/external-fhir-servers#example-basic-auth "Direct link to Example: Basic Auth"/index.html)
medplum profile set example \
--auth-type "basic" \
--base-url "https://api.example.com" \
--fhir-url-path "fhir/R4" \
--client-id "MY_CLIENT_ID" \
--client-secret "MY_CLIENT_SECRET"
Example: JWT Bearer [](/content/docs/cli/external-fhir-servers#example-jwt-bearer "Direct link to Example: JWT Bearer"/index.html)
medplum profile set example \
--auth-type "jwt-bearer" \
--base-url "https://api.example.com" \
--fhir-url-path "fhir/R4" \
--token-url "/oauth2/token" \
--client-id "MY_CLIENT_ID" \
--client-secret "MY_CLIENT_SECRET" \
--scope "openid profile" \
--audience "/oauth2/token" \
--subject "john_doe" \
--issuer "api.example.com"
Example: JWT Assertion [](/content/docs/cli/external-fhir-servers#example-jwt-assertion "Direct link to Example: JWT Assertion"/index.html)
medplum profile set example \
--auth-type "jwt-assertion" \
--base-url "https://api.example.com" \
--fhir-url-path "fhir/R4" \
--token-url "/oauth2/token" \
--client-id "MY_CLIENT_ID" \
--audience "/oauth2/token" \
--subject "john_doe" \
--private-key-path "/path/to/privatekey.pem"
Example: Client Credentials [](/content/docs/cli/external-fhir-servers#example-client-credentials "Direct link to Example: Client Credentials"/index.html)
medplum profile set example \
--auth-type "client-credentials" \
--base-url "https://api.example.com" \
--fhir-url-path "fhir/R4" \
--token-url "oauth2/token" \
--client-id "MY_CLIENT_ID" \
--client-secret "MY_CLIENT_SECRET"
Example: User Login / Authorization Code [](/content/docs/cli/external-fhir-servers#example-user-login--authorization-code "Direct link to Example: User Login / Authorization Code"/index.html)
medplum profile set example \
--base-url "https://api.example.com" \
--fhir-url-path "fhir/R4" \
--authorize-url "oauth2/authorize" \
--token-url "oauth2/token"
Other profile commands include:
describe [](/content/docs/cli/external-fhir-servers#describe "Direct link to describe"/index.html)
To see the state of your credentials in on profile
Syntax [](/content/docs/cli/external-fhir-servers#syntax-1 "Direct link to Syntax"/index.html)
medplum profile describe example
Example [](/content/docs/cli/external-fhir-servers#example "Direct link to Example"/index.html)
medplum profile describe <profileName>
remove [](/content/docs/cli/external-fhir-servers#remove "Direct link to remove"/index.html)
Removing a profile
Syntax [](/content/docs/cli/external-fhir-servers#syntax-2 "Direct link to Syntax"/index.html)
medplum profile remove <profileName>
Example [](/content/docs/cli/external-fhir-servers#example-1 "Direct link to Example"/index.html)
medplum profile remove example
list [](/content/docs/cli/external-fhir-servers#list "Direct link to list"/index.html)
To see all of your profiles
medplum profile list
After your profiles are set, you can login with your credentials and use them on future commands. To login:
medplum login --profile <profile>
For more information take a look at our CLI login
Logging in with a new Profile [](/content/docs/cli/external-fhir-servers#logging-in-with-a-new-profile "Direct link to Logging in with a new Profile"/index.html)
You can run medplum login --profile <profile> and set the same flags that profile has to set a profile and automatically login
Example: Logging in with JWT Bearer [](/content/docs/cli/external-fhir-servers#example-logging-in-with-jwt-bearer "Direct link to Example: Logging in with JWT Bearer"/index.html)
medplum login \
--profile "example" \
--auth-type "jwt-bearer" \
--base-url "https://api.example.com" \
--fhir-url-path "fhir/R4" \
--token-url "/oauth2/token" \
--client-id "MY_CLIENT_ID" \
--client-secret "MY_CLIENT_SECRET" \
--scope "openid profile" \
--audience "/oauth2/token" \
--subject "john_doe" \
--issuer "api.example.com"
note
When running medplum login --profile <profile>, all of the flags need to be set with the flags and valid data
Example: Basic search [](/content/docs/cli/external-fhir-servers#example-basic-search "Direct link to Example: Basic search"/index.html)
In this example, we will show how to search for a patient by identifier using the command line after a profile has been set.
medplum get -p <profileName> 'Patient?identifier:contains=3SH0A00AA00'
Example: Create encounter [](/content/docs/cli/external-fhir-servers#example-create-encounter "Direct link to Example: Create encounter"/index.html)
In this example, an Encounter is created in another system using the command line after a profile has been set.
medplum post -p <profileName> Encounter '{"resourceType": "Encounter", "status": "finished", "class": {"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "AMB"}, "type": [{"coding": [{"system": "http://snomed.info/sct", "code": "162673000", "display": "General examination of patient (procedure)"}], "text": "General examination of patient (procedure)"}], "subject": {"reference": "Patient/13e44a47-636b-49e2-adb3-9f19c7e0e47a", "display": "Mr. Dustin31 Ritchie586"}}'
Example: Bulk FHIR Export [](/content/docs/cli/external-fhir-servers#example-bulk-fhir-export "Direct link to Example: Bulk FHIR Export"/index.html)
In this example, Bulk FHIR ndjson files are exported from the server and stored on on the local drive after a profile has been set.
medplum bulk export -p <profileName> -e Group/all
For example, CMS BCDA publishes a Bulk FHIR test server. You can store test credentials here in a profile and try the following command.
medplum profile set bcda-sandbox --base-url https://sandbox.bcda.cms.gov --fhir-url-path api/v2/ --token-url https://sandbox.bcda.cms.gov/auth/token --client-id <client-id> --client-secret <client-secret>
And then run
medplum bulk export -p bcda-sandbox -e Group/all
Next Steps [](/content/docs/cli/external-fhir-servers#next-steps "Direct link to Next Steps"/index.html)
The Medplum CLI uses Medplum TypescriptSDK to power the functionality. Once the external connection is working and you have tested some of the basic scenarios, it is recommended to build out your integration as a bot to enable your event driven or cron-based workflow.