User Authentication

All requests to the Zus API require an access token to authenticate clients. You can get an access token by following a typical OAuth 2.0 sign in flow, either integrated into your application or simulated by Postman.

More information on OAuth 2.0 can be found here.

New User Setup

Zus will provision an initial administrative user for your sandbox account. This user can create any number of additional users as needed for testing.

Authenticating with a Password

Changing your Password

When Zus or an admin from your organization creates your user account, you will receive an email with a link to reset your password. You will need to change your password and set up multi-factor authentication for your account.

10171017

Clicking the reset link will allow you to set a password that meets the Zus password policy:

422422

If your password reset link above has expired, you can request a new password reset link by navigating to any Zus application (e.g., FHIRPlace) and selecting "Forgot password?" on the login page.

Setting up Multi-Factor Authentication

We have enabled Multi-Factor Authentication has been enabled for all accounts within the sandbox environment. The first time a user authenticates, they will be presented with a QR code.

483483

Scanning the QR code in an authenticator app (eg. Google Authenticator) will add a new entry for zus-sandbox. Enter the corresponding 6 digit code in the box to continue. On any future login, the user will be prompted to enter a new 6 digit code from the authenticator app, but will no longer see the QR code. Additionally, there is a checkbox to remember your device for 30 days. Checking this will skip the one-time password prompt for the current machine for thirty days.

459459

Authenticating with SSO

You can enable your users to log into Zus applications via single sign-on (SSO) using your enterprise identity provider. Zus supports a variety of identity providers. To set up SSO with your identity provider in Zus, please complete this support ticket form, select "Request an action" for the question "What type of support ticket would you like to submit?" and specify "SSO configuration" in the free-text description.

822822

Once SSO has been enabled, users can log in by entering their email address. If the domain of the email address matches a known identity provider, the user will be authenticated using that identity provider, also known as “home realm discovery.” If there is no identity provider for the email domain, the user will be prompted for their password to log in. You can use this same SSO flow to retrieve a Zus API access token in Postman.

Authenticating for API Access

The specifics of your OAuth sign-in flow will depend on your application and platform. This section describes your primary options for signing in and getting an access token. Once you’ve obtained an access token from your OAuth sign in flow, pass this token along with each API request using the Authorization header.

Authenticating in the Zus Documentation Site

Once your Zus user account is set up, the fastest way to try out our APIs is by logging in with your Zus credentials directly. Click the "Log In" button in the top right corner of this page and follow the prompts to enter your email, password, and 6 digit code from your authenticator app used in the Authenticating with a Password section above.

417417

After you log in, you can make requests to API endpoints in our API Reference page that support the "Try It" feature. Your access token will automatically appear in the Authentication "Bearer" field in the "Try It" module for all supported endpoints. Your token will last for one hour; to get a new token, simply log in again following the same steps.

20602060

Authenticating in Postman

For more flexibility in creating and modifying your own API calls, we recommend setting up your own Zus collection in Postman. As a reminder, you must use the desktop version of Postman to call Zus APIs. Zus does not host the Postman web client and cannot guarantee the security of data it transmits.

In your Postman collection, click on the Authorization tab to set up the OAuth flow and retrieve an access token:

Configure your access token in Postman for Authorization Code with PKCE (Proof Key for Code Exchange) using the values below. Because you are using PKCE, you will not need a client secret.

FieldValue
Grant TypeAuthorization Code (With PKCE)
Callback URL<https://www.getpostman.com/oauth2/callback>
Auth URL<https://auth.sandbox.zusapi.com/authorize?audience=https://api.sandbox.zusapi.com>
Access Token URL<https://auth.sandbox.zusapi.com/oauth/token>
Client ID<provided by Zus, already included in Postman collection>
Code Challenge MethodSHA-256
Scopeopenid profile email
State<create a random alphanumeric value of 8-12 characters>
Client AuthenticationSend client credentials in body

Upon clicking on the “Get New Access Token" you will be asked to log in and authorize the PO app (PO for Postman) to have access to your open ID, profile, and email information. After accepting you will be prompted to save and use the token. See Postman’s documentation for more information on how to use tokens in API requests within Postman.

Authenticating in cURL

Your cURL commands need to include a bearer token in the authorization header in order to successfully retrieve data. Follow the steps listed above to get an access token from Postman, and then supply that token in your cURL commands.

Authenticating your Users using your Identity Provider

If you want users of your application to access Zus but without having to log in directly in Zus, and you have an OpenID Connect (OIDC)-compliant identity provider, you can exchange a user's ID Token for a Zus access token through our Token Exchange endpoint. Your user can then use the Zus access token to make authenticated requests to Zus APIs. Zus' Token Exchange endpoint is based on the new OAuth 2.0 extension.

To set up token exchange with Zus, please complete this support ticket form, select "Request an action" for the question "What type of support ticket would you like to submit?" and specify "token exchange configuration" in the free-text description. The Zus team will then reach out to you to help with the Configure Token Exchange Step below.

Prerequisites

Configure Token Exchange

To configure token exchange with your identity provider (IDP), please provide Zus with a sample user ID Token from your IDP. Zus will then extract the following information from the ID Token:

  • iss - the Issuer URL for your IDP
  • aud - the Client ID for your connection with your IDP

NOTE: The ID Token must contain the user’s email, which is used to associate the ID Token to the correct Zus user.

Create Users in Zus

Individual users making token exchange requests through your application need existing Zus user accounts. Create a Zus user with an appropriate role for each individual that your app will make a token exchange request for.

  • Make sure the user’s email matches their email in the ID Token used for token exchange, so that Zus can associate the ID Token to the correct Zus user.
  • For patient users, set the userType to “individual” and the RoleID to the ID for the “Patient” role.
  • For care team users, set the userType to “builder” and the RoleID to the ID for the “Care Team User” role.
  • You can get the ID for a given role name by making the following API call:

GET https://api.sandbox.zusapi.com/auth/roles?filter[name]={{RoleName}}

Make a Token Exchange Request

Once a Zus user account has been created, that user can exchange their external ID Token for their Zus access token. The easiest way to do this in Postman is by using the “POST Token Exchange” request in the “Auth & Permissions” folder within the Zus Health API collection.

HTTP POST request to https://api.sandbox.zusapi.com/auth/token

Headers:

  • Content-Type: application/json

Request Body (JSON):

{
    "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", 
    "audience": "https://api.sandbox.zusapi.com",
    "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
    "subject_token":"<Your ID Token here>", 
    "subject_token_type": "urn:ietf:params:oauth:token-type:id_token" 
}

Response Format (JSON):

{
    "access_token": <This is your Zus access token>,
    "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
    "Bearer": "Bearer",
    "expires_in": <seconds until token expires>
}

Make a Zus Request with your New Access Token

Once you receive the Zus access token from the Token Exchange endpoint shown above, you can use this access token to make calls to Zus APIs.

Example:

HTTP GET request to https://api.sandbox.zusapi.com/auth/users

Headers:

  • Authorization: Bearer

In Postman:
Select the Authorization tab, specify Type = OAuth 2.0, then paste your access token in under “Available Tokens.”

Implement Token Exchange in your Application

Once you have gone through the Prerequisites section above, you can execute token exchange from your external application following a similar process:

  1. Send a POST request to https://api.sandbox.zusapi.com/auth/token to retrieve an access token from Zus.

    • Include the user’s ID Token from their IDP in the token exchange request body.
  2. Include the returned Zus access token in the Authorization header to send authenticated requests to Zus APIs.

    • Zus APIs will return data if the user making the request is authorized to view the data based on the permissions associated with their Zus role (e.g., “Patient” or “Care Team User”).

Below are some application code examples to illustrate how to execute token exchange from an external application.

Python Example

In Python (Django), when a user needs a Zus access token, you can implement something similar to the following:

token_endpoint = "https://api.sandbox.zusapi.com/auth/token"
headers = {
    'Content-Type': 'application/json',
}
body = {
    "grant_type":               "urn:ietf:params:oauth:grant-type:token-exchange", 
    "audience":                 "https://api.sandbox.zusapi.com",
    "requested_token_type":     "urn:ietf:params:oauth:token-type:access_token",
    "subject_token":            id_token, # The token returned by your IDP at login
    "subject_token_type":       "urn:ietf:params:oauth:token-type:id_token", 
}

json_body = json.dumps(body) # Force Python to use Json format
zus_response = requests.post(token_endpoint, data=json_body, headers=headers)
try:
    access_token = zus_response.json()['access_token']
except:
    print("Error: ", zus_response.json())

Once you have an access token from Zus, you can then make a request to Zus with the following code:

api_url = "https://api.sandbox.zusapi.com/fhir/Patient?_count=500&_total=accurate&_offset=0"
headers = {
    'Authorization': f'Bearer {access_token}',
}
zus_data = requests.edit(api_url, headers=headers)

JavaScript Example

In JavaScript, when a user needs a Zus access token, you can implement something similar to the following:

// Set up the body for the token exchange call
let body = {
  grant_type:               "urn:ietf:params:oauth:grant-type:token-exchange", 
  audience:                 "https://api.sandbox.zusapi.com",
  requested_token_type:     "urn:ietf:params:oauth:token-type:access_token",
  subject_token:            idToken, // The token returned by your IDP at login
  subject_token_type:       "urn:ietf:params:oauth:token-type:id_token", 
};

let url = "https://api.sandbox.zusapi.com/auth/token"

// Set up an Http request that will go directly to Zus
let xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

// Triggered when the response returns
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
      // Data returned can be accessed here
      var access_token = JSON.parse(xhr.response)["access_token"]
  }};

let data = JSON.stringify(body);
xhr.send(data);

Once you have an access token from Zus, you can then make a request to Zus with the following code:

let url = "https://api.sandbox.zusapi.com/auth/roles?filter[name]=Builder Admin";
let xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.setRequestHeader("Authorization", "Bearer "+access_token);

xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
    console.log(JSON.parse(xhr.response))
}};
xhr.send();