Web Guide

πŸ“˜

Paid subscription required

Integration requires an active contract. If you don't have yet, please contact us at [email protected] for more information.

Overview

Connect is the authentication widget for your application to allow users to share their health data. After a user has successfully granted you access to their health data using Connect, you'll be able to query their disparate data directly from Human API.

1440

A user searching for their healthcare provider in Connect

Prerequisites

We are assuming that you have some familiarity with HTML and JavaScript. However, you should be able to follow along even if you’re coming from a different programming language.

You must have an active Portal account with a clientId and clientSecret. If you don't have a Portal account, go here.

Start a user session

New User

You need to start a session for your new user before launching Connect.

To start a session, issue a request to our authentication service with your client_id, a client_user_id and client_user_email. The client_user_id is the user identifier, which is any valid UTF-8 string of your choice.

Sessions guarantee the continuity of your user's experience. For instance, in the event of an abnormal termination like the browser crashing, the user can come back and resume where they left off.

Only you can start a session for your users. That's to protect you and your users from malicious "man-in-the-middle" attacks.

Let's take a look at example code that helps us create the new session request:

// This example contains a client secret in the server context. 
// DO NOT use your client secret in the browser!

// This example uses an open source request library to create requests
// You can replace it with your favorite request library
const request = require("request")

// Human API's session authentication endpoint
const authUrl = "https://auth.humanapi.co/v1/connect/token"

// Payload you send to Human API's session authentication endpoint
const requestBody = {
  client_id: "--YOUR_CLIENT_ID--",
  client_user_id: "--YOUR_UNIQUE_IDENTIFIER--",
  client_user_email: "[email protected]",
  client_secret: "--YOUR_CLIENT_SECRET--",
  type: "session"
};

// Issue a POST call to Human API's authentication service
request({
  url: authUrl,
  method: "POST",
  json: true,
  body: requestBody
}, (error, res, body) => {
  if (error) {
    throw error;
  }
  if (res.statusCode >= 400 ) {
    console.error("Server returned error status");
  }
  
  console.log(res.body)
})
POST /v1/connect/token HTTP/1.1
Host: auth.humanapi.co
Content-Type: application/json
Cache-Control: no-cache

{
  "client_id"         : "--YOUR_CLIENT_ID--",
  "client_user_id"    : "--YOUR_UNIQUE_IDENTIFIER--",
  "client_user_email" : "[email protected]",
  "client_secret"     : "--YOUR_CLIENT_SECRET--",
  "type"              : "session"
}

A successful response to the request above will look like this:

{
 "session_token": "--SESSION_TOKEN--",
 "human_id": "70a1fd8fb4935296647f340dddf7dad6",
 "expires_in": 3600 // seconds
}

The session_token is an opaque string that identifies a the user session. You should keep it and use it to launch Connect later within the expires_in time limit. The response also includes the human_id, which is Human API's unique user identifier.

🚧

humanId or human_id?

humanId and human_id refer to the same concept: they are unique user identifiers provisioned by Human API. humanId may appear in the API responses when requesting for health data; human_id appears in the Connect user authentication process, and adheres to OAuth2 conventions.

Returning User

After the session_token has already expired, an id_token must be created and used for the returning user if that user connected at least one data source. The id_token is virtually the same as the session_token in that it helps identify the user. If you try to request a new session_token after a user connected a source, our authentication service will respond with a HTTP 403 error.

To create a request for the id_token, the request body is slightly altered as follows:

const requestBody = {
  client_id: "--YOUR_CLIENT_ID--",
  client_user_id: "--YOUR_UNIQUE_IDENTIFIER--",
  client_secret: "--YOUR_CLIENT_SECRET--",
  type: "id" // note that this is changed from "session" to "id"
};

A successful response to the request above will look like this:

{
  "token_type": "Bearer",
  "id_token": "ee08580dcb5ea51554b3aced5574554c",
  "id_refresh_token": "idrt-bosKV1aM8JMfsrlyce59P3StTWcLzaCP7fbG3FEMHVM"
  "expires_in": 86400 // seconds
}

You should keep the id_token and use it to launch Connect later within the expires_in time limit.

πŸ“˜

What's the difference between session_token and id_token?

Even though session_token and id_token serve virtually the same purpose in identifying the user, we use id_token as a more secure method of authorizing a user after they have already connected a data source. Additionally, session_tokens expire in 3600 seconds, while id_tokens expire in 86400 seconds.

Launch Connect in the browser

Once you have the user's session_token or id_token, you are now enabled to launch Connect. There are several ways to do this as follows:

npm package

You can import HumanConnect into your application:

npm i --save humanapi-connect-client

Then use it in your code:

import * as HumanConnect from "humanapi-connect-client";

The library supports most methods such as AMD and CommonJS

CDN

You can also load HumanConnect into HTML via our CDN.

Once you load the script from CDN, a global HumanConnect Javascript object will be defined.

You can launch the Connect widget within your application anytime after the token is populated. The example below shows how you can launch the widget upon clicking a button on a page:

<html>
  <head>
    <title>Human API demo</title>
    <!-- includes the following script tag to import connectJs -->
    <script src="https://cdn.humanapi.co/[email protected]"></script>
  </head>
 	<body>
    <h1>Human API demo</h1>
    <button id="connect-btn">Connect your health data</button>
  </body>
</html>
function startConnect(){
	
  // calling HumanConnect.open will start a modal view in your page. 
  HumanConnect.open({
    token : "YOUR_TOKEN", // "session_token" or "id_token"
    onClose : function(response) {
      console.log("user closed connect",response);
    }
  });
}

// call startConnect when a user clicks the button
document.getElementById("connect-btn").onclick = startConnect;

HumanConnect.open is a function that takes an options object as the sole argument. The only required attribute in the options object is token.

For a complete list of options, check out the Connect reference.

Get session details from user activity

HumanConnect will bring the user back to your application on exit. The user can exit the widget normally (for example, by clicking the 'X' button in the UI) or abnormally due to irrecoverable errors such as session expiration.

You can supply an onClose function to execute when the user exits Connect. The argument passed to your function will be an object that contains complete details of what happened within the Connect session which will help inform your app how to progress with the user.

The example below shows how to display status details:

// Handler for Connect onClose option
function handleClose(response) {
  var results = response.sessionResults;
  console.log("User closed connect widget",response);
  
  if (response.status === "SUCCESS") {
    console.log("User connected",results.connectedSources.length,"data sources");
  } 
  else {
    console.log("Widget closed with error", response.status);
  }
};

function handleConnect(response) {
	console.log("Connected a source")
};

function handleDisconnect(response) {
  console.log("Disconnected a source")
};

HumanConnect.open({
  token : "my-token",
  onClose : handleClose, // invoked when the user closes Connect
  onConnectSource: handleConnect, // invoked when the user connects a source
  onDisconnectSource: handleDisconnect, // invoked when the user disconnects a source
});

After the user connects several sources, the Connect onClose response supplied as an argument to your function looks like this:

{
  "status": "SUCCESS",
  "sessionResults": {
    "connectedSources": [
      {
        "name": "Starfleet Pharmacy",
        "id": "5b1daf3f079c652eaf41fd23"
      },
      {
        "name": "Cleveland Clinic",
        "id": "54dc427aaa6b4cb7d6203061"
      }
    ],
    "disconnectedSources": [],
  },
  "currentConnections": [
    {
      "name": "Starfleet Pharmacy",
      "id": "5b1daf3f079c652eaf41fd23"
    },
    {
      "name": "Cleveland Clinic",
      "id": "54dc427aaa6b4cb7d6203061"
    }]
}

You can find more details about these properties in our Connect reference.

We now want to start getting actual health data from the API. Let's explore how to do that.

πŸ“˜

onConnectSource and onDisconnectSource

Besides getting session details after the user closes Connect, you can also get that data as soon as the user connects or disconnects a source with the "onConnectSource" and "onDisconnectSource" arguments. Find out more in our Connect reference.

Retrieve the access token

When you want to query the user's health data, you must first get an access token. The request is almost exactly the same as for the session/id tokens except we add the client_secret: "--SECRET--" and type: "access" to the body:

// This example contains your client secret and must be used in your server. DO NOT use in the browser!
// This example uses open source request library to issue requests
// You can replace it with your favorite library

const request = require("request");

// Human API's authentication URL
const authUrl = "https://auth.humanapi.co/v1/connect/token";

// Payload you send to the server
const requestBody = {
  client_id: "--YOUR_CLIENT_ID--",
  client_user_id: "--YOUR_UNIQUE_IDENTIFIER--",
  client_secret: "--YOUR_CLIENT_SECRET--",
  type: "access" // replace this value with "access"
};

// Issue a HTTP call to Human API's authentication service
request({
  url: authUrl,
  method: "POST",
  json: true,
  body: requestBody
}, (error, resp , body) => {
  if (error) {
    throw error;
  }
  if (resp.statusCode >= 400 ) {
    console.error("Server returned error status");
  } else {
    console.log(resp.body);
  } 
})

A successful response to the request above will look like this:

{
    "access_token": "access-token",
    "expires_in": 86400,
    "token_type": "Bearer",
    "refresh_token": "atrt-zr5-gTJD8kWiwsNSWwhX2PhQA5-Rz0MpkCQVmdeDkZ3"
}

When you successfully retrieve the access token, you will use it to get the user's health data from our Data API Overview.

πŸ“˜

What should I do with the refresh tokens?

It is recommended to store the refresh tokens (e.g. "id_refresh_token" or "refresh_token"), but they do not need to be used in the current iteration of the API. You may request for new tokens respectively with the "client_id", "client_user_id", "client_secret" and "type".