Authentication
Every API call must contain an access token to authorize access to your project’s data. This is sent in every API request. This article explains how you get an access token for your requests.
Participant Access Tokens vs Service Access Tokens
MyDataHelps has two different types of access tokens:
- Service access tokens are associated with a service account. Server-to-server applications use them with the REST API to access project resources from an administration standpoint.
- Participant access tokens are associated with a single participant. Client applications use them with the SDK to access data for a single participant.
This guide deals with service access tokens. See Participant Access Tokens for information about participant-based access.
Getting a Service Access Token
The basic steps for getting an service access token are:
- Create a JSON Web Token (JWT) Assertion with details about your application and access request.
- Sign the JWT with your private key.
- Send a token request containing the JWT to the MyDataHelps server.
- The server will use the public key to verify the validity of the request and issue an access token.
- You can use that token in multiple API calls until it expires.
These steps are described in more detail below.
Note
Before you can get an access token, you must first create a service account and associate it with a public key. See
Service Accounts for details.
Code Examples
For examples of how to get a service account token (and generally access the API), check out one of our quickstart apps:
Understanding Public Key Authentication
Service accounts do not have passwords, but instead use a highly secure method for authenticating automated server-to-server applications called public key authentication. This mechanism is based on industry standards for data security, such as FHIR SMART Backend Services Authorization. In public key authentication, the server (MyDataHelps) uses the public key associated with your service account to confirm that your application has the correct private key.
Warning
Guard your private keys carefully. With your private key, anyone could access, manipulate, and even delete your project’s data. Inventory your private keys, change them regularly (as you would a password), and never embed them within source code or disclose them.
Creating and Signing JWT Assertions
When requesting an access token, your application will create a JSON Web Token Assertion (JWT Assertion) specifying information about the request.
The first part of this JWT Assertion is the header, which tells the server about the format of the assertion. Header fields include:
| Field |
Meaning |
Value |
| alg |
Algorithm |
RS256 |
| typ |
Type |
JWT |
Claims
Next are the claims, which contain information about the system making the request and the request itself. Claim fields include:
| Field |
Meaning |
Value |
| iss |
Issuer |
Your service account name (e.g., MyDataHelps.1234.test). |
| sub |
Subject |
Same as Issuer. |
| aud |
Audience |
https://mydatahelps.org/identityserver/connect/token |
| exp |
Expiration |
A timestamp (seconds since the Unix epoch) representing when the JWT token expires. |
| jti |
Identifier |
A unique identifier for each request. |
This claim is then signed using the private key that only your application knows.
Payload
The signed assertion is bundled in with a few other fields in a package called the JWT payload.
| Field |
Meaning |
Value |
| scope |
The scope of access being requested. |
A space-separated list of scopes to limit what permissions the token has. See Scopes for a list of possible values. |
| grant_type |
The type of access being requested. |
client_credentials |
| client_assertion_type |
Defines the format of the assertion. |
urn:ietf:params:oauth:client-assertion-type:jwt-bearer |
| client_assertion |
The assertion itself. |
Your signed assertion. |
Finally the JWT payload and header are sent to the MyDataHelps server. The server uses the public key associated with your service account to verify the validity of the signature, and thus the identity of your application.
Scopes
Scopes are a way to limit what data you can access with a service token. In the payload, you can specify a space-separated list of scopes.
For example, if you specify "Notifications:read Notifications:write" when requesting the token, you will only be able to execute notification-related API operations. Any other API calls will fail due to a lack of permissions.
Tip
As a best practice, only include the scopes you need for your desired use case.
| Scope |
Description |
api |
Full read/write access to all data for the associated account. Avoid this in favor of finer-grained permissions whenever possible. |
AppleHealthActivitySummaries:read |
Read Apple Health activity summaries. |
AppleHealthWorkouts:read |
Read Apple Health workouts. |
CustomEvents:write |
Write custom events. |
DataCollectionSettings:read |
Read data collection settings. |
DeviceData:read |
Read device data. |
DeviceData:write |
Write device data. |
ExternalAccounts:connect |
Connect to external accounts. |
ExternalAccounts:read |
Read external accounts. |
ExternalAccounts:write |
Write to external accounts. |
ExportConfiguration:read |
Read export configuration data. |
ExportConfiguration:write |
Write export configuration data. |
ExportExplorerSavedQueries:read |
Read saved queries in the Export Explorer. |
ExportExplorerSavedQueries:write |
Export saved queries in the Export Explorer. |
Exports:read |
Read data exports. |
File:read |
Read files. |
File:write |
Upload files. |
FitbitDataSummary:read |
Read Fitbit data summary. |
FitbitDailySummaries:read |
Read Fitbit daily summaries. |
FitbitSleepLogs:read |
Read Fitbit sleep logs. |
Notifications:read |
Read notifications. |
Notifications:write |
Send notifications. |
Participant:read |
Read basic participant info (e.g., demographics and participant fields). |
Participant:write |
Writes basic participant info (e.g., demographics and participant fields). |
Project:read |
Read project information. |
Project:write |
Update project settings. |
SurveyAnswers:read |
Read survey answers. |
SurveyResults:write |
Save survey results. |
SurveyTasks:read |
Read survey tasks. |
SurveyTasks:write |
Update survey tasks. |
Sending a Token Request
Once you have a signed JWT, you can send it to the MyDataHelps server’s token request URL:
POST https://mydatahelps.org/identityserver/connect/token
Note
Be sure to use the application/x-www-form-urlencoded content type. The payload must be posted as form parameters, not in the body data as JSON.
You can find sample code for making a token request in API Quickstart Apps. If the request is successful, the server’s response will include the following data:
| Field |
Meaning |
| access_token |
The alphanumeric access token. |
| expires_in |
When the token expires (in seconds). |
| token_type |
Bearer |
Troubleshooting Request Errors
If the request is unsuccessful, you will get an HTTP error code, typically a “400 - Bad Request” error. Here are some common reasons for a token request to fail:
- An invalid service account name. Be sure to use the full name, including the “MyDataHelps” prefix (e.g., MyDataHelps.1234.test).
- The wrong private key. Be sure you are using the correct public/private key pair associated with the service account.
- The incorrect signing algorithm. Only RS256 is supported.
- The wrong request format. Be sure that you are sending the payload as form parameters, not body data.
- An invalid JWT Assertion. Double-check that all the fields are provided, and that the ones with specified values have those exact values.
Using an Access Token
After receiving the access token, you will need to include it in every API call. You can use the same token in multiple API calls until the token expires.
In your HTTP request, add a header named “Authorization” containing the value “Bearer YOUR_TOKEN”.