Firstbeat Cloud API (1.0.0)

Download OpenAPI specification:Download

Overview

This page contains the documentation on how to access First Sports data via API.

First Steps

Is API the right choice for me?

If you are unsure what the Sports API can do and how it works, please contact sports-cloud-api@firstbeat.com. There are use cases that the API does not support and it is better to check your requirements with us before starting the implementation of your API client.

Sports API is available for Sports Premium and Premium+ customers.

An lternative method for getting data out from Firstbeat Sports is the Data Export functionality in Sports Cloud (premium feature).

Possible limitations to be aware of:

  • Some automated tools might not work out of the box with the encoded and compressed query result data or are they are not able to generate the needed API tokens on the fly.
  • The concepts used in your software might be different (measurement, session, etc.) and mapping of the query results might not be straightforward.
  • All metrics in the Firstbeat Sports are not available via API. Please refer to this documentation for the list of available metrics.
  • All metric names in the Sports API and Cloud Data export are not the same. Differences are listed in this document.

Getting Support

In case you have any questions about the Sports API please contact sports-cloud-api@firstbeat.com. For general Firstbeat Sports questions, please contact support@firstbeat.com.

We are happy to help you with any questions you might have.

Trying and Testing the Sports API

It is possible to try the Sports API with a test account. After registering as an API user, you will also get access to a test account that you can use for development and testing purposes.

You will receive an e-mail after you have been granted access to a test account (APITEST) with consumerName and id.

Test Account is a sandbox meant only for testing purposes.

Getting Started

Registering as a new API Consumer

To get started, you need to register as a Sports API consumer.

First, you need to select your API consumerName and then make an API request to account/register endpoint to create id and sharedSecret.

Your API consumerName can be anything but please use something that resembles your team or organization name. Later, your API consumerName will be visible in the Sports Cloud.

Base URI of the API is:

https://api.firstbeat.com/v1/

Example:

curl 'https://api.firstbeat.com/v1/account/register' \
    --data '{"consumerName": "your_api_consumer_name"}' \
    --header 'Content-Type:application/json'

On Windows command prompt you need a workaround for the single quotes:

curl -d "{"consumerName": "your_api_consumer_name"}" https://api.firstbeat.com/v1/account/register -H "Content-Type: application/json"

After a successful API call you should get a response similar to:

{ "id": "87a05c83-d5b7-46ba-aa4a-32f56cd284d5", "consumerName":"your_api_consumer_name", "sharedSecret":"8d5b6d12-61c5-4303-9ae3-c1837a15034b" }`
  • The generated id field is the primary field used for identifying you as an API user.

  • sharedSecretis used later for generating a token to access the API.

Please store this information securely.

Note: You can’t make requests to Sports API yet. We need to approve your account first. Also, you need to create JWT Token and API keys (see next steps).

When you have completed the registration, please copy and paste the consumerName and id field to email and send them to sports-cloud-api@firstbeat.com. The id field is used to approve your API account.

After you have received an e-mail that your id has been approved by the Sports API staff you are ready to proceed to the next step.

Approve API Consumer Access to Your Account Data

Next, your API consumer needs to be granted access to the Sports account you are accessing with your API client. This is done at Sports Cloud (https://www.sports.firstbeat.com).

Successful requests to API cannot be made before completing this step.

If you don’t have access to Sports Cloud, please ask a person who owns the account to complete the steps below.

In Sports Cloud, do the following:

  1. Click the settings menu on the top left corner of the screen. Go to the Cloud API section of the screen.

  2. Read and accept the license agreement.

  3. Select the API consumer from the list to grant access to account data (select the account checkbox).

  4. Finally, save settings.

After the access has been approved, you can proceed to create JWT Tokens and adding an API Key.

Creating a JWT Token

The API token is needed for creating an API key and for making request to the Sports API.

Every Firstbeat Cloud API endpoint (except /register) will require authentication in the form of JWT Token (JSON Web Token) in the Authorization header.

The format for passing the token in headers is as follows:

Authorization Bearer xxxxxxxxxxxxxxxx.yyyyyyyyyyyyy.zzzzzzzzzzzzzzz

JWT Token is a standardized way of generating a token. Currently, Firstbeat Cloud API supports HMACSHA256 encoded JWT tokens, with a shared secret. The token should be valid at the most five minutes after generation.

JWT Token format consists of three parts separated by a . (dot). The first part is the Base64 encoded header information, the second part is Base64 encoded Payload data and the last part is HMAC – encoded combination of HMACSHA256 encoding the headers, payload, and a shared secret text string.

For more information about JWT Tokens, check https://jwt.io/

You need your id and sharedSecret to create an API token.

Examples of how to create a JWT token are provided in the next chapter.

As a result, you should have a token generated. A token looks like this (your token will be unique).

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJjMzhlMjU2ZC0xMWVlLTRmNWQtYWI0NS1iNjJkMDU3NGE3ZmQiLCJpYXQiOjE1ODg2NzQxNzYsImV4cCI6MTU4ODY3NDQ3Nn0.BQpPdmyM4KikNFIRisKdOkFRCADCA1bQpKUzBUWy3QA

Note: Token is valid only for five minutes at a time. After five minutes, the token expires and you need to create a new token to access the API.

Exaples for Generating a JWT Token

Here are some examples with commonly used programming languages on how to generate a JWT Token with the help of some open source JWT libraries:

Java

Create a JWT token with Java (java-jwt):

import java.util.Date;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

try {
Algorithm algorithm = Algorithm.HMAC256("YOUR_SHARED_SECRET");
Date now = new Date();
Date expires = new Date();
expires.setSeconds(expires.getSeconds() + 300);

String token = JWT.create()
    .withIssuer("YOUR_CONSUMER_ID")
    .withIssuedAt(now)
    .withExpiresAt(expires)
    .sign(algorithm);
} catch (UnsupportedEncodingException exception){
//UTF-8 encoding not supported
} catch (JWTCreationException exception){
//Invalid Signing configuration / Couldn't convert Claims.
}

Node.js / JavaScript

Create a JWT token with Node.js (jsonwebtoken):

'use strict';

const jwt = require('jsonwebtoken');
const SECRET = 'YOUR_SHARED_SECRET';
const issuedAt = Date.now() / 1000;
const payload = {
iss: 'YOUR_CONSUMER_ID',
iat: issuedAt,
exp: issuedAt + 300
};

// default algorithm (HMAC SHA256)

const token = jwt.sign(payload, SECRET);

Python

Create a JWT token with Python (pyJwt):

import jwt #pyjwt
import time

secret = 'YOUR_SHARED_SECRET'
now = int(time.time())
expires = now + 300

payload = {
    'iss': 'YOUR_CONSUMER_ID',
    'iat': now,
    'exp': expires
}

token = jwt.encode(payload, secret)

Adding an API Key

Next, create your API key using the account/api-key endpoint.

For this step, you need a valid API token you generated earlier. Please remember the five minute expiration period for the token. Generate a new token in case more than five minutes have passed.

You create an API key only once.

Example curl command:

curl 'https://api.firstbeat.com/v1/account/api-key' \
    --request GET \
    --header 'Authorization: Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJjMzhlMjU2ZC0xMWVlLTRmNWQtYWI0NS1iNjJkMDU3NGE3ZmQiLCJpYXQiOjE1ODg2NzQxNzYsImV4cCI6MTU4ODY3NDQ3Nn0.BQpPdmyM4KikNFIRisKdOkFRCADCA1bQpKUzBUWy3QB' \
    --header 'Content-Type: application/json'

For this command, you make a GET request with a header “Bearer token” string.

If the request is successful, you get an API key as a response:

{"apikey":"cXvpCBUzG64orvHXA5taA2Et2hWGr6Gh1LqL90hx"}

Testing your API Access

At this point:

  1. You have registered as a Sports API user and your account has been approved by Firstbeat
  2. API consumer has been granted access to Sports account data sharing from Sports Cloud
  3. You have generated an API token to add an API key

Now you can access the Sports Cloud API.

Each API request needs to include an API key and a valid token in the header.

Example curl command to list accounts linked for your API consumer:

curl 'https://api.firstbeat.com/v1/sports/accounts' \
    --request GET \
    --header 'Authorization: Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJjMzhlMjU2ZC0xMWVlLTRmNWQtYWI0NS1iNjJkMDU3NGE3ZmQiLCJpYXQiOjE1ODg2NzQxNzYsImV4cCI6MTU4ODY3NDQ3Nn0.BQpPdmyM4KikNFIRisKdOkFRCADCA1bQpKUzBUWy3QA' \
    --header 'x-api-key: cXvpCBUzG64orvHXA5taA2Et2hWGr6Gh1LqL90hx'

Successful operation returns:

{
    "accounts": [
    {
        "accountId": "1-1",
        "name": "Some account",
        "authorizedBy": {
        "coachId": 0
        }
    }
    ]
}

API Usage Limits

Each API consumer will have usage limits of how frequently it is allowed for the consumer to request Firstbeat Cloud API resources.

If the consumer will not follow the usage limits, the account will be first throttled for a moment and denied access to the resources. If, despite being cautioned by Firstbeat, API consumer continues to disuse the API in ways that stress the service excessively Firstbeat reserves the right to disable the consumer access permanently.

Currently, API consumer-specific limits are as follows and should be honored:

  • Max. 60 requests / minute
  • Max. 5000 requests / day

Result pagination

Some endpoints are limited to 1000 results per request. To fetch more results, the API provides an attribute “more” with the results.

If “more: true” attribute is appended to the returned JSON data, you may request the next set of data by providing a query parameter ?offset=OFFSET_NUMBER to the request, to get the next set of data. OFFSET_NUMBER = The amount of already fetched documents. For example 1000.

Returned Time Fields

All returned time fields follow RFC3339 specification. Data is always returned in UTC time.

Filtering Session Results

Sessions can be filtered by time or type. Different filters can be combined in order to have better results.

Parameter (example) Description
fromTime: 2017-02-01T12:00:00Z (year-month-dayThour:minute:secondZ) Returns all sessions that begin earliest at the specified time
toTime:2017-02-02T23:30:00Z (year-month-dayThour:minute:secondZ) returns all sessions that begin before the specified time
type:sessionType returns all sessions which have given type

Result variables

Below is listed the full list of available result variables. There are two types of variables:

  1. Scalars: Single values calculated from the measurement. For example, 64.
  2. Time series vectors: Values from each respective moment of the measurement period. For example [115,115,117,124,...].

Decoding Time Series Vectors

Time series vectors are Base64 encoded and zlib compressed.

Here is a code example how to work with time series data in JavaScript.

import pako from 'pako';
import atob from 'atob';
const decompress = series => {
  const bytes = pako.inflate(
    new Uint8Array(
      atob(series.data)
        .split('')
        .map(x => x.charCodeAt(0))
    )
  );
  const buffer = new ArrayBuffer(bytes.length);
  const view = new DataView(buffer);
  bytes.forEach((b, i) => view.setUint8(i, b));
  const readValueFromByteArray = {
    Float: {
      64: (dataView, index) => dataView.getFloat64(index * 8),
      32: (dataView, index) => dataView.getFloat32(index * 4)
    },
    Unsigned: {
      16: (dataView, index) => dataView.getUint16(index * 2),
      8: (dataView, index) => dataView.getUint8(index)
    },
    Signed: {
      16: (dataView, index) => dataView.getInt16(index * 2)
    }
  };
  const result = [];
  for (let i = 0; i < bytes.length / (series.bits / 8); i++) {
    result[i] = readValueFromByteArray[series.type][series.bits](view, i);
  }
  return result;
};

You may also always use the query parameter list to get the data in an uncompressed format. If possible, please prefer uncompressing the data on the client side.

For example: ...results?var=rmssd1MinSeries,vlfSeries,lfSeries,hfSeries&format=list

Scalar variables

Last column of the table below shows the corresponding variable name in Sports Cloud data export (excel export). Note the differences in some variable names, for example training zone times.

API variable name Unit Description Data Export variable name
heartRateAverage 1/min The average heart rate value for the measurement. Average HR (bpm)
heartRatePeak 1/min The highest heart rate value achieved during the measurement. Peak HR (bpm)
heartRateLowest 1/min The lowest heart rate value achieved during the measurement. Minimum Heart rate`
heartRateAveragePercentage % Average %HRmax from the recorded measurement. Calculated based on the maximum heart rate value set to the profile. Average %HRmax (%)
heartRatePeakPercentage % Peak value of %HRmax. Calculated based on the set maximum heart rate. Peak HR (bpm)
heartRateMinimumPercentage % Minimum value of %HRmax. Calculated based on the set maximum heart rate value. Minimum HR (bpm)
zone1Time min The overall time spent in heart rate zone1 during the measurement. The exercise intensities are categorized into different zones based on the percentage of personal maximal heart rate (%Hrmax). High intensity training (hh:mm:ss)
zone2Time min The overall time spent in heart rate zone2 during the measurement. Anaerobic threshold zone (hh:mm:ss)
zone3Time min The overall time spent in heart rate zone3 during the measurement. Aerobic zone 2 (hh:mm:ss)
zone4Time min The overall time spent in heart rate zone4 during the measurement. Aerobic zone 1 (hh:mm:ss)
zone5Time min The overall time spent in heart rate zone5 during the measurement. Recovery training (hh:mm:ss)
underZonesTime min The overall time spent below the set heart rate zones during the measurement. Time Under Zones (hh:mm:ss)
trimp index Training Impulse value. A cumulative variable illustrating training load TRIMP (Index)
trimpPerMinute 1/min Average TRIMP accumulation per minute in the recorded measurement. TRIMP/min (Index)
epocPeak ml/kg The highest EPOC (Excess Post-Exercise Oxygen Consumption) value achieved during the measurement. EPOC Peak (ml/kg)
vo2max ml/kg/min Maximal amount of oxygen in milliliters per kilogram the athlete can utilize over one minute during an intense, maximal effort. Calculated from the heart rate variability data. VO2max (ml/kg/min)
oxygenConsumptionAverage ml/kg/min The average rate of oxygen consumption achieved during the measurement. Average VO2 (ml/kg/min)
oxygenConsumptionPeak ml/kg/min The highest rate of oxygen consumption achieved (VO2max) during the measurement. Oxygen consumption is calculated in proportion to the person's weight. The higher the value, the higher the peak intensity of exercise. Peak VO2 (ml/kg/min)
oxygenConsumptionMaximumPercentage % Peak value of %VO2max. Calculated based on the set VO2max value. Peak %VO2max (%)
oxygenConsumptionAveragePercentage % Average %VO2max from the recorded measurement. Average %VO2max (%)
acuteTrainingLoad index The TRIMP sum from the past 7 days. Acute Training Load
chronicTrainingLoad index The TRIMP sum from the past 28 days divided by 4. Chronic Training Load
acwr (ratio) Acute and chronic working load ratio. ACWR
aerobicTrainingEffect 0.0 - 5.0 The 0-5 score of the personalized impact of the training measurement on aerobic fitness development. A score 0-0.9 is defined as "no effect", 1.0-1.9 as "minor effect", 2.0-2.9 as "maintaining effect", 3.0-3.9 as "improving effect", 4.0-4.9 as "highly improving effect", and 5.0 as "overreaching effect". Aerobic TE (0.0 - 5.0)
anaerobicTrainingEffect 0.0 - 5.0 Anaerobic Training Effect. See aerobicTrainingEffect for results scale. Anaerobic TE (0.0 - 5.0)
respirationRateAverage 1/min Average respiration rate in times per minute. Calculated from the heart rate variability data. Average RespR (times/min)
respirationRatePeak 1/min Peak value of respiration rate in times per minute Peak RespR (times/min)
energyConsumptionCarbs kcal Shows the carbohydrate energy expenditure in the recorded measurement in kcal. EE Carbohydrates (kcal)
energyConsumptionFats kcal Shows the fat energy expenditure in recorded measurement in kcal. EE Fats (kcal)
energyConsumptionTotal kcal The overall energy (kilocalorie) consumption during the measurement. EE Total (kcal)
movementLoad index Total accumulated movement load. Movement load
averageMovementIntensity index Average of the accumulation rate of movement load. Average movement intensity
quickRecoveryTestScore index The 0-100% score of the personalized result of the Quick Recovery Test (QRT). Quick recovery test (Index)
quickRecoveryScaledScore % Scaled quick recovery index calculated based on the athlete's minimum and maximum quick recovery test index value. Scaled Quick Recovery Test (%)
scaledQrtWeeklyMean % Athlete's individual quick recovery test 7-day average. -
playerStatusScore 0-100 Training status describes the balance of training for an individual athlete. Scale: well balanced: over 70, moderately balanced: 30-70, out of balance: below 30. Training status
rmssd ms Root Mean Square od Successive Differences. Value to indicate quality of recovery. RMSSD (ms)
sdnn ms Standard deviation of normal to normal R-R intervals in milliseconds. SDNN (ms)
lfHfRatio % Ratio between the high frequency and low frequency heart rate variability power during the recorded measurement. LF/HF (%)
lfAverage ms^2 Mean of the low frequency heart rate variability power during the recorded measurement. LF Average (ms^2)
hfAverage ms^2 Mean of the high frequency heart rate variability power during the recorded measurement. HF Average (ms^2)
vlfAverage ms^2 Mean of the very low frequency heart rate variability power during the recorded measurement. VLF Average (ms^2)
recoveryStateTime min The overall time spent in recovery state during the measurement. Relaxation time (hh:mm:ss)
stressStateTime min The overall time spent in stress state during the measurement. Stress time (hh:mm:ss)
sleepStateTime min Athletes’s sleep duration in hours, minutes and seconds. Sleep duration (hh:mm:ss)
sleepRecoveryIndexAbsolute index An index of the athlete's recovery during sleep from the 4-hour window starting 30 minutes after going to bed. Recovery Index (absolute)
daysSinceLastGoodRecovery days Athletes's time since good recovery in days. Quick recovery test (Time since good recovery) (Days)
measurementError % Average percentage of RR intervals recognized as artifacts after the artifact correction has corrected the data. Measurement error (%)

Time series vectors

API variable name Unit Sampling Rate (Hz) Type Bits Description
rmssd1MinSeries 1) ms 0.02 Float 64 Time series data for Root Mean Square od Successive Differences (rmssd). Value to indicate quality of recovery.
vlfSeries 1) ms^2 1 Float 64 Time series data for the mean of the very low frequency heart rate variability during the recorded measurement.
lfSeries 1) ms^2 1 Float 64 Time series data for the mean of the low frequency heart rate variability during the recorded measurement.
hfSeries 1) ms^2 1 Float 64 Time series data for the mean of the high frequency heart rate variability during the recorded measurement.
artifactCorrectedRrVector 1) ms - Float 64 Artifact corrected RR interval vector. Vector consists of values indicating time in milliseconds between consecutive R-peaks.
heartRateSeries1s 1/min 1 Unsigned 8 The time series showing the momentary value of heart rate during the measurement, 1s sampling.
heartRateSeries 1/min 0.2 Unsigned 8 The time series showing the momentary value of heart rate during the measurement. 5s sampling.
heartRatePercentageSeries 1) 0.2 Float 64 Heart rate percentage vector.
epocSeries ml/kg 0.2 Float 64 The time series showing the momentary value of EPOC during the measurement.
energyConsumptionSeries kcal/h 0.2 Unsigned 16 The time series showing the momentary value of energy (kilocalorie) consumption rate as kcal/h during the measurement.
trimpSeries 0.2 Float 64 The time series showing the momentary value of TRIMP during the measurement.
trimpPerMinuteSeries 1) 1/min 0.2 Float 64 TRIMP time series vector.
movementLoadAccumulationRate 1/min 0.2 Float 64 Time series vector for Movement Load Accumulation Rate.

NOTE: TimeSeries variables marked with an 1) need to be explicitly requested from the /results endpoints due to their data-heavy nature. To request them, use the ?var= query parameter.

For example: .../results?var=trimpPerMinuteSeries,heartRatePercentageSeries

account

Register as an API consumer

Registers a new API consumer

Request Body schema: */*

Created API Consumer object

consumerName
required
string

Responses

Response samples

Content type
application/json
{
  • "id": "0df33d4b-f526-4040-ad6e-447589f810f5",
  • "consumerName": "Firstbeat Cloud API User",
  • "sharedSecret": "5e03d766-4d55-4c88-a011-f0785bccb671"
}

Request an api-key

Generate consumer specific api-key needed to access other Cloud API endpoints

header Parameters
Authorization
required
string

format: Bearer YOUR_TOKEN

Responses