NAV
Shell HTTP Node.JS Ruby Python Java

Polar AccessLink API v3

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Polar AccessLink API documentation

Base URL: https://www.polaraccesslink.com/

Email: Support
Web: Support
License: Polar Electro AccessLink Limited License Agreement

Introduction

AccessLink is the access channel to the training and daily activity data recorded by Polar devices. Any registered Polar Flow user can create API client to AccessLink by filling application details at https://admin.polaraccesslink.com.

AccessLink uses OAuth2 as authentication protocol. Registered partners will require OAuth2 client credentials in order to request user authorizations and be able to access their data.

In addition, each user needs to have all mandatory consents accepted in order to be able to access their data. User consents can be changed anytime at https://account.polar.com.

JSON and XML file formats are supported except for OAuth2 process where only JSON file format is supported.

How to get started?

  1. Create Polar Flow account if you don't have one already
  2. Go to https://admin.polaraccesslink.com and log in using your Polar Flow credentials
  3. Fill your application/service information and create client
  4. After client is created, remember to write down OAuth2 client id and secret for later use
  5. Obtain authorization code for the user using authorization endpoint
  6. Use authorization code to obtain access token for the user using token endpoint
  7. Register user using register user endpoint to be able to access user's data
  8. Start developing the API

Support

For support, please contact b2bhelpdesk@polar.com

API basics

Users
The resource allows partners to register, de-register and retrieve user's basic information.
Pull notification
The resource allows partners to check if their users have available data for downloading.
Daily activity
The resource allows partners to access their users' daily activity data.
Training data
The resource allows partners to access their users' training data.
Physical info
The resource allows partners to access their users' physical information. Whenever some user's physical information changes, new entry containing full physical info is stored to AccessLink. Pull notifications can be used to check if user has new physical information available.
Continuous Heart Rate
The resource allows partners to access their users' continuous heart rate data. Check Continuous Heart Rate page for more information.
SleepWise™
The resource allows partners to access their users' SleepWise™ data. SleepWise&trade data consists of alertness periods and circadian bedtime periods. Check SleepWise™ page for more information.
Elixir™ Biosensing
The resource allows partners to access their users' Elixir™ Biosensing data. Elixir™ Biosensing data consists of body temperature data, sleep skin temperature data, skin contacts data, wrist ECG test report data and SpO2 test report data. Check Elixir™ Biosensing page for more information.
Webhooks
The resource allows partners to register webhooks to let them know when their users' data is available for retrieval.
Exercises
The resource allows partners to access their users' exercise data.
Sleep & Sleep Plus Stages™
The resource allows partners to access their users' sleep data. Check Sleep Plus Stages™ page for more information.
Nightly Recharge™
The resource allows partners to access their users' nightly recharge data. Check Nightly Recharge™ page for more information.
Cardio Load
Cardio load is based on training impulse calculation (TRIMP), a commonly accepted and scientifically proven method to quantify training load. Your Cardio load value tells you how much strain your training session put on your cardiovascular system.
Data models
Data models describes all the objects that carries data between server and the client.
Appendixes
Appendixes contains examples and more detailed info about the application interface.

Security

TLS (Transport Layer Security) connections are required in order to access Polar AccessLink API endpoints. TLS will provide privacy and data integrity between client application and Polar AccessLink API.

AccessLink uses OAuth2 as an authentication protocol. See authentication page to get started.

Rate limiting

Dynamic rate limit scales partners rate limit values based on number of registered users. Rate limit values are updated daily. There are two kind of rate limits: short term (15min) and long term(24h). The short term limit is reset after 15 minutes have passed since first request is made and the long term limit is reset after 24 hours have passed since first request.

The formula for calculating rate limit are:

Partner's limits, usage and reset time are returned with every API request as part of the HTTP Headers.

Name Value Description
RateLimit-Usage Integer, Integer Two comma separated values, short term followed by long term usage.
RateLimit-Limit Integer, Integer Two comma separated values, short term followed by long term limit.
RateLimit-Reset Integer, Integer Two comma separated values, short term followed by long term reset time in seconds.

Requests exceeding the limit will return 429 - Too Many Requests. Note that requests violating the short term limit will still count toward the long term limit.

Development resources

Transaction model

Fetching user data (training, activity and physical information) from Accesslink is based on transactions.

Using transactions consist of three request/response pairs:

  1. Initiating a new transaction
  2. Retrieving data within the transaction
  3. Committing transaction

Pull notifications can be used to check if user have available data.

Each transaction will consist of at most 50 entities. Once entities linked to transaction have been fetched, transaction must be committed. If transaction is not committed within 10 minutes after it was created, it will be disbanded, and all data linked to it will be returned in next transaction. Attempting to access disbanded transaction will result HTTP error 404 NOT FOUND.

Activity transactions

Each transaction will consist of at most 50 activity summaries. In case a transaction with 50 activity summaries is retrieved by partner, they can check for new data by initiating a new transaction. In case less that 50 activity summaries is returned, partner should not request a new transaction immediately after committing.

In Accesslink 2.1x activity data could only contain one data item per user per day, but in Accesslink 3.0 user can have several activity data items per day. For example, if user synchs data at noon 1st of May, as a result you will get a partial activity summary that will contain data for first half of May 1st. When user synchs data on May 2nd, or later, you will get the full days activity summary for May 1st as second piece of data.

Example, transaction contains three summaries for same user, two on same date:

Even though transaction returns three activity summaries, only summaries with created times 2020-01-01T00:00:00.000 and 2020-01-02T15:00:00.000 should be taken into account because summary with created time 2020-01-02T15:00:00.000 contains latest data for that day. Summary with created time 2020-01-02T10:00:00.000 is outdated information. Or in other words, only the latest activity summary should be taken into account for each day for each user.

Activity data supports combining activity data from multiple devices. If user, for example, synchs (two minutes apart) data for two devices, summary data will be like following: * Summary, created time 2020-01-03T13:00:00.000, will have data for users first device * Summary, created time 2020-01-03T13:02:00.000, will have data for first AND second device, combined

In this case, summary with created time 2020-01-03T13:02:00.000 should be used as users activity data for that day.

NOTE! Not all data will be synched on the day it was recorded on. Sometimes there can be very long delays between recording and synching the activity. User may synch the data weeks, or even months after recording the data. It is important to check what day the activity was recorded on, and then use the latest synch data for that user, for that day.

Accesslink webhooks

Overview

Polar Accesslink webhooks allows client application to subscribe to receive notification when certain event occurs.

Webhook delivery

Information about event is sent to registered webhook URL using HTTP POST method. Webhook delivery expects response 200 from remote endpoint.

Creating webhook

PING example

POST / HTTP/1.1
Host: myapp.example.com:443
Content-type: application/json
Polar-Webhook-Event: PING
Polar-Webhook-Signature: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
{
    "timestamp": "2019-01-11T08:25:10.02Z",
    "event": "PING"
}

Webhook can be created using create webhook -endpoint. When creating webhook Accesslink API sends ping message to given url so make sure the webhook url is valid and there is a server responding to messages.

When new webhook is created Accesslink API returns a unique signature_secret_key. Accesslink service uses this signing key to sign all payload messages. Signature is included in "Polar-Webhook-Signature" header, and receiving endpoint should verify the signature when receiving message to verify origin of message.

This signing key is not available after create so make sure to save the key when creating webhook.

Note! Client application can only have one webhook registered.

Payload example

POST /acl_webhook HTTP/1.1
Host: myapp.example.com:443
Content-Type: application/json
Polar-Webhook-Signature: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
Polar-Webhook-Event: EXERCISE
{
   "event": "EXERCISE",
   "user_id": 475,
   "entity_id": "aQlC83",
   "timestamp": "2018-05-15T14:22:24Z",
   "url": "https://www.polaraccesslink.com/v3/exercises/aQlC83"
}

Webhook payload

Webhook payload contains event type and event specific metadata related to event, and possible url related to event. Payload schemas for different event types are available at:

Message headers contains webhook event type and signature for verifying that sender is actually Polar.

Verifying payload signature

Hash-based message authentication code (HMAC SHA-256) is used to sign every webhook payload Accesslink sends. The secret key for calculating signature is given to client when they create the webhook.

To verify sender client should calculate HMAC and compare it to the signature in payload header.

Failure management

Webhook will be automatically deactivated if push notifications have not been successful for a period of seven (7) days. Deactivated webhook can be activated by using /v3/webhooks/activate endpoint.

HMAC SHA-256 calculation example

public static String calculateHMAC(String data, String key)
    throws SignatureException, NoSuchAlgorithmException, InvalidKeyException
{
    SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(signingKey);
    return toHexString(mac.doFinal(data.getBytes()));
}

Authentication

The basic Polar OAuth2 flow for Accesslink use goes as follows:

  1. User is re-directed from partner system to OAuth2 authorization endpoint in Polar Flow
  2. User grants partner the right to access his/her data in Accesslink
  3. User is redirected back to partner system and partner system receives authorization code as part of the request
  4. Partner system uses the authorization code to get access token using token endpoint in Polar Remote
  5. Access token is used to register/de-register users and to access their data

Authorization endpoint

GET https://flow.polar.com/oauth2/authorization

Some of the API endpoints require an authorization code to be used as part of the request. To get the authorization code for a user, redirect user to the following endpoint with required and optional query parameters:

https://flow.polar.com/oauth2/authorization?[...params]

An example with mandatory query parameters is shown below:

https://flow.polar.com/oauth2/authorization?response_type=code&client_id=d52d533a-3c71-4141-aea6-3402519678aa

Parameters and their definitions

Name Required Description
response_type YES Specifies used authorization flow. "code" is the only response type supported and means that authorization code flow is used.
client_id YES Unique client id provided by Polar when the client is registered in the admin page.
redirect_uri NO Redirect URL used by the client. Must be identical to the redirect URL given during Accesslink client registration or any other URL that has been added for the client. Note that you can add multiple URLs for the client by modifying the client in the admin page. If redirect_uri is not specified in the request the only existing URL or the one flagged as the default URL will be used.
scope NO Specifies the scope of the requested user authorization. If not provided, user will be asked to grant authorization for all scopes linked to client. Accesslink uses accesslink.read_all -scope, which allows access to user's data.
state NO An opaque string. This will be given as parameter when making a request to the redirect URL. It can be used to prevent CSRF attacks.

On success, user will be shown the authorization form. After granting authorization, user will be redirected to URL specified by the optional redirect_uri. If specified, value of the redirect_uri must be identical to the redirect URL given during Accesslink client registration or any other URL that has been added for the client.

You can modify, add and delete client's redirect URLs in the admin page: https://admin.polaraccesslink.com/. You can also select which URL to use as the default URL when redirect_uri is not provided in the request.

If specified redirect_uri is not found from the client then error code is included in the response. Otherwise the authorization code will be provided as a query parameter as part of the request when user is redirected to the specified location.

Examples:

If an error occurs, user will be redirected to the specified default redirect URL with error code included.

Example:

Parameters and their definitions

Name Description
state Same value as "state"-parameter in the authorization server request. If the parameter was not given on authorization request, this parameter will not be present.
code Authorization code that expires in 10 minutes. This code must only be used once. If it's used more than once, the request will be denied and ALL issued tokens will be deleted. If an error occurs, this parameters is not present.
error Code for error that happened. This parameter is only present if an error occured.

Error codes

Token endpoint

POST https://polarremote.com/v2/oauth2/token

With authorization code, an access token can be requested by posting authorization code to token endpoint.

Request headers

Request POST data

Name Required Description
grant_type YES Must be always value "authorization_code"
code YES Authorization code received from authorization endpoint
redirect_uri NO* Must be specified if redirect_uri was passed to authorization endpoint

Response JSON object

If error occurs during request, result JSON object will be

Status Codes

Example request

# You can also use wget
curl -X POST https://polarremote.com/v2/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic dGhpc2RvZXNudDpkb2FueXRoaW6s' \
  --data-urlencode "grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA"
POST https://polarremote.com/v2/oauth2/token HTTP/1.1
Authorization: Basic dGhpc2RvZXNudDpkb2FueXRoaW6s
Content-Type: application/x-www-form-urlencoded
Accept: application/json;charset=UTF-8

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
const fetch = require('node-fetch');
const inputBody = {
  'grant_type': 'authorization_code',
  'code': 'SplxlOBeZQQYbYS6WxSbIA'
};
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json',
  'Authorization':'Basic dGhpc2RvZXNudDpkb2FueXRoaW6s'
};

fetch('https://polarremote.com/v2/oauth2/token',
{
  method: 'POST',
  body: new URLSearchParams(inputBody),
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Authorization': 'Basic dGhpc2RvZXNudDpkb2FueXRoaW6s'
  'Accept': 'application/json',
}
body = {
  'grant_type': 'authorization_code',
  'code': 'SplxlOBeZQQYbYS6WxSbIA'
}

r = requests.post('https://polarremote.com/v2/oauth2/token', data=body, headers=headers)

print r.json()
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Authorization' => 'Basic dGhpc2RvZXNudDpkb2FueXRoaW6s'
}
body = {
  'grant_type' => 'authorization_code',
  'code' => 'SplxlOBeZQQYbYS6WxSbIA'
}

result = RestClient.post 'https://polarremote.com/v2/oauth2/token', body, headers: headers

p JSON.parse(result)
String body="grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA";
        byte[]bodyBytes=body.getBytes(StandardCharsets.UTF_8);
        URL obj=new URL("https://polarremote.com/v2/oauth2/token");
        HttpURLConnection con=(HttpURLConnection)obj.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        con.setRequestProperty("Authorization","Basic dGhpc2RvZXNudDpkb2FueXRoaW6s");
        con.setRequestProperty("Accept","application/json");

        try(DataOutputStream wr=new DataOutputStream(conn.getOutputStream())){
        wr.write(odyBytes);
        }

        int responseCode=con.getResponseCode();
        BufferedReader in=new BufferedReader(
        new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response=new StringBuffer();
        while((inputLine=in.readLine())!=null){
        response.append(inputLine);
        }
        in.close();
        System.out.println(response.toString());

Example response

{
    "access_token" : "2YotnFZFEjr1zCsicMWpAA",
    "token_type" : "bearer",
    "expires_in" : 31535999,
    "x_user_id" : 10579
}

Making requests

Accesslink 3.0 uses two kinds of authentication. Authentication with user token (access token), and authentication with client (partner) credentials. All requests to /v3/users and its subresources are done with user token authentication, and all other /v3/ requests (/v3/notifications for example) are done with client credentials.

User token authentication

In order to make requests to Users API, add the OAuth2 token received from the token endpoint to the Authorization request header:

Name Value
Authorization Bearer <access-token>

Access tokens will not expire unless explicitly revoked by partners or users.

Client credentials authentication

In order to make requests to client level resources, include the following header:

Name Value
Authorization Basic dGhpc2RvZXNudDpkb2FueXRoaW6s

Where dGhpc2RvZXNudDpkb2FueXRoaW6s is replaced with base64 encoded string client_id:client_secret. For example, if your client id is 12345 and client secret is verySecret, then you need to base64 encode string 12345:verySecret.

Users

This resource provides all the necessary functions to manage users.

Register user

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/users \
  -H 'Content-Type: application/xml' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://www.polaraccesslink.com/v3/users HTTP/1.1
Host: www.polaraccesslink.com
Content-Type: application/xml
Accept: application/json

const fetch = require('node-fetch');
const inputBody = '{
  "member-id": "User_id_999"
}';
const headers = {
  'Content-Type':'application/xml',  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/xml',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://www.polaraccesslink.com/v3/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
input_body = {
  "member-id": "User_id_999"
};
headers = {
  'Content-Type': 'application/xml',  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.post('https://www.polaraccesslink.com/v3/users', headers = headers
    , json=input_body)

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/users

Once partner has been authorized by user, partner must register the user before being able to access its data. API user-id and Polar User Id (polar-user-id) are interchangeable terms.

Body parameter

{
  "member-id": "User_id_999"
}
<?xml version="1.0" encoding="UTF-8" ?>
<register>
  <member-id>User_id_999</member-id>
</register>

Parameters

Parameter In Type Required Description
body body register true none
» member-id body string true Partner's custom identifier for user.

Example responses

200 Response

{
  "polar-user-id": 2278512,
  "member-id": "i09u9ujj",
  "registration-date": "2011-10-14T12:50:37.000Z",
  "first-name": "Eka",
  "last-name": "Toka",
  "birthdate": "1985-09-06",
  "gender": "MALE",
  "weight": 66,
  "height": 170,
  "extra-info": [
    {
      "value": "2",
      "index": 0,
      "name": "number-of-children"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<user>
  <polar-user-id>2278512</polar-user-id>
  <member-id>i09u9ujj</member-id>
  <registration-date>2011-10-14T12:50:37.000Z</registration-date>
  <first-name>Eka</first-name>
  <last-name>Toka</last-name>
  <birthdate>1985-09-06</birthdate>
  <gender>MALE</gender>
  <weight>66</weight>
  <height>170</height>
  <extra-info>
    <value>2</value>
    <index>0</index>
    <name>number-of-children</name>
  </extra-info>
</user>

Responses

Status Meaning Description Schema
200 OK User's base information. user
204 No Content No content when user with given userId is not found. None
403 Forbidden User has not accepted all mandatory consents. None
409 Conflict User already registered to partner or duplicated member-id. None

Get user information

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}

List user basic information. Note: Although it is possible to get users weight and height from this resource, the get physical info should be used instead.

Parameters

Parameter In Type Required Description
user-id path integer(int64) true User identifier

Example responses

200 Response

{
  "polar-user-id": 2278512,
  "member-id": "i09u9ujj",
  "registration-date": "2011-10-14T12:50:37.000Z",
  "first-name": "Eka",
  "last-name": "Toka",
  "birthdate": "1985-09-06",
  "gender": "MALE",
  "weight": 66,
  "height": 170,
  "extra-info": [
    {
      "value": "2",
      "index": 0,
      "name": "number-of-children"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<user>
  <polar-user-id>2278512</polar-user-id>
  <member-id>i09u9ujj</member-id>
  <registration-date>2011-10-14T12:50:37.000Z</registration-date>
  <first-name>Eka</first-name>
  <last-name>Toka</last-name>
  <birthdate>1985-09-06</birthdate>
  <gender>MALE</gender>
  <weight>66</weight>
  <height>170</height>
  <extra-info>
    <value>2</value>
    <index>0</index>
    <name>number-of-children</name>
  </extra-info>
</user>

Responses

Status Meaning Description Schema
200 OK User's base information. user
204 No Content No content when user with given userId is not found. None
403 Forbidden User has not accepted all mandatory consents. None

Delete user

Code samples

# You can also use wget
curl -X DELETE https://www.polaraccesslink.com/v3/users/{user-id} \
  -H 'Authorization: Bearer {access-token}'

DELETE https://www.polaraccesslink.com/v3/users/{user-id} HTTP/1.1
Host: www.polaraccesslink.com

const fetch = require('node-fetch');

const headers = {
  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.delete 'https://www.polaraccesslink.com/v3/users/{user-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Authorization': 'Bearer {access-token}'
};

r = requests.delete('https://www.polaraccesslink.com/v3/users/{user-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

DELETE /v3/users/{user-id}

When partner wishes no longer to receive user data, user can be de-registered.This will revoke the access token authorized by user.

Parameters

Parameter In Type Required Description
user-id path integer(int64) true User identifier

Responses

Status Meaning Description Schema
204 No Content will be returned when user is successfully de-registered. None

Pull notifications

This resource allows partners to check if their users have available data for downloading. Use client credentials authentication. Returns object holding list of available data objects.

List

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/notifications \
  -H 'Accept: application/json'

GET https://www.polaraccesslink.com/v3/notifications HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json'
};

fetch('https://www.polaraccesslink.com/v3/notifications',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/notifications',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json'
};

r = requests.get('https://www.polaraccesslink.com/v3/notifications', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/notifications");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/notifications

Get list of available exercises and activities for users

Example responses

200 Response

{
  "available-user-data": [
    {
      "user-id": 475,
      "data-type": "ACTIVITY_SUMMARY",
      "url": "https://www.polaraccesslink.com/v3/users/475/activity-transactions"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<available-user-datas>
  <available-user-data>
    <user-id>475</user-id>
    <data-type>ACTIVITY_SUMMARY</data-type>
    <url>https://www.polaraccesslink.com/v3/users/475/activity-transactions</url>
  </available-user-data>
</available-user-datas>

Responses

Status Meaning Description Schema
200 OK List of available data available-user-datas
204 No Content No content when no available data found None

Daily activity

This resource allows partners to access their users' daily activity data. During the transfer, the activity data is copied also into the AccessLink database so the end-users cannot change the data that is accessible via AccessLink afterwards. Begin and end of day are determined by the time set on the device used. No timezone information is available. Each transaction will consist of at most 50 activity summaries. Available data presented in section Schemas. Only data that has been uploaded to Flow after the user has been registered to your client will be available. Only data that has been uploaded in the last 30 days will be available.

Create transaction

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions',
{
  method: 'POST',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.post('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/users/{user-id}/activity-transactions

Initiate activity transaction. Check for new activity summaries and create a new transaction if found. Only data uploaded to Flow in the last 30 days will be available. Only data that has been uploaded to Flow after the user is registered with your client will be available.

Parameters

Parameter In Type Required Description
user-id path integer true User identifier

Example responses

201 Response

{
  "transaction-id": 122,
  "resource-uri": "https://polaraccesslink.com/v3/users/21/physical-information-transactions/32"
}
<?xml version="1.0" encoding="UTF-8" ?>
<transaction-location>
  <transaction-id>122</transaction-id>
  <resource-uri>https://polaraccesslink.com/v3/users/21/physical-information-transactions/32</resource-uri>
</transaction-location>

Responses

Status Meaning Description Schema
201 Created Return link to created transaction containing new activity data. transaction-location
204 No Content No content when there is no new activity data available. None
403 Forbidden User has not accepted all mandatory consents. None

List activities

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/activity-transactions/{transaction-id}

List new activity data. After successfully initiating a transaction, activity summaries included within it can be retrieved with the provided transactionId.

Parameters

Parameter In Type Required Description
transaction-id path integer(int64) true Transaction identifier
user-id path integer true User identifier

Example responses

200 Response

{
  "activity-log": [
    "https://www.polaraccesslink.com/v3/users/12/activity-transactions/34/activities/56",
    "https://www.polaraccesslink.com/v3/users/12/activity-transactions/34/activities/120"
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<activity-logs>
  <activity-log>https://www.polaraccesslink.com/v3/users/12/activity-transactions/34/activities/56</activity-log>
  <activity-log>https://www.polaraccesslink.com/v3/users/12/activity-transactions/34/activities/120</activity-log>
</activity-logs>

Responses

Status Meaning Description Schema
200 OK Return list of hyperlinks to activity summaries contained within the transaction. activity-log
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found No transaction was found with given transaction id. None

Commit transaction

Code samples

# You can also use wget
curl -X PUT https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id} \
  -H 'Authorization: Bearer {access-token}'

PUT https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id} HTTP/1.1
Host: www.polaraccesslink.com

const fetch = require('node-fetch');

const headers = {
  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}',
{
  method: 'PUT',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Authorization': 'Bearer {access-token}'
};

r = requests.put('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

PUT /v3/users/{user-id}/activity-transactions/{transaction-id}

After successfully retrieving activity summary data within a transaction, partners are expected to commit the transaction.

Parameters

Parameter In Type Required Description
transaction-id path integer(int64) true Transaction identifier
user-id path integer true User identifier

Responses

Status Meaning Description Schema
200 OK Transaction has been committed and data deleted. None
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get activity summary

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
activity-id path integer true Activity summary identifier

Example responses

200 Response

{
  "id": 1234,
  "polar-user": "https://www.polaraccesslink/v3/users/1",
  "transaction-id": 179879,
  "date": "2010-12-31",
  "created": "2016-04-27T20:11:33.000Z",
  "calories": 2329,
  "active-calories": 428,
  "duration": "PT2H44M",
  "active-steps": 250
}
<?xml version="1.0" encoding="UTF-8" ?>
<activity>
  <id>1234</id>
  <polar-user>https://www.polaraccesslink/v3/users/1</polar-user>
  <transaction-id>179879</transaction-id>
  <date>2010-12-31</date>
  <created>2016-04-27T20:11:33.000Z</created>
  <calories>2329</calories>
  <active-calories>428</active-calories>
  <duration>PT2H44M</duration>
  <active-steps>250</active-steps>
</activity>

Responses

Status Meaning Description Schema
200 OK Return activity summary contained within the transaction. activity
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get step samples

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/step-samples

Get activity step samples. Example data can be seen from appendix.

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
activity-id path integer true Activity summary identifier

Example responses

200 Response

{
  "date": "2022-02-10",
  "interval": 0,
  "samples": [
    {
      "steps": 0,
      "time": "12:37:33.000"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<activity-step-samples>
  <date>2022-02-10</date>
  <interval>0</interval>
  <samples>
    <steps>0</steps>
    <time>12:37:33.000</time>
  </samples>
</activity-step-samples>

Responses

Status Meaning Description Schema
200 OK Return activity step samples. activity-step-samples
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get zone samples

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/activity-transactions/{transaction-id}/activities/{activity-id}/zone-samples

Get activity zone samples. Example data can be seen from appendix.

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
activity-id path integer true Activity summary identifier

Example responses

200 Response

{
  "date": "2022-02-10",
  "interval": 0,
  "samples": [
    {
      "activity-zones": [
        {
          "index": 1,
          "inzone": "PT51M5S"
        }
      ],
      "time": "string"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<activity-zone-samples>
  <date>2022-02-10</date>
  <interval>0</interval>
  <samples>
    <activity-zones>
      <index>1</index>
      <inzone>PT51M5S</inzone>
    </activity-zones>
    <time>string</time>
  </samples>
</activity-zone-samples>

Responses

Status Meaning Description Schema
200 OK Return activity zone samples. activity-zone-samples
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Training data

This resource allows partners to access their users' training data. All time values are UTC except start-time. Start-time is the time set on the training computer. Each transaction will consist of at most 50 training sessions. Available data presented in section Schemas. Only data that has been uploaded to Flow after the user has been registered to your client will be available. Only data that has been uploaded in the last 30 days will be available.

Create transaction

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions',
{
  method: 'POST',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.post('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/users/{user-id}/exercise-transactions

Check for new training data and create a new transaction if found. Only data uploaded to Flow in the last 30 days will be available. Only data that has been uploaded to Flow after the user is registered with your client will be available.

Parameters

Parameter In Type Required Description
user-id path integer true User identifier

Example responses

201 Response

{
  "transaction-id": 122,
  "resource-uri": "https://polaraccesslink.com/v3/users/21/physical-information-transactions/32"
}
<?xml version="1.0" encoding="UTF-8" ?>
<transaction-location>
  <transaction-id>122</transaction-id>
  <resource-uri>https://polaraccesslink.com/v3/users/21/physical-information-transactions/32</resource-uri>
</transaction-location>

Responses

Status Meaning Description Schema
201 Created Return link to created transaction containing new training session data. transaction-location
204 No Content No content when there is no new training session data available. None
403 Forbidden User has not accepted all mandatory consents. None

List exercises

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}

After successfully initiating a transaction, training sessions included within it can be retrieved with the provided transactionId.

Parameters

Parameter In Type Required Description
transaction-id path integer(int64) true Transaction identifier
user-id path integer true User identifier

Example responses

200 Response

{
  "exercises": [
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56",
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/120"
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<exercises>
  <exercise>https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56</exercise>
  <exercise>https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/120</exercise>
</exercises>

Responses

Status Meaning Description Schema
200 OK Return list of hyperlinks to training sessions contained within the transaction. exercises
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Commit transaction

Code samples

# You can also use wget
curl -X PUT https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id} \
  -H 'Authorization: Bearer {access-token}'

PUT https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id} HTTP/1.1
Host: www.polaraccesslink.com

const fetch = require('node-fetch');

const headers = {
  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}',
{
  method: 'PUT',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Authorization': 'Bearer {access-token}'
};

r = requests.put('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

PUT /v3/users/{user-id}/exercise-transactions/{transaction-id}

After successfully retrieving training session data within a transaction, partners are expected to commit the transaction.

Parameters

Parameter In Type Required Description
transaction-id path integer(int64) true Transaction identifier
user-id path integer true User identifier

Responses

Status Meaning Description Schema
200 OK Transaction has been committed and data deleted. None
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found No transaction was found with given transaction id. None

Get exercise summary

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}

Retrieve training session summary data

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier

Example responses

200 Response

{
  "id": 1937529874,
  "upload-time": "2008-10-13T10:40:0.000Z",
  "polar-user": "https://www.polaraccesslink/v3/users/1",
  "transaction-id": 179879,
  "device": "Polar M400",
  "device-id": "1111AAAA",
  "start-time": "2008-10-13T10:40:02",
  "start-time-utc-offset": 180,
  "duration": "PT2H44M45S",
  "calories": 530,
  "distance": 1600.2,
  "heart-rate": {
    "average": 129,
    "maximum": 147
  },
  "training-load": 143.22,
  "sport": "OTHER",
  "has-route": true,
  "club-id": 999,
  "club-name": "Polar Club",
  "detailed-sport-info": "RUNNING",
  "fat-percentage": 60,
  "carbohydrate-percentage": 38,
  "protein-percentage": 2,
  "running-index": 51,
  "training-load-pro": [
    {
      "date": "2023-01-01",
      "cardio-load": 1,
      "muscle-load": 1,
      "perceived-load": 1,
      "cardio-load-interpretation": "UNKNOWN",
      "muscle-load-interpretation": "UNKNOWN",
      "perceived-load-interpretation": "UNKNOWN",
      "user-rpe": "UNKNOWN"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<exercise>
  <id>1937529874</id>
  <upload-time>2008-10-13T10:40:0.000Z</upload-time>
  <polar-user>https://www.polaraccesslink/v3/users/1</polar-user>
  <transaction-id>179879</transaction-id>
  <device>Polar M400</device>
  <device-id>1111AAAA</device-id>
  <start-time>2008-10-13T10:40:02</start-time>
  <start-time-utc-offset>180</start-time-utc-offset>
  <duration>PT2H44M45S</duration>
  <calories>530</calories>
  <distance>1600.2</distance>
  <heart-rate>
    <average>129</average>
    <maximum>147</maximum>
  </heart-rate>
  <training-load>143.22</training-load>
  <sport>OTHER</sport>
  <has-route>true</has-route>
  <club-id>999</club-id>
  <club-name>Polar Club</club-name>
  <detailed-sport-info>RUNNING</detailed-sport-info>
  <fat-percentage>60</fat-percentage>
  <carbohydrate-percentage>38</carbohydrate-percentage>
  <protein-percentage>2</protein-percentage>
  <running-index>51</running-index>
  <training-load-pro>
    <date>2023-01-01</date>
    <cardio-load>1</cardio-load>
    <muscle-load>1</muscle-load>
    <perceived-load>1</perceived-load>
    <cardio-load-interpretation>UNKNOWN</cardio-load-interpretation>
    <muscle-load-interpretation>UNKNOWN</muscle-load-interpretation>
    <perceived-load-interpretation>UNKNOWN</perceived-load-interpretation>
    <user-rpe>UNKNOWN</user-rpe>
  </training-load-pro>
</exercise>

Responses

Status Meaning Description Schema
200 OK Exercise summary. exercise
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get FIT

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit \
  -H 'Accept: */*' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit HTTP/1.1
Host: www.polaraccesslink.com
Accept: */*

const fetch = require('node-fetch');

const headers = {
  'Accept':'*/*',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': '*/*',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/fit

Retrieve exercise in FIT format. See FIT sport mappings in appendix.

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Return FIT file. string
204 No Content No FIT available for exercise. None
403 Forbidden User has not accepted all mandatory consents. None

Get GPX

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx \
  -H 'Accept: application/gpx+xml' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/gpx+xml

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/gpx+xml',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/gpx+xml',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/gpx+xml',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/gpx

Retrieve training session summary data in GPX format

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier
includePauseTimes query boolean false Whether to add pauses as part of the route. Default is false.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Return training session in GPX (GPS Exchange format). string
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get heart rate zones

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/heart-rate-zones

Retrieve heart rate zones in training session

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier

Example responses

200 Response

{
  "zone": [
    {
      "index": 1,
      "lower-limit": 110,
      "upper-limit": 130,
      "in-zone": "PT4S"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<zones>
  <zone>
    <index>1</index>
    <lower-limit>110</lower-limit>
    <upper-limit>130</upper-limit>
    <in-zone>PT4S</in-zone>
  </zone>
</zones>

Responses

Status Meaning Description Schema
200 OK Return heart rate zones in training session. zones
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get available samples

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples

Retrieve list of links to available samples in training session

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier

Example responses

200 Response

{
  "samples": [
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56/samples/0",
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56/samples/3"
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<samples>
  <samples>https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56/samples/0</samples>
  <samples>https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56/samples/3</samples>
</samples>

Responses

Status Meaning Description Schema
200 OK Return list of hyperlinks to available samples in training session. samples
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get samples

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/samples/{type-id}

Retrieve sample data of given type

Parameters

Parameter In Type Required Description
type-id path string(byte) true Sample type id
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier

Example responses

200 Response

{
  "recording-rate": 5,
  "sample-type": "1",
  "data": "0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122"
}
<?xml version="1.0" encoding="UTF-8" ?>
<sample>
  <recording-rate>5</recording-rate>
  <sample-type>1</sample-type>
  <data>0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122</data>
</sample>

Responses

Status Meaning Description Schema
200 OK Return sample data. sample
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get TCX

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx \
  -H 'Accept: application/vnd.garmin.tcx+xml' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/vnd.garmin.tcx+xml

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/vnd.garmin.tcx+xml',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/vnd.garmin.tcx+xml',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/vnd.garmin.tcx+xml',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/exercise-transactions/{transaction-id}/exercises/{exercise-id}/tcx

Retrieve exercise in TCX format

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
exercise-id path integer true Exercise identifier

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Return gzipped TCX. string
204 No Content No TCX available for exercise. None
403 Forbidden User has not accepted all mandatory consents. None

Physical info

This resource allows partners to access their users' physical information. Whenever some user's physical information changes, new entry containing full physical info is stored to AccessLink. Pull notifications can be used to check if user have new physical information available. Available data presented in section Schemas.

Create transaction

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions',
{
  method: 'POST',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.post('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/users/{user-id}/physical-information-transactions

Initiate physical info transaction. Check for new physical info and create a new transaction if found.

Parameters

Parameter In Type Required Description
user-id path integer true User identifier

Example responses

201 Response

{
  "transaction-id": 122,
  "resource-uri": "https://polaraccesslink.com/v3/users/21/physical-information-transactions/32"
}
<?xml version="1.0" encoding="UTF-8" ?>
<transaction-location>
  <transaction-id>122</transaction-id>
  <resource-uri>https://polaraccesslink.com/v3/users/21/physical-information-transactions/32</resource-uri>
</transaction-location>

Responses

Status Meaning Description Schema
201 Created Return link to created transaction containing new physical info data. transaction-location
204 No Content No content when there is no new physical info data available. None
403 Forbidden User has not accepted all mandatory consents. None

List physical infos

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/physical-information-transactions/{transaction-id}

List new physical info data. After successfully initiating a transaction, physical infos included within it can be retrieved with the provided transactionId.

Parameters

Parameter In Type Required Description
transaction-id path integer(int64) true Transaction identifier
user-id path integer true User identifier

Example responses

200 Response

{
  "physical-informations": [
    "https://www.polaraccesslink.com/v3/users/12/physical-information-transactions/12/physical-informations/56",
    "https://www.polaraccesslink.com/v3/users/12/physical-information-transactions/12/physical-informations/120"
  ]
}
<?xml version="1.0" encoding="UTF-8" ?>
<physical-informations>
  <physical-information>https://www.polaraccesslink.com/v3/users/12/physical-information-transactions/12/physical-informations/56</physical-information>
  <physical-information>https://www.polaraccesslink.com/v3/users/12/physical-information-transactions/12/physical-informations/120</physical-information>
</physical-informations>

Responses

Status Meaning Description Schema
200 OK Return list of hyperlinks to physical information contained within the transaction. physical-informations
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found No transaction was found with given transaction id. None

Commit transaction

Code samples

# You can also use wget
curl -X PUT https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id} \
  -H 'Authorization: Bearer {access-token}'

PUT https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id} HTTP/1.1
Host: www.polaraccesslink.com

const fetch = require('node-fetch');

const headers = {
  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}',
{
  method: 'PUT',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Authorization': 'Bearer {access-token}'
};

r = requests.put('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

PUT /v3/users/{user-id}/physical-information-transactions/{transaction-id}

After successfully retrieving physical information within a transaction, partners are expected to commit the transaction.

Parameters

Parameter In Type Required Description
transaction-id path integer(int64) true Transaction identifier
user-id path integer true User identifier

Responses

Status Meaning Description Schema
200 OK Transaction has been committed and data deleted. None
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Get physical info

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/{user-id}/physical-information-transactions/{transaction-id}/physical-informations/{physical-info-id}

Get physical info entity data

Parameters

Parameter In Type Required Description
user-id path integer true User identifier
transaction-id path integer true Transaction identifier
physical-info-id path integer true Physical information identifier

Example responses

200 Response

{
  "id": 123,
  "transaction-id": 179879,
  "created": "2016-04-27T20:11:33.000Z",
  "polar-user": "https://www.polaraccesslink/v3/users/1",
  "weight": 80,
  "height": 180,
  "maximum-heart-rate": 160,
  "resting-heart-rate": 60,
  "aerobic-threshold": 123,
  "anaerobic-threshold": 123,
  "vo2-max": 12,
  "weight-source": "SOURCE_MEASURED"
}
<?xml version="1.0" encoding="UTF-8" ?>
<physical-information>
  <id>123</id>
  <transaction-id>179879</transaction-id>
  <created>2016-04-27T20:11:33.000Z</created>
  <polar-user>https://www.polaraccesslink/v3/users/1</polar-user>
  <weight>80</weight>
  <height>180</height>
  <maximum-heart-rate>160</maximum-heart-rate>
  <resting-heart-rate>60</resting-heart-rate>
  <aerobic-threshold>123</aerobic-threshold>
  <anaerobic-threshold>123</anaerobic-threshold>
  <vo2-max>12</vo2-max>
  <weight-source>SOURCE_MEASURED</weight-source>
</physical-information>

Responses

Status Meaning Description Schema
200 OK Physical information. physical-information
204 No Content No content when there is no data available. None
403 Forbidden User has not accepted all mandatory consents. None

Continuous Heart Rate

This resource allows partners to access their users' continuous heart rate data. Continuous heart rate is recorded with supported devices when the heart rate tracking is turned on in device settings. Samples are recording in 5 minute intervals. Heart rate samples from training sessions are not available through this resource. Training sessions samples have more precise sampling interval and they can be accessed from the training data resource. Supported devices

Get Continuous Heart rate samples

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/continuous-heart-rate/{date} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/continuous-heart-rate/{date} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/continuous-heart-rate/{date}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/continuous-heart-rate/{date}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/continuous-heart-rate/{date}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/continuous-heart-rate/{date}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/continuous-heart-rate/{date}

Get users continuous heart rate values for given date. Supported devices

Parameters

Parameter In Type Required Description
date path string(date) true Date of Continuous Heart Rate as ISO-8601 date string, example: "2022-01-01"

Example responses

200 Response

{
  "polar_user": "https://polaraccesslink.com/v3/users/627139",
  "date": "2022-09-12",
  "heart_rate_samples": [
    {
      "heart_rate": 63,
      "sample_time": "00:02:08"
    },
    {
      "heart_rate": 62,
      "sample_time": "00:07:08"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Request was successful. continuous-heartrate
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found No data found for date. None

Elixir™ Biosensing (Beta)

This resource allows partners to access their users' Elixir™ Biosensing data. All time values are UTC times. Elixir™ Biosensing data consists of body temperature data, sleep skin temperature data, skin contacts data, wrist ECG test report data and SpO2 test report data.

Body temperature data

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/biosensing/bodytemperature \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/biosensing/bodytemperature HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/biosensing/bodytemperature',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/biosensing/bodytemperature',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/biosensing/bodytemperature', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/biosensing/bodytemperature");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/biosensing/bodytemperature

Get user's body temperature data for last 28 days or for given date range. Maximum date range between from and to cannot be more than 28 days.

Parameters

Parameter In Type Required Description
from query string(date) false Inclusive start date of range as ISO-8601 date string, example: "2023-10-01"
to query string(date) false Inclusive end date of range as ISO-8601 date string, example: "2023-10-28"

Example responses

200 Response

[
  {
    "source_device_id": "1111AAAA",
    "measurement_type": "TM_CORE_TEMPERATURE",
    "sensor_location": "SL_PROXIMAL",
    "start_time": "2023-10-20T04:00:00",
    "end_time": "2023-10-20T05:00:00",
    "modified_time": "2023-10-20T04:00:00",
    "samples": [
      {
        "temperature_celsius": 36.5,
        "recording_time_delta_milliseconds": 123
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [body-temperature-period] false none none
» source_device_id string false none none
» measurement_type string false none Measurement type
» sensor_location string false none Sensor location
» start_time string(date-time) false none Measurement period start time (UTC)
» end_time string(date-time) false none Measurement period end time (UTC)
» modified_time string(date-time) false none Measurement period modified time (UTC)
» samples [body-temperature-sample] false none none
»» temperature_celsius number(float) false none none
»» recording_time_delta_milliseconds integer(int64) false none none

Enumerated Values

Property Value
measurement_type TM_UNKNOWN
measurement_type TM_SKIN_TEMPERATURE
measurement_type TM_CORE_TEMPERATURE
sensor_location SL_UNKNOWN
sensor_location SL_DISTAL
sensor_location SL_PROXIMAL

Sleep skin temperature data

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/biosensing/skintemperature \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/biosensing/skintemperature HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/biosensing/skintemperature',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/biosensing/skintemperature',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/biosensing/skintemperature', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/biosensing/skintemperature");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/biosensing/skintemperature

Get user's sleep skin temperature data for last 28 days or for given date range. Maximum date range between from and to cannot be more than 28 days.

Parameters

Parameter In Type Required Description
from query string(date) false Inclusive start date of range as ISO-8601 date string, example: "2023-10-01"
to query string(date) false Inclusive end date of range as ISO-8601 date string, example: "2023-10-28"

Example responses

200 Response

[
  {
    "sleep_time_skin_temperature_celsius": 36.5,
    "deviation_from_baseline_celsius": 0.5,
    "sleep_date": "2023-10-20"
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [skin-temperature] false none none
» sleep_time_skin_temperature_celsius number(float) false none none
» deviation_from_baseline_celsius number(float) false none none
» sleep_date string(date) false none none

Skin contacts data

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/biosensing/skincontacts \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/biosensing/skincontacts HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/biosensing/skincontacts',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/biosensing/skincontacts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/biosensing/skincontacts', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/biosensing/skincontacts");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/biosensing/skincontacts

Get user's skin contacts data for last 28 days or for given date range. Maximum date range between from and to cannot be more than 28 days.

Parameters

Parameter In Type Required Description
from query string(date) false Inclusive start date of range as ISO-8601 date string, example: "2023-10-01"
to query string(date) false Inclusive end date of range as ISO-8601 date string, example: "2023-10-28"

Example responses

200 Response

[
  {
    "source_device_id": "1111AAAA",
    "start_time": "2023-10-20T04:00:00",
    "end_time": "2023-10-20T05:00:00",
    "modified_time": "2023-10-20T04:00:00",
    "skin_contact_changes": [
      {
        "skin_contact": true,
        "recording_time_delta_milliseconds": 123
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [skin-contact-period] false none none
» source_device_id string false none none
» start_time string(date-time) false none Measurement period start time (UTC)
» end_time string(date-time) false none Measurement period end time (UTC)
» modified_time string(date-time) false none Measurement period modified time (UTC)
» skin_contact_changes [skin-contact-change] false none none
»» skin_contact boolean false none none
»» recording_time_delta_milliseconds integer(int64) false none none

Wrist ECG test result data

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/biosensing/ecg \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/biosensing/ecg HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/biosensing/ecg',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/biosensing/ecg',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/biosensing/ecg', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/biosensing/ecg");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/biosensing/ecg

Get user's wrist ECG test result data for last 28 days or for given date range. Maximum date range between from and to cannot be more than 28 days.

Parameters

Parameter In Type Required Description
from query string(date) false Inclusive start date of range as ISO-8601 date string, example: "2023-10-01"
to query string(date) false Inclusive end date of range as ISO-8601 date string, example: "2023-10-28"

Example responses

200 Response

[
  {
    "source_device_id": "1111AAAA",
    "test_time": 1697787256,
    "time_zone_offset": 180,
    "average_heart_rate_bpm": 60,
    "heart_rate_variability_ms": 0,
    "heart_rate_variability_level": "ECG_HRV_LEVEL_NO_BASELINE",
    "rri_ms": 100,
    "pulse_transit_time_systolic_ms": 100,
    "pulse_transit_time_diastolic_ms": 100,
    "pulse_transit_time_quality_index": 100,
    "samples": [
      {
        "recording_time_delta_ms": 123,
        "amplitude_mv": 0.1
      }
    ],
    "quality_measurements": [
      {
        "recording_time_delta_ms": 123,
        "quality_level": "ECG_QUALITY_HIGH"
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [ecg-test-result] false none none
» source_device_id string false none none
» test_time integer(int64) false none none
» time_zone_offset integer(int32) false none none
» average_heart_rate_bpm integer(uint32) false none none
» heart_rate_variability_ms number(float) false none none
» heart_rate_variability_level string false none none
» rri_ms number(float) false none none
» pulse_transit_time_systolic_ms number(float) false none none
» pulse_transit_time_diastolic_ms number(float) false none none
» pulse_transit_time_quality_index number(float) false none none
» samples [ecg-sample] false none none
»» recording_time_delta_ms integer(int32) false none none
»» amplitude_mv number(float) false none none
» quality_measurements [quality-measurement] false none none
»» recording_time_delta_ms integer(int32) false none none
»» quality_level string false none none

Enumerated Values

Property Value
heart_rate_variability_level ECG_HRV_LEVEL_NO_BASELINE
heart_rate_variability_level ECG_HRV_LEVEL_BELOW_USUAL
heart_rate_variability_level ECG_HRV_LEVEL_USUAL
heart_rate_variability_level ECG_HRV_LEVEL_ABOVE_USUAL
quality_level ECG_QUALITY_UNKNOWN
quality_level ECG_QUALITY_NO_CONTACT
quality_level ECG_QUALITY_LOW
quality_level ECG_QUALITY_HIGH

SpO2 test result data

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/biosensing/spo2 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/biosensing/spo2 HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/biosensing/spo2',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/biosensing/spo2',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/biosensing/spo2', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/biosensing/spo2");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/biosensing/spo2

Get user's SpO2 test result data for last 28 days or for given date range. Maximum date range between from and to cannot be more than 28 days.

Parameters

Parameter In Type Required Description
from query string(date) false Inclusive start date of range as ISO-8601 date string, example: "2023-10-01"
to query string(date) false Inclusive end date of range as ISO-8601 date string, example: "2023-10-28"

Example responses

200 Response

[
  {
    "source_device_id": "1111AAAA",
    "test_time": 1697787256,
    "time_zone_offset": 180,
    "test_status": "SPO2_TEST_PASSED",
    "blood_oxygen_percent": 95,
    "spo2_class": "SPO2_CLASS_NORMAL",
    "spo2_value_deviation_from_baseline": "DEVIATION_NO_BASELINE",
    "spo2_quality_average_percent": 90,
    "average_heart_rate_bpm": 60,
    "heart_rate_variability_ms": 100,
    "spo2_hrv_deviation_from_baseline": "DEVIATION_NO_BASELINE",
    "altitude_meters": 50
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [spo2-test-result] false none none
» source_device_id string false none none
» test_time integer(int64) false none none
» time_zone_offset integer(int32) false none none
» test_status string false none none
» blood_oxygen_percent integer(int32) false none none
» spo2_class string false none none
» spo2_value_deviation_from_baseline string false none none
» spo2_quality_average_percent number(float) false none none
» average_heart_rate_bpm integer(uint32) false none none
» heart_rate_variability_ms number(float) false none none
» spo2_hrv_deviation_from_baseline string false none none
» altitude_meters number(float) false none none

Enumerated Values

Property Value
test_status SPO2_TEST_PASSED
test_status SPO2_TEST_INCONCLUSIVE_TOO_LOW_QUALITY_IN_SAMPLES
test_status SPO2_TEST_INCONCLUSIVE_TOO_LOW_OVERALL_QUALITY
test_status SPO2_TEST_INCONCLUSIVE_TOO_MANY_MISSING_SAMPLES
spo2_class SPO2_CLASS_UNKNOWN
spo2_class SPO2_CLASS_VERY_LOW
spo2_class SPO2_CLASS_LOW
spo2_class SPO2_CLASS_NORMAL
spo2_value_deviation_from_baseline DEVIATION_NO_BASELINE
spo2_value_deviation_from_baseline DEVIATION_BELOW_USUAL
spo2_value_deviation_from_baseline DEVIATION_USUAL
spo2_value_deviation_from_baseline DEVIATION_ABOVE_USUAL
spo2_hrv_deviation_from_baseline DEVIATION_NO_BASELINE
spo2_hrv_deviation_from_baseline DEVIATION_BELOW_USUAL
spo2_hrv_deviation_from_baseline DEVIATION_USUAL
spo2_hrv_deviation_from_baseline DEVIATION_ABOVE_USUAL

Webhooks

Webhook resources provides endpoints for creating, modifying and deleting webhooks.

Create webhook

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/webhooks \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://www.polaraccesslink.com/v3/webhooks HTTP/1.1
Host: www.polaraccesslink.com
Content-Type: application/json
Accept: application/json

const fetch = require('node-fetch');
const inputBody = '{
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
}';
const headers = {
  'Content-Type':'application/json',  'Accept':'application/json'
};

fetch('https://www.polaraccesslink.com/v3/webhooks',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://www.polaraccesslink.com/v3/webhooks',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
input_body = {
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
};
headers = {
  'Content-Type': 'application/json',  'Accept': 'application/json'
};

r = requests.post('https://www.polaraccesslink.com/v3/webhooks', headers = headers
    , json=input_body)

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/webhooks");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/webhooks

Create new webhook.

When creating webhook the AccessLink sends a ping message to the url in request body. The ping message must be answered with 200 OK or otherwise the webhook is not created.

Created webhook is by default in activated state and will send push notifications about subscribed events. Webhook will be automatically deactivated if push notifications have not been successful for a period of seven (7) days. Note! Save the signature_secret_key from response since this is the only chance to get it.

Body parameter

{
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
}

Parameters

Parameter In Type Required Description
body body webhookRequest true Webhook to create.
» events body [webhookType] true Type of events to subscribe.
» url body string(uri) true Url where the webhook notification is sent.

Enumerated Values

Parameter Value
» events EXERCISE, SLEEP, CONTINUOUS_HEART_RATE, SLEEP_WISE_CIRCADIAN_BEDTIME, SLEEP_WISE_ALERTNESS

Example responses

201 Response

{
  "data": {
    "id": "abdf33",
    "events": [
      "EXERCISE"
    ],
    "url": "https://myapp.example.com/acl_webhook",
    "signature_secret_key": "abe1f3ae-fd33-11e8-8eb2-f2801f1b9fd1"
  }
}

Responses

Status Meaning Description Schema
201 Created Created webhook. createdWebhook
400 Bad Request Webhook cannot be created. error
409 Conflict Webhook already exists. error

Get webhook

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/webhooks \
  -H 'Accept: application/json'

GET https://www.polaraccesslink.com/v3/webhooks HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json'
};

fetch('https://www.polaraccesslink.com/v3/webhooks',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/webhooks',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json'
};

r = requests.get('https://www.polaraccesslink.com/v3/webhooks', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/webhooks");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/webhooks

Returns created webhook if exists.

Example responses

200 Response

{
  "data": {
    "id": "abdf33",
    "events": [
      "EXERCISE"
    ],
    "url": "https://myapp.example.com/acl_webhook",
    "active": true
  }
}

Responses

Status Meaning Description Schema
200 OK Existing webhook. webhookInfo

Activate webhook

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/webhooks/activate

POST https://www.polaraccesslink.com/v3/webhooks/activate HTTP/1.1
Host: www.polaraccesslink.com

const fetch = require('node-fetch');

fetch('https://www.polaraccesslink.com/v3/webhooks/activate',
{
  method: 'POST'

})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

result = RestClient.post 'https://www.polaraccesslink.com/v3/webhooks/activate',
  params: {
  }

p JSON.parse(result)

import requests

r = requests.post('https://www.polaraccesslink.com/v3/webhooks/activate'
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/webhooks/activate");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/webhooks/activate

Activate deactivated webhook. Activation is successful if the configured webhook url returns HTTP status 200 (OK) for the issued ping request.

Responses

Status Meaning Description Schema
200 OK Webhook has been successfully activated. None
204 No Content Webhook does not exits and it cannot be activated. None

Deactivate webhook

Code samples

# You can also use wget
curl -X POST https://www.polaraccesslink.com/v3/webhooks/deactivate

POST https://www.polaraccesslink.com/v3/webhooks/deactivate HTTP/1.1
Host: www.polaraccesslink.com

const fetch = require('node-fetch');

fetch('https://www.polaraccesslink.com/v3/webhooks/deactivate',
{
  method: 'POST'

})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

result = RestClient.post 'https://www.polaraccesslink.com/v3/webhooks/deactivate',
  params: {
  }

p JSON.parse(result)

import requests

r = requests.post('https://www.polaraccesslink.com/v3/webhooks/deactivate'
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/webhooks/deactivate");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

POST /v3/webhooks/deactivate

Deactivate activated webhook. Deactivated webhook does not push notifications about subscribed events.

Responses

Status Meaning Description Schema
200 OK Webhook has been successfully deactivated. None
204 No Content Webhook does not exits and it cannot be deactivated. None

Update webhook

Code samples

# You can also use wget
curl -X PATCH https://www.polaraccesslink.com/v3/webhooks/{webhook-id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PATCH https://www.polaraccesslink.com/v3/webhooks/{webhook-id} HTTP/1.1
Host: www.polaraccesslink.com
Content-Type: application/json
Accept: application/json

const fetch = require('node-fetch');
const inputBody = '{
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
}';
const headers = {
  'Content-Type':'application/json',  'Accept':'application/json'
};

fetch('https://www.polaraccesslink.com/v3/webhooks/{webhook-id}',
{
  method: 'PATCH',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.patch 'https://www.polaraccesslink.com/v3/webhooks/{webhook-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
input_body = {
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
};
headers = {
  'Content-Type': 'application/json',  'Accept': 'application/json'
};

r = requests.patch('https://www.polaraccesslink.com/v3/webhooks/{webhook-id}', headers = headers
    , json=input_body)

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/webhooks/{webhook-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PATCH");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

PATCH /v3/webhooks/{webhook-id}

Edit webhook event types and/or url.

When updating webhook url the AccessLink sends a ping message to the new address. The ping message must be answered with 200 OK or otherwise the webhook is not updated.

Body parameter

{
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
}

Parameters

Parameter In Type Required Description
webhook-id path string true Webhook id to update
body body webhookPatch true New value(s) for events and/or url.
» events body [webhookType] false Type of events to subscribe.
» url body string(uri) false Url where the webhook notification is sent.

Enumerated Values

Parameter Value
» events EXERCISE, SLEEP, CONTINUOUS_HEART_RATE, SLEEP_WISE_CIRCADIAN_BEDTIME, SLEEP_WISE_ALERTNESS

Example responses

200 Response

{
  "data": {
    "id": "abdf33",
    "events": [
      "EXERCISE"
    ],
    "url": "https://myapp.example.com/acl_webhook",
    "active": true
  }
}

Responses

Status Meaning Description Schema
200 OK Webhook updated successfully. webhookInfo
400 Bad Request Webhook cannot be updated. error
404 Not Found Webhook not found. error

Delete webhook

Code samples

# You can also use wget
curl -X DELETE https://www.polaraccesslink.com/v3/webhooks/{webhook-id} \
  -H 'Accept: application/json'

DELETE https://www.polaraccesslink.com/v3/webhooks/{webhook-id} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json'
};

fetch('https://www.polaraccesslink.com/v3/webhooks/{webhook-id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.delete 'https://www.polaraccesslink.com/v3/webhooks/{webhook-id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json'
};

r = requests.delete('https://www.polaraccesslink.com/v3/webhooks/{webhook-id}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/webhooks/{webhook-id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

DELETE /v3/webhooks/{webhook-id}

Delete webhook by id.

Parameters

Parameter In Type Required Description
webhook-id path string true Webhook id to delete

Example responses

404 Response

{
  "timestamp": "2019-08-24T14:15:22Z",
  "status": 0,
  "errorType": "string",
  "message": "string",
  "corrId": "string"
}

Responses

Status Meaning Description Schema
204 No Content Webhook deleted successfully. None
404 Not Found Webhook not found. error

Exercises

Resources for getting information about exercise. These endpoints does not require active transaction, but they use hashed id.

List exercises

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/exercises \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/exercises HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/exercises',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/exercises',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/exercises', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/exercises");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/exercises

List users exercises available in AccessLink. Only Exercises uploaded to Flow in the last 30 days are returned. Only exercises that have been uploaded to Flow after the user is registered with your client will be returned. Use samples and zones query parameters to return optional samples and zone information of the exercises. Training Load Pro data will be included in the exercise object if the exercise is recorded with a specific wrist unit model, please check compatible devices for more information.

Parameters

Parameter In Type Required Description
samples query boolean false Return all sample data for this exercise.
zones query boolean false Return all zones data for this exercise.
route query boolean false Return all route data for this exercise.

Example responses

200 Response

[
  {
    "id": "2AC312F",
    "upload_time": "2008-10-13T10:40:02.000Z",
    "polar_user": "https://www.polaraccesslink/v3/users/1",
    "device": "Polar M400",
    "device_id": "1111AAAA",
    "start_time": "2008-10-13T10:40:02",
    "start_time_utc_offset": 180,
    "duration": "PT2H44M",
    "calories": 530,
    "distance": 1600,
    "heart_rate": {
      "average": 129,
      "maximum": 147
    },
    "training_load": 143.22,
    "sport": "OTHER",
    "has_route": true,
    "club_id": 999,
    "club_name": "Polar Club",
    "detailed_sport_info": "WATERSPORTS_WATERSKI",
    "fat_percentage": 60,
    "carbohydrate_percentage": 38,
    "protein_percentage": 2,
    "running-index": 51,
    "heart_rate_zones": [
      {
        "index": 1,
        "lower-limit": 110,
        "upper-limit": 130,
        "in-zone": "PT4S"
      }
    ],
    "samples": [
      {
        "recording-rate": 5,
        "sample-type": "1",
        "data": "0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122"
      }
    ],
    "route": [
      {
        "latitude": 60.21982833,
        "longitude": 25.13925,
        "time": "PT210.026S",
        "satellites": 4,
        "fix": 1
      }
    ],
    "training_load_pro": [
      {
        "date": "2023-01-01",
        "cardio-load": 1,
        "muscle-load": 1,
        "perceived-load": 1,
        "cardio-load-interpretation": "UNKNOWN",
        "muscle-load-interpretation": "UNKNOWN",
        "perceived-load-interpretation": "UNKNOWN",
        "user-rpe": "UNKNOWN"
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK List of users exercises. exercisesHashId
403 Forbidden User has not accepted all mandatory consents. None

Get exercise

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/exercises/{exerciseId} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/exercises/{exerciseId} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/exercises/{exerciseId}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/exercises/{exerciseId}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/exercises/{exerciseId}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/exercises/{exerciseId}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/exercises/{exerciseId}

Get users exercise using hashed id. Only Exercises uploaded to Flow in the last 30 days are available. Only exercises that have been uploaded to Flow after the user is registered with your client will be available. Use samples and zones query parameters to return optional samples and zone information of the exercise.

Parameters

Parameter In Type Required Description
exerciseId path string true Hashed exercise id.
samples query boolean false Return all sample data for this exercise.
zones query boolean false Return all zones data for this exercise.
route query boolean false Return all route data for this exercise.

Example responses

200 Response

{
  "id": "2AC312F",
  "upload_time": "2008-10-13T10:40:02.000Z",
  "polar_user": "https://www.polaraccesslink/v3/users/1",
  "device": "Polar M400",
  "device_id": "1111AAAA",
  "start_time": "2008-10-13T10:40:02",
  "start_time_utc_offset": 180,
  "duration": "PT2H44M",
  "calories": 530,
  "distance": 1600,
  "heart_rate": {
    "average": 129,
    "maximum": 147
  },
  "training_load": 143.22,
  "sport": "OTHER",
  "has_route": true,
  "club_id": 999,
  "club_name": "Polar Club",
  "detailed_sport_info": "WATERSPORTS_WATERSKI",
  "fat_percentage": 60,
  "carbohydrate_percentage": 38,
  "protein_percentage": 2,
  "running-index": 51,
  "heart_rate_zones": [
    {
      "index": 1,
      "lower-limit": 110,
      "upper-limit": 130,
      "in-zone": "PT4S"
    }
  ],
  "samples": [
    {
      "recording-rate": 5,
      "sample-type": "1",
      "data": "0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122"
    }
  ],
  "route": [
    {
      "latitude": 60.21982833,
      "longitude": 25.13925,
      "time": "PT210.026S",
      "satellites": 4,
      "fix": 1
    }
  ],
  "training_load_pro": [
    {
      "date": "2023-01-01",
      "cardio-load": 1,
      "muscle-load": 1,
      "perceived-load": 1,
      "cardio-load-interpretation": "UNKNOWN",
      "muscle-load-interpretation": "UNKNOWN",
      "perceived-load-interpretation": "UNKNOWN",
      "user-rpe": "UNKNOWN"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Exercise information. exerciseHashId
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found Exercise not found. None

Get exercise FIT

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/exercises/{exerciseId}/fit \
  -H 'Accept: */*' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/exercises/{exerciseId}/fit HTTP/1.1
Host: www.polaraccesslink.com
Accept: */*

const fetch = require('node-fetch');

const headers = {
  'Accept':'*/*',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/exercises/{exerciseId}/fit',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/exercises/{exerciseId}/fit',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': '*/*',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/exercises/{exerciseId}/fit', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/exercises/{exerciseId}/fit");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/exercises/{exerciseId}/fit

FIT file for users exercise. Only Exercises uploaded to Flow in the last 30 days are available. Only exercises that have been uploaded to Flow after the user is registered with your client will be available. See FIT sport mappings in appendix.

Parameters

Parameter In Type Required Description
exerciseId path string true Hashed exercise id.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Return FIT file. string
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found Exercise not found. None

Get exercise TCX

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/exercises/{exerciseId}/tcx \
  -H 'Accept: application/vnd.garmin.tcx+xml' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/exercises/{exerciseId}/tcx HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/vnd.garmin.tcx+xml

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/vnd.garmin.tcx+xml',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/exercises/{exerciseId}/tcx',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/vnd.garmin.tcx+xml',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/exercises/{exerciseId}/tcx',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/vnd.garmin.tcx+xml',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/exercises/{exerciseId}/tcx', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/exercises/{exerciseId}/tcx");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/exercises/{exerciseId}/tcx

TCX file for users exercise without an AccessLink "transaction". Only Exercises uploaded to Flow in the last 30 days are available. Only exercises that have been uploaded to Flow after the user is registered with your client will be available.

Parameters

Parameter In Type Required Description
exerciseId path string true Hashed exercise id.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Return gzipped TCX. string
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found Exercise not found. None

Get exercise GPX

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/exercises/{exerciseId}/gpx \
  -H 'Accept: application/gpx+xml' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/exercises/{exerciseId}/gpx HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/gpx+xml

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/gpx+xml',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/exercises/{exerciseId}/gpx',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/gpx+xml',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/exercises/{exerciseId}/gpx',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/gpx+xml',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/exercises/{exerciseId}/gpx', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/exercises/{exerciseId}/gpx");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/exercises/{exerciseId}/gpx

GPX file for users exercise without an AccessLink "transaction". Only Exercises uploaded to Flow in the last 30 days are available. Only exercises that have been uploaded to Flow after the user is registered with your client will be available.

Parameters

Parameter In Type Required Description
exerciseId path string true Hashed exercise id.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Return exercise in GPX (GPS Exchange format). string
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found Exercise not found. None

Sleep

Sleep endpoints support Polar Sleep Plus™ and Sleep Plus Stages™. Available data is presented in section Schemas.

List nights

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleep \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleep HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleep',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleep',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleep', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleep");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleep

List sleep data of user for the last 28 days.

Example responses

200 Response

{
  "nights": [
    {
      "polar_user": "https://www.polaraccesslink/v3/users/1",
      "date": "2020-01-01",
      "sleep_start_time": "2020-01-01T00:39:07+03:00",
      "sleep_end_time": "2020-01-01T09:19:37+03:00",
      "device_id": "1111AAAA",
      "continuity": 2.1,
      "continuity_class": 2,
      "light_sleep": 1000,
      "deep_sleep": 1000,
      "rem_sleep": 1000,
      "unrecognized_sleep_stage": 1000,
      "sleep_score": 80,
      "total_interruption_duration": 1000,
      "sleep_charge": 3,
      "sleep_goal": 28800,
      "sleep_rating": 3,
      "short_interruption_duration": 500,
      "long_interruption_duration": 300,
      "sleep_cycles": 6,
      "group_duration_score": 100,
      "group_solidity_score": 75,
      "group_regeneration_score": 54.2,
      "hypnogram": {
        "00:39": 2,
        "00:50": 3,
        "01:23": 6
      },
      "heart_rate_samples": {
        "00:41": 76,
        "00:46": 77,
        "00:51": 76
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Request was successful nights
403 Forbidden User has not accepted all mandatory consents. None

Get Sleep

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleep/{date} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleep/{date} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleep/{date}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleep/{date}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleep/{date}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleep/{date}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleep/{date}

Get Users sleep data for given date.

Parameters

Parameter In Type Required Description
date path string true Date of sleep as ISO-8601 date string, example: "2020-01-01"

Example responses

200 Response

{
  "polar_user": "https://www.polaraccesslink/v3/users/1",
  "date": "2020-01-01",
  "sleep_start_time": "2020-01-01T00:39:07+03:00",
  "sleep_end_time": "2020-01-01T09:19:37+03:00",
  "device_id": "1111AAAA",
  "continuity": 2.1,
  "continuity_class": 2,
  "light_sleep": 1000,
  "deep_sleep": 1000,
  "rem_sleep": 1000,
  "unrecognized_sleep_stage": 1000,
  "sleep_score": 80,
  "total_interruption_duration": 1000,
  "sleep_charge": 3,
  "sleep_goal": 28800,
  "sleep_rating": 3,
  "short_interruption_duration": 500,
  "long_interruption_duration": 300,
  "sleep_cycles": 6,
  "group_duration_score": 100,
  "group_solidity_score": 75,
  "group_regeneration_score": 54.2,
  "hypnogram": {
    "00:39": 2,
    "00:50": 3,
    "01:23": 6
  },
  "heart_rate_samples": {
    "00:41": 76,
    "00:46": 77,
    "00:51": 76
  }
}

Responses

Status Meaning Description Schema
200 OK Request was successful. sleep
400 Bad Request Invalid date. None
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found No data found for date. None

Get available sleep times

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleep/available \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleep/available HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleep/available',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleep/available',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleep/available', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleep/available");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleep/available

Get the dates with sleep start and end times, where user has sleep data available in the last 28 days.

Example responses

200 Response

{
  "available": [
    {
      "date": "2020-01-01",
      "start_time": "2020-01-01T00:39:07+03:00",
      "end_time": "2020-01-01T09:39:07+03:00"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Request was successful. available-sleeps
403 Forbidden User has not accepted all mandatory consents. None

Cardio load (Beta)

Cardio load is based on training impulse calculation (TRIMP), a commonly accepted and scientifically proven method to quantify training load. Your Cardio load value tells you how much strain your training session put on your cardiovascular system. The higher the Cardio load, the more strenuous the training session was for the cardiovascular system. Cardio load is calculated after every workout from your heart rate data and session duration. For more detailed information please check cardio load.

List cardio loads

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/cardio-load/ \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/cardio-load/ HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/cardio-load/',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/cardio-load/',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/cardio-load/', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/cardio-load/");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/cardio-load/

Returns cardio load data for the last 28 days.

Example responses

200 Response

[
  {
    "date": "2023-01-01",
    "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
    "cardio_load": 0.2,
    "strain": 0.3,
    "tolerance": 0.4,
    "cardio_load_ratio": 0.1,
    "cardio_load_level": {
      "very_low": 0.1,
      "low": 0.1,
      "medium": 0.1,
      "high": 0.1,
      "very-high": 0.1
    }
  }
]

Responses

Status Meaning Description Schema
200 OK List of user cardio loads. cardio-load-schema
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Get cardio load by date

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/cardio-load/{date} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/cardio-load/{date} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/cardio-load/{date}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/cardio-load/{date}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/cardio-load/{date}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/cardio-load/{date}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/cardio-load/{date}

Returns cardio load data for selected date.

Parameters

Parameter In Type Required Description
date path string(date) true Inclusive start date of range as ISO-8601 date string, example: "2022-01-01"

Example responses

200 Response

[
  {
    "date": "2023-01-01",
    "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
    "cardio_load": 0.2,
    "strain": 0.3,
    "tolerance": 0.4,
    "cardio_load_ratio": 0.1,
    "cardio_load_level": {
      "very_low": 0.1,
      "low": 0.1,
      "medium": 0.1,
      "high": 0.1,
      "very-high": 0.1
    }
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. cardio-load-schema
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Get cardio load by date range

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/cardio-load/date?from=2019-08-24&to=2019-08-24 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/cardio-load/date?from=2019-08-24&to=2019-08-24 HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/cardio-load/date?from=2019-08-24&to=2019-08-24',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/cardio-load/date',
  params: {
  'from' => 'string(date)',
'to' => 'string(date)'
}, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/cardio-load/date?from=2019-08-24&to=2019-08-24', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/cardio-load/date?from=2019-08-24&to=2019-08-24");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/cardio-load/date

Returns cardio load data for selected date range. The response list contains cardio load objects for every day between range even if the cardio load values cannot be calculated, in this case the cardio load status is represented as LOAD_STATUS_NOT_AVAILABLE.

Parameters

Parameter In Type Required Description
from query string(date) true Inclusive as ISO-8601 date string, example: "2022-01-01"
to query string(date) true Inclusive as ISO-8601 date string, example: "2022-01-01"

Example responses

200 Response

[
  {
    "date": "2023-01-01",
    "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
    "cardio_load": 0.2,
    "strain": 0.3,
    "tolerance": 0.4,
    "cardio_load_ratio": 0.1,
    "cardio_load_level": {
      "very_low": 0.1,
      "low": 0.1,
      "medium": 0.1,
      "high": 0.1,
      "very-high": 0.1
    }
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. cardio-load-schema
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Get historical data by days

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/cardio-load/period/days/{days} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/cardio-load/period/days/{days} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/cardio-load/period/days/{days}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/cardio-load/period/days/{days}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/cardio-load/period/days/{days}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/cardio-load/period/days/{days}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/cardio-load/period/days/{days}

Returns historical cardio load data for selected period of days counting from current date.

Parameters

Parameter In Type Required Description
days path integer true Period of days.

Example responses

200 Response

[
  {
    "date": "2023-01-01",
    "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
    "cardio_load": 0.2,
    "strain": 0.3,
    "tolerance": 0.4,
    "cardio_load_ratio": 0.1,
    "cardio_load_level": {
      "very_low": 0.1,
      "low": 0.1,
      "medium": 0.1,
      "high": 0.1,
      "very-high": 0.1
    }
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. cardio-load-schema
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Get historical data by months

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/cardio-load/period/months/{months} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/cardio-load/period/months/{months} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/cardio-load/period/months/{months}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/cardio-load/period/months/{months}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/cardio-load/period/months/{months}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/cardio-load/period/months/{months}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/cardio-load/period/months/{months}

Returns historical cardio load data for selected period of months counting from current date.

Parameters

Parameter In Type Required Description
months path integer true Period of months.

Example responses

200 Response

[
  {
    "date": "2023-01-01",
    "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
    "cardio_load": 0.2,
    "strain": 0.3,
    "tolerance": 0.4,
    "cardio_load_ratio": 0.1,
    "cardio_load_level": {
      "very_low": 0.1,
      "low": 0.1,
      "medium": 0.1,
      "high": 0.1,
      "very-high": 0.1
    }
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. cardio-load-schema
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Nightly Recharge

List Nightly Recharges

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/nightly-recharge \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/nightly-recharge HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/nightly-recharge',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/nightly-recharge',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/nightly-recharge', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/nightly-recharge");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/nightly-recharge

List Nightly Recharge data of user for the last 28 days.

Example responses

200 Response

{
  "recharges": [
    {
      "polar_user": "https://www.polaraccesslink/v3/users/1",
      "date": "2020-01-01",
      "heart_rate_avg": 70,
      "beat_to_beat_avg": 816,
      "heart_rate_variability_avg": 28,
      "breathing_rate_avg": 14.1,
      "nightly_recharge_status": 3,
      "ans_charge": 0,
      "ans_charge_status": 3,
      "hrv_samples": {
        "00:41": 14,
        "00:46": 14,
        "00:51": 15
      },
      "breathing_samples": {
        "00:39": 13.4,
        "00:44": 13.5,
        "00:49": 13.5
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Request was successful. recharges
403 Forbidden User has not accepted all mandatory consents. None

Get Nightly Recharge

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/nightly-recharge/{date} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/nightly-recharge/{date} HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/nightly-recharge/{date}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/nightly-recharge/{date}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/nightly-recharge/{date}', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/nightly-recharge/{date}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/nightly-recharge/{date}

Get Users Nightly Recharge data for given date.

Parameters

Parameter In Type Required Description
date path string true Date of Nightly Recharge as ISO-8601 date string, example: "2020-01-01"

Example responses

200 Response

{
  "polar_user": "https://www.polaraccesslink/v3/users/1",
  "date": "2020-01-01",
  "heart_rate_avg": 70,
  "beat_to_beat_avg": 816,
  "heart_rate_variability_avg": 28,
  "breathing_rate_avg": 14.1,
  "nightly_recharge_status": 3,
  "ans_charge": 0,
  "ans_charge_status": 3,
  "hrv_samples": {
    "00:41": 14,
    "00:46": 14,
    "00:51": 15
  },
  "breathing_samples": {
    "00:39": 13.4,
    "00:44": 13.5,
    "00:49": 13.5
  }
}

Responses

Status Meaning Description Schema
200 OK Request was successful. nightly-recharge
400 Bad Request Invalid date. None
403 Forbidden User has not accepted all mandatory consents. None
404 Not Found No data found for date. None

Continuous Heart Rate (Beta)

Get Continuous Heart rate samples with range

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/continuous-heart-rate?from=2019-08-24&to=2019-08-24 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/continuous-heart-rate?from=2019-08-24&to=2019-08-24 HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/continuous-heart-rate?from=2019-08-24&to=2019-08-24',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/continuous-heart-rate',
  params: {
  'from' => 'string(date)',
'to' => 'string(date)'
}, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/continuous-heart-rate?from=2019-08-24&to=2019-08-24', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/continuous-heart-rate?from=2019-08-24&to=2019-08-24");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/continuous-heart-rate

Get users continuous heart rate values for given date range. Supported devices

Parameters

Parameter In Type Required Description
from query string(date) true Inclusive start date of range as ISO-8601 date string, example: "2022-01-01"
to query string(date) true Inclusive end date of range as ISO-8601 date string, example: "2022-01-28"

Example responses

200 Response

{
  "polar_user": "https://polaraccesslink.com/v3/users/627139",
  "date": "2022-09-12",
  "heart_rate_samples": [
    {
      "heart_rate": 63,
      "sample_time": "00:02:08"
    },
    {
      "heart_rate": 62,
      "sample_time": "00:07:08"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Request was successful. continuous-heartrate
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

SleepWise™ (Beta)

Alertness period data (last 28 days)

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleepwise/alertness \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleepwise/alertness HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleepwise/alertness',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleepwise/alertness',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleepwise/alertness', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleepwise/alertness");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleepwise/alertness

Get user's alertness period data for the last 28 days. Supported devices

Example responses

200 Response

[
  {
    "grade": 9.9,
    "grade_validity_seconds": 57600,
    "grade_type": "GRADE_TYPE_PRIMARY",
    "grade_classification": "GRADE_CLASSIFICATION_STRONG",
    "validity": "VALIDITY_ESTIMATE",
    "sleep_inertia": "SLEEP_INERTIA_MILD",
    "sleep_type": "SLEEP_TYPE_PRIMARY",
    "result_type": "ALERTNESS_TYPE_HISTORY",
    "period_start_time": "2022-11-20T20:52:20",
    "period_end_time": "2022-11-21T19:15:52",
    "sleep_period_start_time": "2022-11-20T20:52:20.57",
    "sleep_period_end_time": "2022-11-21T04:11:20.57",
    "sleep_timezone_offset_minutes": 120,
    "hourly_data": [
      {
        "validity": "VALIDITY_ESTIMATE",
        "alertness_level": "ALERTNESS_LEVEL_LOW",
        "start_time": "2022-11-21T04:12:00",
        "end_time": "2022-11-21T05:00:00"
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found for last 28 days. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [alertness] false none [Alertness period data]
» grade number(double) false none Grade
» grade_validity_seconds number(int) false none Grade validity seconds
» grade_type string false none Grade type
» grade_classification string false none Grade classification
» validity string false none Validity
» sleep_inertia string false none Sleep inertia
» sleep_type string false none Sleep type
» result_type string false none Result type
» period_start_time string(date) false none Alertness period start time (UTC)
» period_end_time string(date) false none Alertness period end time (UTC)
» sleep_period_start_time string(date) false none Sleep period start time (UTC)
» sleep_period_end_time string(date) false none Sleep period end time (UTC)
» sleep_timezone_offset_minutes number(int) false none Sleep timezone offset minutes
» hourly_data [alertness-hourly-data] false none Alertness hourly data for the alertness period
»» validity string false none Validity
»» alertness_level string false none Alertness level
»» start_time string(date) false none Alertness period start time (UTC)
»» end_time string(date) false none Alertness period end time (UTC)

Enumerated Values

Property Value
grade_type GRADE_TYPE_UNKNOWN
grade_type GRADE_TYPE_PRIMARY
grade_type GRADE_TYPE_ADDITIONAL
grade_classification GRADE_CLASSIFICATION_UNKNOWN
grade_classification GRADE_CLASSIFICATION_WEAK
grade_classification GRADE_CLASSIFICATION_FAIR
grade_classification GRADE_CLASSIFICATION_STRONG
grade_classification GRADE_CLASSIFICATION_EXCELLENT
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
sleep_inertia SLEEP_INERTIA_UNKNOWN
sleep_inertia SLEEP_INERTIA_NO_INERTIA
sleep_inertia SLEEP_INERTIA_MILD
sleep_inertia SLEEP_INERTIA_MODERATE
sleep_inertia SLEEP_INERTIA_HEAVY
sleep_type SLEEP_TYPE_UNKNOWN
sleep_type SLEEP_TYPE_PRIMARY
sleep_type SLEEP_TYPE_SECONDARY
sleep_type SLEEP_TYPE_ARTIFICIAL
result_type ALERTNESS_TYPE_UNKNOWN
result_type ALERTNESS_TYPE_PREDICTION
result_type ALERTNESS_TYPE_HISTORY
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
alertness_level ALERTNESS_LEVEL_UNKNOWN
alertness_level ALERTNESS_LEVEL_MINIMAL
alertness_level ALERTNESS_LEVEL_VERY_LOW
alertness_level ALERTNESS_LEVEL_LOW
alertness_level ALERTNESS_LEVEL_HIGH
alertness_level ALERTNESS_LEVEL_VERY_HIGH

Alertness period data (date range)

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date?from=2019-08-24&to=2019-08-24 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date?from=2019-08-24&to=2019-08-24 HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date?from=2019-08-24&to=2019-08-24',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date',
  params: {
  'from' => 'string(date)',
'to' => 'string(date)'
}, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date?from=2019-08-24&to=2019-08-24', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date?from=2019-08-24&to=2019-08-24");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleepwise/alertness/date

Get user's alertness period data for given date range. Maximum date range between from and to cannot be more than 28 days. Supported devices

Parameters

Parameter In Type Required Description
from query string(date) true Inclusive start date of range as ISO-8601 date string, example: "2022-01-01"
to query string(date) true Inclusive end date of range as ISO-8601 date string, example: "2022-01-28"

Example responses

200 Response

[
  {
    "grade": 9.9,
    "grade_validity_seconds": 57600,
    "grade_type": "GRADE_TYPE_PRIMARY",
    "grade_classification": "GRADE_CLASSIFICATION_STRONG",
    "validity": "VALIDITY_ESTIMATE",
    "sleep_inertia": "SLEEP_INERTIA_MILD",
    "sleep_type": "SLEEP_TYPE_PRIMARY",
    "result_type": "ALERTNESS_TYPE_HISTORY",
    "period_start_time": "2022-11-20T20:52:20",
    "period_end_time": "2022-11-21T19:15:52",
    "sleep_period_start_time": "2022-11-20T20:52:20.57",
    "sleep_period_end_time": "2022-11-21T04:11:20.57",
    "sleep_timezone_offset_minutes": 120,
    "hourly_data": [
      {
        "validity": "VALIDITY_ESTIMATE",
        "alertness_level": "ALERTNESS_LEVEL_LOW",
        "start_time": "2022-11-21T04:12:00",
        "end_time": "2022-11-21T05:00:00"
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found for date range. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [alertness] false none [Alertness period data]
» grade number(double) false none Grade
» grade_validity_seconds number(int) false none Grade validity seconds
» grade_type string false none Grade type
» grade_classification string false none Grade classification
» validity string false none Validity
» sleep_inertia string false none Sleep inertia
» sleep_type string false none Sleep type
» result_type string false none Result type
» period_start_time string(date) false none Alertness period start time (UTC)
» period_end_time string(date) false none Alertness period end time (UTC)
» sleep_period_start_time string(date) false none Sleep period start time (UTC)
» sleep_period_end_time string(date) false none Sleep period end time (UTC)
» sleep_timezone_offset_minutes number(int) false none Sleep timezone offset minutes
» hourly_data [alertness-hourly-data] false none Alertness hourly data for the alertness period
»» validity string false none Validity
»» alertness_level string false none Alertness level
»» start_time string(date) false none Alertness period start time (UTC)
»» end_time string(date) false none Alertness period end time (UTC)

Enumerated Values

Property Value
grade_type GRADE_TYPE_UNKNOWN
grade_type GRADE_TYPE_PRIMARY
grade_type GRADE_TYPE_ADDITIONAL
grade_classification GRADE_CLASSIFICATION_UNKNOWN
grade_classification GRADE_CLASSIFICATION_WEAK
grade_classification GRADE_CLASSIFICATION_FAIR
grade_classification GRADE_CLASSIFICATION_STRONG
grade_classification GRADE_CLASSIFICATION_EXCELLENT
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
sleep_inertia SLEEP_INERTIA_UNKNOWN
sleep_inertia SLEEP_INERTIA_NO_INERTIA
sleep_inertia SLEEP_INERTIA_MILD
sleep_inertia SLEEP_INERTIA_MODERATE
sleep_inertia SLEEP_INERTIA_HEAVY
sleep_type SLEEP_TYPE_UNKNOWN
sleep_type SLEEP_TYPE_PRIMARY
sleep_type SLEEP_TYPE_SECONDARY
sleep_type SLEEP_TYPE_ARTIFICIAL
result_type ALERTNESS_TYPE_UNKNOWN
result_type ALERTNESS_TYPE_PREDICTION
result_type ALERTNESS_TYPE_HISTORY
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
alertness_level ALERTNESS_LEVEL_UNKNOWN
alertness_level ALERTNESS_LEVEL_MINIMAL
alertness_level ALERTNESS_LEVEL_VERY_LOW
alertness_level ALERTNESS_LEVEL_LOW
alertness_level ALERTNESS_LEVEL_HIGH
alertness_level ALERTNESS_LEVEL_VERY_HIGH

Circadian bedtime period data (last 28 days)

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleepwise/circadian-bedtime

Get user's circadian bedtime period data for the last 28 days. Supported devices

Example responses

200 Response

[
  {
    "validity": "VALIDITY_ESTIMATE",
    "quality": "CIRCADIAN_BEDTIME_QUALITY_COMPROMISED",
    "result_type": "CIRCADIAN_BEDTIME_TYPE_HISTORY",
    "period_start_time": "2022-11-20T21:18:30",
    "period_end_time": "2022-11-21T05:18:30",
    "preferred_sleep_period_start_time": "2022-11-20T21:18:30",
    "preferred_sleep_period_end_time": "2022-11-21T05:18:30",
    "sleep_gate_start_time": "2022-11-20T21:03:30",
    "sleep_gate_end_time": "2022-11-20T21:33:30",
    "sleep_timezone_offset_minutes": 120
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found for last 28 days. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [circadian-bedtime] false none [Circadian bedtime period data]
» validity string false none Validity
» quality string false none Quality
» result_type string false none Result type
» period_start_time string(date) false none Circadian bedtime period start time (UTC)
» period_end_time string(date) false none Circadian bedtime period end time (UTC)
» preferred_sleep_period_start_time string(date) false none Circadian bedtime preferred sleep period start time (UTC)
» preferred_sleep_period_end_time string(date) false none Circadian bedtime preferred sleep period end time (UTC)
» sleep_gate_start_time string(date) false none Circadian bedtime sleep gate (suggested fall a sleep window) start time (UTC)
» sleep_gate_end_time string(date) false none Circadian bedtime sleep gate (suggested fall a sleep window) end time (UTC)
» sleep_timezone_offset_minutes number(int) false none Sleep timezone offset minutes

Enumerated Values

Property Value
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
quality CIRCADIAN_BEDTIME_QUALITY_UNKNOWN
quality CIRCADIAN_BEDTIME_QUALITY_WEAK
quality CIRCADIAN_BEDTIME_QUALITY_COMPROMISED
quality CIRCADIAN_BEDTIME_QUALITY_CLEARLY_RECOGNIZABLE
result_type CIRCADIAN_BEDTIME_TYPE_UNKNOWN
result_type CIRCADIAN_BEDTIME_TYPE_PREDICTION
result_type CIRCADIAN_BEDTIME_TYPE_HISTORY

Circadian bedtime period data (date range)

Code samples

# You can also use wget
curl -X GET https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime/date?from=2019-08-24&to=2019-08-24 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime/date?from=2019-08-24&to=2019-08-24 HTTP/1.1
Host: www.polaraccesslink.com
Accept: application/json

const fetch = require('node-fetch');

const headers = {
  'Accept':'application/json',  'Authorization':'Bearer {access-token}'
};

fetch('https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime/date?from=2019-08-24&to=2019-08-24',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime/date',
  params: {
  'from' => 'string(date)',
'to' => 'string(date)'
}, headers: headers

p JSON.parse(result)

import requests

headers = {
  'Accept': 'application/json',  'Authorization': 'Bearer {access-token}'
};

r = requests.get('https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime/date?from=2019-08-24&to=2019-08-24', headers = headers
    )

if r.status_code >= 200 and r.status_code < 400:
    print(r.json())
else:
    print(r)
URL obj = new URL("https://www.polaraccesslink.com/v3/users/sleepwise/circadian-bedtime/date?from=2019-08-24&to=2019-08-24");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

GET /v3/users/sleepwise/circadian-bedtime/date

Get user's circadian bedtime period data for given date range. Maximum date range between from and to cannot be more than 28 days. Supported devices

Parameters

Parameter In Type Required Description
from query string(date) true Inclusive start date of range as ISO-8601 date string, example: "2022-01-01"
to query string(date) true Inclusive end date of range as ISO-8601 date string, example: "2022-01-28"

Example responses

200 Response

[
  {
    "validity": "VALIDITY_ESTIMATE",
    "quality": "CIRCADIAN_BEDTIME_QUALITY_COMPROMISED",
    "result_type": "CIRCADIAN_BEDTIME_TYPE_HISTORY",
    "period_start_time": "2022-11-20T21:18:30",
    "period_end_time": "2022-11-21T05:18:30",
    "preferred_sleep_period_start_time": "2022-11-20T21:18:30",
    "preferred_sleep_period_end_time": "2022-11-21T05:18:30",
    "sleep_gate_start_time": "2022-11-20T21:03:30",
    "sleep_gate_end_time": "2022-11-20T21:33:30",
    "sleep_timezone_offset_minutes": 120
  }
]

Responses

Status Meaning Description Schema
200 OK Request was successful. Inline
204 No Content No data found for date range. None
400 Bad Request Invalid request. None
401 Unauthorized Unauthorized. None
403 Forbidden User has not accepted all mandatory consents. None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [circadian-bedtime] false none [Circadian bedtime period data]
» validity string false none Validity
» quality string false none Quality
» result_type string false none Result type
» period_start_time string(date) false none Circadian bedtime period start time (UTC)
» period_end_time string(date) false none Circadian bedtime period end time (UTC)
» preferred_sleep_period_start_time string(date) false none Circadian bedtime preferred sleep period start time (UTC)
» preferred_sleep_period_end_time string(date) false none Circadian bedtime preferred sleep period end time (UTC)
» sleep_gate_start_time string(date) false none Circadian bedtime sleep gate (suggested fall a sleep window) start time (UTC)
» sleep_gate_end_time string(date) false none Circadian bedtime sleep gate (suggested fall a sleep window) end time (UTC)
» sleep_timezone_offset_minutes number(int) false none Sleep timezone offset minutes

Enumerated Values

Property Value
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
quality CIRCADIAN_BEDTIME_QUALITY_UNKNOWN
quality CIRCADIAN_BEDTIME_QUALITY_WEAK
quality CIRCADIAN_BEDTIME_QUALITY_COMPROMISED
quality CIRCADIAN_BEDTIME_QUALITY_CLEARLY_RECOGNIZABLE
result_type CIRCADIAN_BEDTIME_TYPE_UNKNOWN
result_type CIRCADIAN_BEDTIME_TYPE_PREDICTION
result_type CIRCADIAN_BEDTIME_TYPE_HISTORY

Schemas

training-load-pro-rpe-enum

"UNKNOWN"

Quantifies internal training load of a session.

Properties

Name Type Required Restrictions Description
anonymous string false none Quantifies internal training load of a session.

Enumerated Values

Property Value
anonymous UNKNOWN
anonymous RPE_NONE
anonymous RPE_EASY
anonymous RPE_LIGHT
anonymous RPE_FAIRLY_BRISK
anonymous RPE_BRISK
anonymous RPE_MODERATE
anonymous RPE_FAIRLY_HARD
anonymous RPE_HARD
anonymous RPE_EXHAUSTING
anonymous RPE_EXTREME

training-load-pro-load-enum

"UNKNOWN"

Properties

Name Type Required Restrictions Description
anonymous string false none none

Enumerated Values

Property Value
anonymous UNKNOWN
anonymous VERY_LOW
anonymous LOW
anonymous MEDIUM
anonymous HIGH
anonymous VERY_HIGH
anonymous NOT_AVAILABLE

training-load-pro-sample

{
  "date": "2023-01-01",
  "cardio-load": 1,
  "muscle-load": 1,
  "perceived-load": 1,
  "cardio-load-interpretation": "UNKNOWN",
  "muscle-load-interpretation": "UNKNOWN",
  "perceived-load-interpretation": "UNKNOWN",
  "user-rpe": "UNKNOWN"
}

Properties

Name Type Required Restrictions Description
date string(date) false none Date in format YYYY-MM-DD.
cardio-load number(float) false none User cardio load value.
muscle-load number(float) false none User muscle load value.
perceived-load number(float) false none User perceived load value.
cardio-load-interpretation training-load-pro-load-enum false none none
muscle-load-interpretation training-load-pro-load-enum false none none
perceived-load-interpretation training-load-pro-load-enum false none none
user-rpe training-load-pro-rpe-enum false none Quantifies internal training load of a session.

cardio-load-schema

[
  {
    "date": "2023-01-01",
    "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
    "cardio_load": 0.2,
    "strain": 0.3,
    "tolerance": 0.4,
    "cardio_load_ratio": 0.1,
    "cardio_load_level": {
      "very_low": 0.1,
      "low": 0.1,
      "medium": 0.1,
      "high": 0.1,
      "very-high": 0.1
    }
  }
]

List of cardio loads.

Properties

Name Type Required Restrictions Description
anonymous [cardio-load] false none List of cardio loads.

cardio-load

{
  "date": "2023-01-01",
  "cardio_load_status": "LOAD_STATUS_NOT_AVAILABLE",
  "cardio_load": 0.2,
  "strain": 0.3,
  "tolerance": 0.4,
  "cardio_load_ratio": 0.1,
  "cardio_load_level": {
    "very_low": 0.1,
    "low": 0.1,
    "medium": 0.1,
    "high": 0.1,
    "very-high": 0.1
  }
}

Cardio load model.

Properties

Name Type Required Restrictions Description
date string(date) false none Date in format YYYY-MM-DD.
cardio_load_status cardio-load-status-enum false none Text representation of cardio load status.
cardio_load number(float) false none Cardio load (training impulse, TRIMP) shows your cardiac response to a training session.
strain number(float) false none Strain shows how much you have strained yourself with training lately. It shows your average daily load from the past 7 days.
tolerance number(float) false none Tolerance describes how prepared you are to endure cardio training. It shows your average daily load from the past 28 days.
cardio_load_ratio number(float) false none Ratio between strain and tolerance.
cardio_load_level cardio-load-levels false none Cardio load levels indicate how hard a training session was compared to your session average from the past 90 days.

cardio-load-status-enum

"LOAD_STATUS_NOT_AVAILABLE"

Text representation of cardio load status.

Properties

Name Type Required Restrictions Description
anonymous string false none Text representation of cardio load status.

Enumerated Values

Property Value
anonymous LOAD_STATUS_NOT_AVAILABLE
anonymous DETRAINING
anonymous MAINTAINING
anonymous PRODUCTIVE
anonymous OVERREACHING
anonymous UNRECOGNIZED

cardio-load-levels

{
  "very_low": 0.1,
  "low": 0.1,
  "medium": 0.1,
  "high": 0.1,
  "very-high": 0.1
}

Cardio load levels indicate how hard a training session was compared to your session average from the past 90 days.

Properties

Name Type Required Restrictions Description
very_low number(float) false none none
low number(float) false none none
medium number(float) false none none
high number(float) false none none
very-high number(float) false none none

AvailableUserData

{
  "user-id": 475,
  "data-type": "ACTIVITY_SUMMARY",
  "url": "https://www.polaraccesslink.com/v3/users/475/activity-transactions"
}

Model contains information of the data available.

Properties

Name Type Required Restrictions Description
user-id integer(int64) false none User identifier who has available data.
data-type string false none Type of available data.
url string false none URI pointing to transaction initiation endpoint for user

Enumerated Values

Property Value
data-type EXERCISE
data-type ACTIVITY_SUMMARY
data-type PHYSICAL_INFORMATION

DurationZone

{
  "index": 1,
  "inzone": "PT51M5S"
}

Model contains the time spent in certain activity zone.

Properties

Name Type Required Restrictions Description
index integer(int32) false none Activity zone index
inzone string false none Time duration spent in the zone ISO 8601

HeartRate

{
  "average": 129,
  "maximum": 147
}

Heart-rate statistics information

Properties

Name Type Required Restrictions Description
average integer(int32) false none Average heart-rate
maximum integer(int32) false none Maximum heart-rate

UserExtraInfo

{
  "value": "2",
  "index": 0,
  "name": "number-of-children"
}

User's answers to the custom extra-info fields requested by partners

Properties

Name Type Required Restrictions Description
value string false none Value provided by the customer
index integer(int32) false none Item index
name string false none Name of the extra info asked from customer

activity

{
  "id": 1234,
  "polar-user": "https://www.polaraccesslink/v3/users/1",
  "transaction-id": 179879,
  "date": "2010-12-31",
  "created": "2016-04-27T20:11:33.000Z",
  "calories": 2329,
  "active-calories": 428,
  "duration": "PT2H44M",
  "active-steps": 250
}

Summary of user's daily activity

Properties

Name Type Required Restrictions Description
id integer(int64) false none Activity summary id
polar-user string false none Absolute link to user owning the activity
transaction-id integer(int64) false none Id of the activity-transaction this training was transferred in
date string false none Date when activity summary was recorded, in format YYYY-MM-DD
created string false none The time activity summary was created in AccessLink, in format YYYY-MM-DDTHH:mm:ss.SSS
calories integer(int32) false none Total daily calories in kilo calories including BMR
active-calories integer(int32) false none Total daily calories not including BMR. Precise calculation requires that user's physical data is entered into Polar Flow
duration string false none The time interval as specified in ISO 8601
active-steps integer(int32) false none You could consider this as a kind of activity unit. If you take one step the active-steps should increase by one and any activity comparable to one physical step would also increase the number by one

activity-log

{
  "activity-log": [
    "https://www.polaraccesslink.com/v3/users/12/activity-transactions/34/activities/56",
    "https://www.polaraccesslink.com/v3/users/12/activity-transactions/34/activities/120"
  ]
}

Activity transaction container

Properties

Name Type Required Restrictions Description
activity-log [string] false none Absolute links to individual activity summaries within the transaction

activity-step-sample

{
  "steps": 0,
  "time": "12:37:33.000"
}

Model contains number of steps in certain time period.

Properties

Name Type Required Restrictions Description
steps integer(int32) false none Number of steps in sample segment. If element is null, step samples are not available for current segment.
time string false none Start time of sample segment.

activity-step-samples

{
  "date": "2022-02-10",
  "interval": 0,
  "samples": [
    {
      "steps": 0,
      "time": "12:37:33.000"
    }
  ]
}

Wrapper model for partner step samples.

Properties

Name Type Required Restrictions Description
date string false none Activity step sample date
interval integer(int32) false none Sample interval in minutes.
samples [activity-step-sample] false none List of individual step sample objects.

activity-zone-sample

{
  "activity-zones": [
    {
      "index": 1,
      "inzone": "PT51M5S"
    }
  ],
  "time": "string"
}

Model contains number of steps in certain time period.

Properties

Name Type Required Restrictions Description
activity-zones [DurationZone] false none List of heart rate zones with duration.
time string false none Start time of sample segment.

activity-zone-samples

{
  "date": "2022-02-10",
  "interval": 0,
  "samples": [
    {
      "activity-zones": [
        {
          "index": 1,
          "inzone": "PT51M5S"
        }
      ],
      "time": "string"
    }
  ]
}

List containing the times (in zone) in different heart rate zones (i.e. Heart rate between lower and upper values). Zone is null if no zone information available.

Properties

Name Type Required Restrictions Description
date string false none Activity zone sample date
interval integer(int32) false none Sample interval in minutes.
samples [activity-zone-sample] false none List of individual zone sample objects.

available-user-datas

{
  "available-user-data": [
    {
      "user-id": 475,
      "data-type": "ACTIVITY_SUMMARY",
      "url": "https://www.polaraccesslink.com/v3/users/475/activity-transactions"
    }
  ]
}

*AvailableUserDatas is a container model for AvailableUserData. *

Properties

Name Type Required Restrictions Description
available-user-data [AvailableUserData] false none List of available user datas.

error

{
  "timestamp": "2019-08-24T14:15:22Z",
  "status": 0,
  "errorType": "string",
  "message": "string",
  "corrId": "string"
}

Error model which contains useful info about the error occurred.

Properties

Name Type Required Restrictions Description
timestamp string(date-time) false none Timestamp of the error.
status integer false none Http status code
errorType string false none Error type.
message string false none Human readable error message.
corrId string false none Correlation id of the response for problem solving and debugging use.

exercise

{
  "id": 1937529874,
  "upload-time": "2008-10-13T10:40:0.000Z",
  "polar-user": "https://www.polaraccesslink/v3/users/1",
  "transaction-id": 179879,
  "device": "Polar M400",
  "device-id": "1111AAAA",
  "start-time": "2008-10-13T10:40:02",
  "start-time-utc-offset": 180,
  "duration": "PT2H44M45S",
  "calories": 530,
  "distance": 1600.2,
  "heart-rate": {
    "average": 129,
    "maximum": 147
  },
  "training-load": 143.22,
  "sport": "OTHER",
  "has-route": true,
  "club-id": 999,
  "club-name": "Polar Club",
  "detailed-sport-info": "RUNNING",
  "fat-percentage": 60,
  "carbohydrate-percentage": 38,
  "protein-percentage": 2,
  "running-index": 51,
  "training-load-pro": [
    {
      "date": "2023-01-01",
      "cardio-load": 1,
      "muscle-load": 1,
      "perceived-load": 1,
      "cardio-load-interpretation": "UNKNOWN",
      "muscle-load-interpretation": "UNKNOWN",
      "perceived-load-interpretation": "UNKNOWN",
      "user-rpe": "UNKNOWN"
    }
  ]
}

Training session summary data

Properties

Name Type Required Restrictions Description
id integer(int64) false none Id of the trainining session
upload-time string false none Time of the transfer from wrist unit to Polar database
polar-user string false none Absolute link to Polar user owning the training
transaction-id integer(int64) false none Id of the exercise-transaction this training was transferred in
device string false none Polar product used in training
device-id string false none Id of the Polar device
start-time string false none Start time of the training session in local time
start-time-utc-offset integer(int32) false none The offset from UTC (in minutes) when the training session was started
duration string false none The duration of the training session as specified in ISO8601
calories integer(int32) false none Expended calories during training in kilocalories
distance number(float) false none Distance in meters travelled during training
heart-rate HeartRate false none Heart-rate statistics information
training-load number(float) false none Training load effect to user
sport string false none Sport name
has-route boolean false none Boolean indicating if the exercise has route data
club-id integer(int64) false none Has value if the exercise is from "Flow For Club", otherwise not printed. Value -1 indicates that there were errors finding the club
club-name string false none Has value if the exercise is from "Flow For Club", otherwise not printed. Value "Ambiguous club location. Please contact support." is printed in case of error (and the club-id is -1).
detailed-sport-info string false none String containing the name of a Polar Flow-compatible sport, if one is set for the exercise.
fat-percentage integer(int32) false none Fat percentage of exercise calories. Has value if the exercise is from training device supporting Energy sources, otherwise not printed.
carbohydrate-percentage integer(int32) false none Carbohydrate percentage of exercise calories. Has value if the exercise is from training device supporting Energy sources, otherwise not printed.
protein-percentage integer(int32) false none Protein percentage of exercise calories. Has value if the exercise is from training device supporting Energy sources, otherwise not printed.
running-index integer(int32) false none Running index is a score automatically calculated every run based on your heart rate and speed data collected via GPS or stride sensor.
training-load-pro [training-load-pro-sample] false none none

exerciseHashId

{
  "id": "2AC312F",
  "upload_time": "2008-10-13T10:40:02.000Z",
  "polar_user": "https://www.polaraccesslink/v3/users/1",
  "device": "Polar M400",
  "device_id": "1111AAAA",
  "start_time": "2008-10-13T10:40:02",
  "start_time_utc_offset": 180,
  "duration": "PT2H44M",
  "calories": 530,
  "distance": 1600,
  "heart_rate": {
    "average": 129,
    "maximum": 147
  },
  "training_load": 143.22,
  "sport": "OTHER",
  "has_route": true,
  "club_id": 999,
  "club_name": "Polar Club",
  "detailed_sport_info": "WATERSPORTS_WATERSKI",
  "fat_percentage": 60,
  "carbohydrate_percentage": 38,
  "protein_percentage": 2,
  "running-index": 51,
  "heart_rate_zones": [
    {
      "index": 1,
      "lower-limit": 110,
      "upper-limit": 130,
      "in-zone": "PT4S"
    }
  ],
  "samples": [
    {
      "recording-rate": 5,
      "sample-type": "1",
      "data": "0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122"
    }
  ],
  "route": [
    {
      "latitude": 60.21982833,
      "longitude": 25.13925,
      "time": "PT210.026S",
      "satellites": 4,
      "fix": 1
    }
  ],
  "training_load_pro": [
    {
      "date": "2023-01-01",
      "cardio-load": 1,
      "muscle-load": 1,
      "perceived-load": 1,
      "cardio-load-interpretation": "UNKNOWN",
      "muscle-load-interpretation": "UNKNOWN",
      "perceived-load-interpretation": "UNKNOWN",
      "user-rpe": "UNKNOWN"
    }
  ]
}

Training session summary data

Properties

Name Type Required Restrictions Description
id string false none Hashed id of the trainining session
upload_time string false none Time of the transfer from wrist unit to Polar database
polar_user string false none Absolute link to Polar user owning the training
device string false none Polar product used in training
device_id string false none Id of the Polar device
start_time string false none Start time of the training session in local time
start_time_utc_offset integer(int32) false none The offset from UTC (in minutes) when the training session was started
duration string false none The duration of the training session as specified in ISO8601
calories integer(int32) false none Expended calories during training in kilocalories
distance number(float) false none Distance in meters travelled during training
heart_rate HeartRate false none Heart-rate statistics information
training_load number(float) false none Training load effect to user
sport string false none Sport name
has_route boolean false none Boolean indicating if the exercise has route data
club_id integer(int64) false none Has value if the exercise is from "Flow For Club", otherwise not printed. Value -1 indicates that there were errors finding the club
club_name string false none Has value if the exercise is from "Flow For Club", otherwise not printed. Value "Ambiguous club location. Please contact support." is printed in case of error (and the club-id is -1).
detailed_sport_info string false none String containing the name of a Polar Flow-compatible sport, if one is set for the exercise.
fat_percentage integer(int32) false none Fat percentage of exercise calories. Has value if the exercise is from training device supporting Energy sources, otherwise not printed.
carbohydrate_percentage integer(int32) false none Carbohydrate percentage of exercise calories. Has value if the exercise is from training device supporting Energy sources, otherwise not printed.
protein_percentage integer(int32) false none Protein percentage of exercise calories. Has value if the exercise is from training device supporting Energy sources, otherwise not printed.
running-index integer(int32) false none Running index is a score automatically calculated every run based on your heart rate and speed data collected via GPS or stride sensor.
heart_rate_zones [zone] false none Heart rate zones for this exercise. Returned when query parameter 'zones=true' is used.
samples [sample] false none List of all samples available for this exercise. Returned when query parameter 'samples=true' is used.
route [location] false none List of all route points/locations available for this exercise. Returned when query parameter 'route=true' is used.
training_load_pro [training-load-pro-sample] false none none

exercisesHashId

[
  {
    "id": "2AC312F",
    "upload_time": "2008-10-13T10:40:02.000Z",
    "polar_user": "https://www.polaraccesslink/v3/users/1",
    "device": "Polar M400",
    "device_id": "1111AAAA",
    "start_time": "2008-10-13T10:40:02",
    "start_time_utc_offset": 180,
    "duration": "PT2H44M",
    "calories": 530,
    "distance": 1600,
    "heart_rate": {
      "average": 129,
      "maximum": 147
    },
    "training_load": 143.22,
    "sport": "OTHER",
    "has_route": true,
    "club_id": 999,
    "club_name": "Polar Club",
    "detailed_sport_info": "WATERSPORTS_WATERSKI",
    "fat_percentage": 60,
    "carbohydrate_percentage": 38,
    "protein_percentage": 2,
    "running-index": 51,
    "heart_rate_zones": [
      {
        "index": 1,
        "lower-limit": 110,
        "upper-limit": 130,
        "in-zone": "PT4S"
      }
    ],
    "samples": [
      {
        "recording-rate": 5,
        "sample-type": "1",
        "data": "0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122"
      }
    ],
    "route": [
      {
        "latitude": 60.21982833,
        "longitude": 25.13925,
        "time": "PT210.026S",
        "satellites": 4,
        "fix": 1
      }
    ],
    "training_load_pro": [
      {
        "date": "2023-01-01",
        "cardio-load": 1,
        "muscle-load": 1,
        "perceived-load": 1,
        "cardio-load-interpretation": "UNKNOWN",
        "muscle-load-interpretation": "UNKNOWN",
        "perceived-load-interpretation": "UNKNOWN",
        "user-rpe": "UNKNOWN"
      }
    ]
  }
]

List of exercises.

Properties

Name Type Required Restrictions Description
anonymous [exerciseHashId] false none List of exercises.

exercises

{
  "exercises": [
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56",
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/120"
  ]
}

Exercise transaction container

Properties

Name Type Required Restrictions Description
exercises [string] false none Absolute links to individual exercises within the transaction

physical-information

{
  "id": 123,
  "transaction-id": 179879,
  "created": "2016-04-27T20:11:33.000Z",
  "polar-user": "https://www.polaraccesslink/v3/users/1",
  "weight": 80,
  "height": 180,
  "maximum-heart-rate": 160,
  "resting-heart-rate": 60,
  "aerobic-threshold": 123,
  "anaerobic-threshold": 123,
  "vo2-max": 12,
  "weight-source": "SOURCE_MEASURED"
}

User's physical information

Properties

Name Type Required Restrictions Description
id integer(int64) false none Physical information id
transaction-id integer(int64) false none Id of the physical-information-transaction this training was transferred in
created string false none The time physical information was created in AccessLink, in format YYYY-MM-DDTHH:mm:ss.SSSZ
polar-user string false none Absolute link to user owning the activity
weight number(float) false none Weight
height number(float) false none Height
maximum-heart-rate integer(int32) false none Maximum heart rate
resting-heart-rate integer(int32) false none Resting hear rate
aerobic-threshold integer(int32) false none Aerobic threshold
anaerobic-threshold integer(int32) false none Anaerobic threshold
vo2-max integer(int32) false none VO2 max
weight-source string false none Weight source

Enumerated Values

Property Value
weight-source SOURCE_MEASURED
weight-source SOURCE_USER

physical-informations

{
  "physical-informations": [
    "https://www.polaraccesslink.com/v3/users/12/physical-information-transactions/12/physical-informations/56",
    "https://www.polaraccesslink.com/v3/users/12/physical-information-transactions/12/physical-informations/120"
  ]
}

Physical information transaction container

Properties

Name Type Required Restrictions Description
physical-informations [string] false none Absolute links to individual physical information within the transaction

register

{
  "member-id": "User_id_999"
}

Model for registering user to partner.

Properties

Name Type Required Restrictions Description
member-id string true none Partner's custom identifier for user.

sample

{
  "recording-rate": 5,
  "sample-type": "1",
  "data": "0,100,102,97,97,101,103,106,96,89,88,87,98,108,113,112,114,115,118,121,121,121,121,123,117,119,122"
}

Training session sample data

Properties

Name Type Required Restrictions Description
recording-rate integer(int32) false none Sample recording rate in seconds. Null when recording rate is not applicable - currently only with RR-data.
sample-type string(byte) false none Sample type
data string false none Sample values as a comma-separated list of strings. Can contain null -values which indicate a situation where sensor was offline.

samples

{
  "samples": [
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56/samples/0",
    "https://www.polaraccesslink.com/v3/users/12/exercise-transactions/34/exercises/56/samples/3"
  ]
}

List of URIs pointing to single sample type data.

Properties

Name Type Required Restrictions Description
samples [string] false none List of URIs pointing to single sample type data.

location

{
  "latitude": 60.21982833,
  "longitude": 25.13925,
  "time": "PT210.026S",
  "satellites": 4,
  "fix": 1
}

Exercise route point/location.

Properties

Name Type Required Restrictions Description
latitude number(double) false none The latitude, expressed in degrees.
longitude number(double) false none The longitude, expressed in degrees.
time string false none The time, expressed as a duration.
satellites integer(int64) false none Satellites. A byte-sized value with a maximum of 63.
fix integer(int64) false none Fix. A byte-sized value with a maximum of three.

route

[
  {
    "latitude": 60.21982833,
    "longitude": 25.13925,
    "time": "PT210.026S",
    "satellites": 4,
    "fix": 1
  }
]

List of route points/locations of the exercise.

Properties

Name Type Required Restrictions Description
anonymous [location] false none List of route points/locations of the exercise.

transaction-location

{
  "transaction-id": 122,
  "resource-uri": "https://polaraccesslink.com/v3/users/21/physical-information-transactions/32"
}

Contains absolute link to the created transaction.

Properties

Name Type Required Restrictions Description
transaction-id integer(int64) false none Id of the created transaction
resource-uri string(uri) false none Absolute links to the created transaction

user

{
  "polar-user-id": 2278512,
  "member-id": "i09u9ujj",
  "registration-date": "2011-10-14T12:50:37.000Z",
  "first-name": "Eka",
  "last-name": "Toka",
  "birthdate": "1985-09-06",
  "gender": "MALE",
  "weight": 66,
  "height": 170,
  "extra-info": [
    {
      "value": "2",
      "index": 0,
      "name": "number-of-children"
    }
  ]
}

User's basic information

Properties

Name Type Required Restrictions Description
polar-user-id integer(int64) false none User's id in Polar database
member-id string false none User's identifier in partner's database
registration-date string(date-time) false none Timestamp marked when ACCEPTED
first-name string false none User's first name
last-name string false none User's surname
birthdate string false none User's birthdate as YYYY-MM-DD
gender string false none User's sex
weight number(float) false none User's weight in kg
height number(float) false none Users height in centimeters
extra-info [UserExtraInfo] false none List containing answers given by the user to a number of partner-specific questions. Extra-info is null if there are no required fields defined by the partner.

Enumerated Values

Property Value
gender MALE
gender FEMALE

createdWebhook

{
  "data": {
    "id": "abdf33",
    "events": [
      "EXERCISE"
    ],
    "url": "https://myapp.example.com/acl_webhook",
    "signature_secret_key": "abe1f3ae-fd33-11e8-8eb2-f2801f1b9fd1"
  }
}

Properties

Name Type Required Restrictions Description
data object false none none
» id string false none Id of the new webhook.
» events [webhookType] false none Subscribed event types.
» url string(uri) false none Url where the webhook notification is sent.
» signature_secret_key string false none Signing key for verifying that sender is actually Polar.

webhookInfo

{
  "data": {
    "id": "abdf33",
    "events": [
      "EXERCISE"
    ],
    "url": "https://myapp.example.com/acl_webhook",
    "active": true
  }
}

Properties

Name Type Required Restrictions Description
data object false none none
» id string false none Id of the webhook.
» events [webhookType] false none Subscribed event types.
» url string(uri) false none Url where the webhook notification is sent.
» active boolean false none Is the webhook active.

webhookPatch

{
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
}

Properties

Name Type Required Restrictions Description
events [webhookType] false none Type of events to subscribe.
url string(uri) false none Url where the webhook notification is sent.

webhookPayloadExercise

{
  "event": "EXERCISE",
  "user_id": 475,
  "entity_id": "aQlC83",
  "timestamp": "2018-05-15T14:22:24Z",
  "url": "https://www.polaraccesslink.com/v3/exercises/aQlC83"
}

Payload example for webhook payload for event type EXERCISE

Properties

Name Type Required Restrictions Description
event string false none Type of available data.
user_id integer(int64) false none Id of the user who has new data.
entity_id string false none Id of the available data.
timestamp string(date-time) false none Time when webhook notification is sent.
url string(uri) false none Url to the new available data.

webhookPayloadSleep

{
  "event": "SLEEP",
  "user_id": 475,
  "date": "2019-12-31",
  "timestamp": "2018-05-15T14:22:24Z",
  "url": "https://www.polaraccesslink.com/v3/users/sleep/2019-12-31"
}

Payload example for webhook payload for event type SLEEP

Properties

Name Type Required Restrictions Description
event string false none Type of available data.
user_id integer(int64) false none Id of the user who has new data.
date string false none Date of the available sleep data.
timestamp string(date-time) false none Time when webhook notification is sent.
url string(uri) false none Url to the new available data.

webhookPayloadContinuousHeartRate

{
  "event": "CONTINUOUS_HEART_RATE",
  "user_id": 475,
  "date": "2022-09-31",
  "timestamp": "2018-05-15T14:22:24Z",
  "url": "https://www.polaraccesslink.com/v3/users/continuous-heart-rate/2022-09-31"
}

Payload example for webhook payload for event type CONTINUOUS_HEART_RATE

Properties

Name Type Required Restrictions Description
event string false none Type of available data.
user_id integer(int64) false none Id of the user who has new data.
date string false none Date of the available continuous hr data.
timestamp string(date-time) false none Time when webhook notification is sent.
url string(uri) false none Url to the new available data.

webhookPayloadCircadianBedtime

{
  "event": "SLEEP_WISE_CIRCADIAN_BEDTIME",
  "user_id": 475,
  "from": "2022-09-31",
  "to": "2022-10-02",
  "timestamp": "2022-10-02T14:22:24Z",
  "url": "https://www.polaraccesslink.com/v3/users/sleepwise/circadian_bedtime/date?from=2022-09-31&to=2022-10-02"
}

Payload example for webhook payload for event type SLEEP_WISE_CIRCADIAN_BEDTIME

Properties

Name Type Required Restrictions Description
event string false none Type of available data.
user_id integer(int64) false none Id of the user who has new data.
from string false none For consistency use period for all descriptions
to string false none For consistency use period for all descriptions
timestamp string(date-time) false none Time when webhook notification is sent.
url string(uri) false none Url to the new available data.

webhookPayloadAlertness

{
  "event": "SLEEP_WISE_ALERTNESS",
  "user_id": 475,
  "from": "2022-09-31",
  "to": "2022-10-02",
  "timestamp": "2022-10-02T14:22:24Z",
  "url": "https://www.polaraccesslink.com/v3/users/sleepwise/alertness/date?from=2022-09-31&to=2022-10-02"
}

Payload example for webhook payload for event type SLEEP_WISE_ALERTNESS

Properties

Name Type Required Restrictions Description
event string false none Type of available data.
user_id integer(int64) false none Id of the user who has new data.
from string false none For consistency use period for all descriptions
to string false none For consistency use period for all descriptions
timestamp string(date-time) false none Time when webhook notification is sent.
url string(uri) false none Url to the new available data.

webhookPing

{
  "timestamp": "2018-05-15T14:22:24Z",
  "event": "PING"
}

AccessLink sends ping message as HTTP POST to callback URL being registered when creating new or modifying webhook. Ping message is sent to verify webhook URL. Receiving service must response to ping message with 200 OK or the webhook is not created/modified.

Properties

Name Type Required Restrictions Description
timestamp string(date-time) false none Time when webhook ping is sent.
event string false none Only possible value is PING for ping message.

Enumerated Values

Property Value
event PING

webhookRequest

{
  "events": [
    "EXERCISE"
  ],
  "url": "https://myapp.example.com/acl_webhook"
}

Properties

Name Type Required Restrictions Description
events [webhookType] true none Type of events to subscribe.
url string(uri) true none Url where the webhook notification is sent.

webhookType

"EXERCISE, SLEEP, CONTINUOUS_HEART_RATE, SLEEP_WISE_CIRCADIAN_BEDTIME, SLEEP_WISE_ALERTNESS"

Event type to subscribe. Currently EXERCISE, SLEEP, CONTINUOUS_HEART_RATE, SLEEP_WISE_CIRCADIAN_BEDTIME and SLEEP_WISE_ALERTNESS are supported.

Properties

Name Type Required Restrictions Description
anonymous string false none Event type to subscribe. Currently EXERCISE, SLEEP, CONTINUOUS_HEART_RATE, SLEEP_WISE_CIRCADIAN_BEDTIME and SLEEP_WISE_ALERTNESS are supported.

Enumerated Values

Property Value
anonymous EXERCISE, SLEEP, CONTINUOUS_HEART_RATE, SLEEP_WISE_CIRCADIAN_BEDTIME, SLEEP_WISE_ALERTNESS

zone

{
  "index": 1,
  "lower-limit": 110,
  "upper-limit": 130,
  "in-zone": "PT4S"
}

Heart-rate zone information

Properties

Name Type Required Restrictions Description
index integer(int32) false none Zone list index
lower-limit integer(int32) false none Lower heart-rate boundary of the zone
upper-limit integer(int32) false none Upper heart-rate boundary of the zone
in-zone string false none Time duration spent in the zone ISO 8601

zones

{
  "zone": [
    {
      "index": 1,
      "lower-limit": 110,
      "upper-limit": 130,
      "in-zone": "PT4S"
    }
  ]
}

List containing the times (in zone) in different heart rate zones (i.e. Heart rate between lower and upper values). Zone is null if no zone information available.

Properties

Name Type Required Restrictions Description
zone [zone] false none List of heart rate zones.

sleep

{
  "polar_user": "https://www.polaraccesslink/v3/users/1",
  "date": "2020-01-01",
  "sleep_start_time": "2020-01-01T00:39:07+03:00",
  "sleep_end_time": "2020-01-01T09:19:37+03:00",
  "device_id": "1111AAAA",
  "continuity": 2.1,
  "continuity_class": 2,
  "light_sleep": 1000,
  "deep_sleep": 1000,
  "rem_sleep": 1000,
  "unrecognized_sleep_stage": 1000,
  "sleep_score": 80,
  "total_interruption_duration": 1000,
  "sleep_charge": 3,
  "sleep_goal": 28800,
  "sleep_rating": 3,
  "short_interruption_duration": 500,
  "long_interruption_duration": 300,
  "sleep_cycles": 6,
  "group_duration_score": 100,
  "group_solidity_score": 75,
  "group_regeneration_score": 54.2,
  "hypnogram": {
    "00:39": 2,
    "00:50": 3,
    "01:23": 6
  },
  "heart_rate_samples": {
    "00:41": 76,
    "00:46": 77,
    "00:51": 76
  }
}

Properties

Name Type Required Restrictions Description
polar_user string false none Absolute link to user owning the sleep
date string(date) false none Result date of the sleep
sleep_start_time string(date-time) false none Start timestamp of the sleep as ISO-8601 datetime string
sleep_end_time string(date-time) false none End timestamp of the sleep as ISO-8601 datetime string
device_id string false none Id of the device the sleep was measured with
continuity number(float) false none Continuity is an estimate of how continuous the sleep was on a scale of 1.0 – 5.0, where 5.0 reflects uninterrupted sleep. The lower the value the more fragmented the sleep was.
continuity_class integer(int32) false none Verbal assessments of sleep continuity Very continuous sleep (5) Continuous sleep (4) Fairly continuous sleep (3) Fairly fragmented sleep (2) Fragmented sleep (1)
light_sleep integer(int32) false none Total time in seconds spent in light sleep stage between when you fell asleep and when you woke up. Corresponds to N1+ N2 according to AASM classification.
deep_sleep integer(int32) false none Total time in seconds spent in the deep sleep stage between when you fell asleep and when you woke up. Corresponds to N3 according to AASM classification.
rem_sleep integer(int32) false none Total time in seconds spent in REM sleep stage between when you fell asleep and when you woke up. REM stands for rapid eye movement.
unrecognized_sleep_stage integer(int32) false none Total time in seconds spent in unrecognised sleep stage. Sometimes it's impossible to recognize sleep stages. This might happen when, for example, the wrist strap is not tight enough, or if you sleep on your hand.
sleep_score integer(int32) false none Sleep score summarizes the amount and quality of your sleep into a single number on a scale of 1 – 100. Sleep score tells you how well you slept compared to the indicators of a good night's sleep based on the current sleep science. It consists of six components; sleep time, long interruptions, continuity, actual sleep, REM sleep, and deep sleep.
total_interruption_duration integer(int32) false none The total time in seconds you spent awake between when you fell asleep and when you woke up.
sleep_charge integer(int32) false none Sleep score compared to your usual level from the past 28 days.Scale: much below usual (1) – below usual (2) – usual (3) – above usual (4) – much above usual(5).
sleep_goal integer(int32) false none Time goal in seconds for sleep selectedby user. A default value of the setting is based on age-related sleep duration recommendations.
sleep_rating integer(int32) false none Numeric value given by user for representing the quality of sleep. Selection scale: Very poorly(1), poorly(2), ok(3), well(4), very well(5). 0 means no value is given.
short_interruption_duration integer(int32) false none Total time in seconds of short interruptions. Short interruption is interruption in sleep of less than 90 seconds.
long_interruption_duration integer(int32) false none Total time in seconds of long interruptions. Long interruption is interruption in sleep of 90 seconds or more.
sleep_cycles integer(int32) false none Number of sleep cycles.
group_duration_score number(float) false none Sleep score consists of six components that are grouped under three themes. Score for sleep duration theme looks at your sleep time compared to your ‘preferred sleep time’ setting and the age-related duration recommendations. Group duration score ranges from 1.0 to 100.0. It is interpreted as textual feedback: poor, moderate or good amount.
group_solidity_score number(float) false none Sleep score consists of six components that are grouped under three themes. Score for sleep solidity theme is the average of the component scores of long interruptions, continuity and actual sleep. Group solidity score ranges from 1.0 to 100.0. It is interpreted as textual feedback: poor, moderate or good solidity.
group_regeneration_score number(float) false none Sleep score consists of six components that are grouped under three themes. Score for regeneration theme is the average of the scores of REM sleep and deep sleep. Group regeneration score ranges from 1.0 to 100.0. It is interpreted as textual feedback: poor, moderate or good regeneration
hypnogram object false none The time span between when you fell asleep and when you woke up is classified into light, deep or REM sleep, or unrecognised or wake in 30-s epochs. 0 = WAKE, 1 = REM, 2 = LIGHTER NON-REM, 3 = LIGHT NON-REM, 4 = DEEP NON-REM, 5 = UNKNOWN (eg. due to bad skin contact).
heart_rate_samples object false none 5 min average samples of heart rate from the duration of the sleep. Default time between samples is 5 minutes. There may be periods with samples more often than every 5 minutes. Unit of samples is beats per minute (bpm).

nights

{
  "nights": [
    {
      "polar_user": "https://www.polaraccesslink/v3/users/1",
      "date": "2020-01-01",
      "sleep_start_time": "2020-01-01T00:39:07+03:00",
      "sleep_end_time": "2020-01-01T09:19:37+03:00",
      "device_id": "1111AAAA",
      "continuity": 2.1,
      "continuity_class": 2,
      "light_sleep": 1000,
      "deep_sleep": 1000,
      "rem_sleep": 1000,
      "unrecognized_sleep_stage": 1000,
      "sleep_score": 80,
      "total_interruption_duration": 1000,
      "sleep_charge": 3,
      "sleep_goal": 28800,
      "sleep_rating": 3,
      "short_interruption_duration": 500,
      "long_interruption_duration": 300,
      "sleep_cycles": 6,
      "group_duration_score": 100,
      "group_solidity_score": 75,
      "group_regeneration_score": 54.2,
      "hypnogram": {
        "00:39": 2,
        "00:50": 3,
        "01:23": 6
      },
      "heart_rate_samples": {
        "00:41": 76,
        "00:46": 77,
        "00:51": 76
      }
    }
  ]
}

Sleep list

Properties

Name Type Required Restrictions Description
nights [sleep] false none List of sleep objects

available-sleep

{
  "date": "2020-01-01",
  "start_time": "2020-01-01T00:39:07+03:00",
  "end_time": "2020-01-01T09:39:07+03:00"
}

Properties

Name Type Required Restrictions Description
date string(date) false none Result date of the sleep
start_time string(date-time) false none Start timestamp of the sleep as ISO-8601 datetime string
end_time string(date-time) false none End timestamp of the sleep as ISO-8601 datetime string

available-sleeps

{
  "available": [
    {
      "date": "2020-01-01",
      "start_time": "2020-01-01T00:39:07+03:00",
      "end_time": "2020-01-01T09:39:07+03:00"
    }
  ]
}

Properties

Name Type Required Restrictions Description
available [available-sleep] false none List of available sleep data

nightly-recharge

{
  "polar_user": "https://www.polaraccesslink/v3/users/1",
  "date": "2020-01-01",
  "heart_rate_avg": 70,
  "beat_to_beat_avg": 816,
  "heart_rate_variability_avg": 28,
  "breathing_rate_avg": 14.1,
  "nightly_recharge_status": 3,
  "ans_charge": 0,
  "ans_charge_status": 3,
  "hrv_samples": {
    "00:41": 14,
    "00:46": 14,
    "00:51": 15
  },
  "breathing_samples": {
    "00:39": 13.4,
    "00:44": 13.5,
    "00:49": 13.5
  }
}

Properties

Name Type Required Restrictions Description
polar_user string false none Absolute link to user owning the sleep
date string(date) false none Result date of the Nightly Recharge
heart_rate_avg integer(int32) false none Average heart rate as beats per minute (bpm) during a 4-hour period starting at 30 minutes after falling asleep.
beat_to_beat_avg integer(int32) false none Average time in milliseconds (ms) between successive heart beats during a 4-hour period starting at 30 minutes after falling asleep.
heart_rate_variability_avg integer(int32) false none Average variation in the time in milliseconds (ms) between successive heart beats during a 4-hour period starting at 30 minutes after falling asleep. The Heart rate variability is Root Mean Square of Successive Differences (RMSSD) in beat-to-beat intervals.
breathing_rate_avg number(float) false none Average breathing rate as breaths per minute (bpm) during a 4-hour period starting at 30 minutes after falling asleep.
nightly_recharge_status integer(int32) false none The Nightly Recharge status shows how your body was able to recover from training and stress during the night. Scores for both ANS charge and sleep charge are taken into account. Nightly Recharge status has the following (6-item) scale: very poor (1) – poor (2) – compromised (3) – OK (4) – good (5) – very good (6).
ans_charge number(float) false none ANS stands for autonomic nervous system. ANS charge is formed by measuring heart rate, heart rate variability and breathing rate during roughly the first four hours of your sleep. It is formed comparing your last night to your usual levels from the past 28 days. The scale is from -10.0 to +10.0. Around zero is your usual level.
ans_charge_status integer(int32) false none ANS charge status = much below usual (1) - below usual (2) - usual (3) - above usual (4) - much above usual (5)
hrv_samples object false none 5-minute average samples of heart rate variability. Unit of samples is milliseconds(ms).
breathing_samples object false none 5-minute average samples of breathing rate. Unit of samples is breaths per minute (bpm).

continuous-heartrate

{
  "polar_user": "https://polaraccesslink.com/v3/users/627139",
  "date": "2022-09-12",
  "heart_rate_samples": [
    {
      "heart_rate": 63,
      "sample_time": "00:02:08"
    },
    {
      "heart_rate": 62,
      "sample_time": "00:07:08"
    }
  ]
}

*5 min average samples of heart rate from the duration of the continuous heart rate measurement. Default time between samples is 5 minutes. There may be periods with samples more often than every 5 minutes. Unit of samples is beats per minute (bpm). *

Properties

Name Type Required Restrictions Description
polar_user string false none Absolute link to user owning the continuous heart rate samples
date string(date) false none Result date of the Continuous Heart Rate
heart_rate_samples object false none none
» heart_rate integer false none heart rate rpm
» sample_time string(date) false none Measurement time of heart rate. Device time used for measurement

recharges

{
  "recharges": [
    {
      "polar_user": "https://www.polaraccesslink/v3/users/1",
      "date": "2020-01-01",
      "heart_rate_avg": 70,
      "beat_to_beat_avg": 816,
      "heart_rate_variability_avg": 28,
      "breathing_rate_avg": 14.1,
      "nightly_recharge_status": 3,
      "ans_charge": 0,
      "ans_charge_status": 3,
      "hrv_samples": {
        "00:41": 14,
        "00:46": 14,
        "00:51": 15
      },
      "breathing_samples": {
        "00:39": 13.4,
        "00:44": 13.5,
        "00:49": 13.5
      }
    }
  ]
}

Nightly Recharge list

Properties

Name Type Required Restrictions Description
recharges [nightly-recharge] false none List of Nightly Recharge objects

alertness

{
  "grade": 9.9,
  "grade_validity_seconds": 57600,
  "grade_type": "GRADE_TYPE_PRIMARY",
  "grade_classification": "GRADE_CLASSIFICATION_STRONG",
  "validity": "VALIDITY_ESTIMATE",
  "sleep_inertia": "SLEEP_INERTIA_MILD",
  "sleep_type": "SLEEP_TYPE_PRIMARY",
  "result_type": "ALERTNESS_TYPE_HISTORY",
  "period_start_time": "2022-11-20T20:52:20",
  "period_end_time": "2022-11-21T19:15:52",
  "sleep_period_start_time": "2022-11-20T20:52:20.57",
  "sleep_period_end_time": "2022-11-21T04:11:20.57",
  "sleep_timezone_offset_minutes": 120,
  "hourly_data": [
    {
      "validity": "VALIDITY_ESTIMATE",
      "alertness_level": "ALERTNESS_LEVEL_LOW",
      "start_time": "2022-11-21T04:12:00",
      "end_time": "2022-11-21T05:00:00"
    }
  ]
}

Alertness period data

Properties

Name Type Required Restrictions Description
grade number(double) false none Grade
grade_validity_seconds number(int) false none Grade validity seconds
grade_type string false none Grade type
grade_classification string false none Grade classification
validity string false none Validity
sleep_inertia string false none Sleep inertia
sleep_type string false none Sleep type
result_type string false none Result type
period_start_time string(date) false none Alertness period start time (UTC)
period_end_time string(date) false none Alertness period end time (UTC)
sleep_period_start_time string(date) false none Sleep period start time (UTC)
sleep_period_end_time string(date) false none Sleep period end time (UTC)
sleep_timezone_offset_minutes number(int) false none Sleep timezone offset minutes
hourly_data [alertness-hourly-data] false none Alertness hourly data for the alertness period

Enumerated Values

Property Value
grade_type GRADE_TYPE_UNKNOWN
grade_type GRADE_TYPE_PRIMARY
grade_type GRADE_TYPE_ADDITIONAL
grade_classification GRADE_CLASSIFICATION_UNKNOWN
grade_classification GRADE_CLASSIFICATION_WEAK
grade_classification GRADE_CLASSIFICATION_FAIR
grade_classification GRADE_CLASSIFICATION_STRONG
grade_classification GRADE_CLASSIFICATION_EXCELLENT
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
sleep_inertia SLEEP_INERTIA_UNKNOWN
sleep_inertia SLEEP_INERTIA_NO_INERTIA
sleep_inertia SLEEP_INERTIA_MILD
sleep_inertia SLEEP_INERTIA_MODERATE
sleep_inertia SLEEP_INERTIA_HEAVY
sleep_type SLEEP_TYPE_UNKNOWN
sleep_type SLEEP_TYPE_PRIMARY
sleep_type SLEEP_TYPE_SECONDARY
sleep_type SLEEP_TYPE_ARTIFICIAL
result_type ALERTNESS_TYPE_UNKNOWN
result_type ALERTNESS_TYPE_PREDICTION
result_type ALERTNESS_TYPE_HISTORY

circadian-bedtime

{
  "validity": "VALIDITY_ESTIMATE",
  "quality": "CIRCADIAN_BEDTIME_QUALITY_COMPROMISED",
  "result_type": "CIRCADIAN_BEDTIME_TYPE_HISTORY",
  "period_start_time": "2022-11-20T21:18:30",
  "period_end_time": "2022-11-21T05:18:30",
  "preferred_sleep_period_start_time": "2022-11-20T21:18:30",
  "preferred_sleep_period_end_time": "2022-11-21T05:18:30",
  "sleep_gate_start_time": "2022-11-20T21:03:30",
  "sleep_gate_end_time": "2022-11-20T21:33:30",
  "sleep_timezone_offset_minutes": 120
}

Circadian bedtime period data

Properties

Name Type Required Restrictions Description
validity string false none Validity
quality string false none Quality
result_type string false none Result type
period_start_time string(date) false none Circadian bedtime period start time (UTC)
period_end_time string(date) false none Circadian bedtime period end time (UTC)
preferred_sleep_period_start_time string(date) false none Circadian bedtime preferred sleep period start time (UTC)
preferred_sleep_period_end_time string(date) false none Circadian bedtime preferred sleep period end time (UTC)
sleep_gate_start_time string(date) false none Circadian bedtime sleep gate (suggested fall a sleep window) start time (UTC)
sleep_gate_end_time string(date) false none Circadian bedtime sleep gate (suggested fall a sleep window) end time (UTC)
sleep_timezone_offset_minutes number(int) false none Sleep timezone offset minutes

Enumerated Values

Property Value
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
quality CIRCADIAN_BEDTIME_QUALITY_UNKNOWN
quality CIRCADIAN_BEDTIME_QUALITY_WEAK
quality CIRCADIAN_BEDTIME_QUALITY_COMPROMISED
quality CIRCADIAN_BEDTIME_QUALITY_CLEARLY_RECOGNIZABLE
result_type CIRCADIAN_BEDTIME_TYPE_UNKNOWN
result_type CIRCADIAN_BEDTIME_TYPE_PREDICTION
result_type CIRCADIAN_BEDTIME_TYPE_HISTORY

alertness-hourly-data

{
  "validity": "VALIDITY_ESTIMATE",
  "alertness_level": "ALERTNESS_LEVEL_VERY_HIGH",
  "start_time": "2022-11-21T04:00:00",
  "end_time": "2022-11-21T05:00:00"
}

Hourly data for the alertness period

Properties

Name Type Required Restrictions Description
validity string false none Validity
alertness_level string false none Alertness level
start_time string(date) false none Alertness period start time (UTC)
end_time string(date) false none Alertness period end time (UTC)

Enumerated Values

Property Value
validity VALIDITY_UNKNOWN
validity VALIDITY_RESET
validity VALIDITY_NOT_VALID
validity VALIDITY_ESTIMATE
validity VALIDITY_VALID
alertness_level ALERTNESS_LEVEL_UNKNOWN
alertness_level ALERTNESS_LEVEL_MINIMAL
alertness_level ALERTNESS_LEVEL_VERY_LOW
alertness_level ALERTNESS_LEVEL_LOW
alertness_level ALERTNESS_LEVEL_HIGH
alertness_level ALERTNESS_LEVEL_VERY_HIGH

body-temperature-period

{
  "source_device_id": "1111AAAA",
  "measurement_type": "TM_CORE_TEMPERATURE",
  "sensor_location": "SL_PROXIMAL",
  "start_time": "2023-10-20T04:00:00",
  "end_time": "2023-10-20T05:00:00",
  "modified_time": "2023-10-20T04:00:00",
  "samples": [
    {
      "temperature_celsius": 36.5,
      "recording_time_delta_milliseconds": 123
    }
  ]
}

Properties

Name Type Required Restrictions Description
source_device_id string false none none
measurement_type string false none Measurement type
sensor_location string false none Sensor location
start_time string(date-time) false none Measurement period start time (UTC)
end_time string(date-time) false none Measurement period end time (UTC)
modified_time string(date-time) false none Measurement period modified time (UTC)
samples [body-temperature-sample] false none none

Enumerated Values

Property Value
measurement_type TM_UNKNOWN
measurement_type TM_SKIN_TEMPERATURE
measurement_type TM_CORE_TEMPERATURE
sensor_location SL_UNKNOWN
sensor_location SL_DISTAL
sensor_location SL_PROXIMAL

body-temperature-sample

{
  "temperature_celsius": 36.5,
  "recording_time_delta_milliseconds": 123
}

Properties

Name Type Required Restrictions Description
temperature_celsius number(float) false none none
recording_time_delta_milliseconds integer(int64) false none none

skin-temperature

{
  "sleep_time_skin_temperature_celsius": 36.5,
  "deviation_from_baseline_celsius": 0.5,
  "sleep_date": "2023-10-20"
}

Properties

Name Type Required Restrictions Description
sleep_time_skin_temperature_celsius number(float) false none none
deviation_from_baseline_celsius number(float) false none none
sleep_date string(date) false none none

skin-contact-period

{
  "source_device_id": "1111AAAA",
  "start_time": "2023-10-20T04:00:00",
  "end_time": "2023-10-20T05:00:00",
  "modified_time": "2023-10-20T04:00:00",
  "skin_contact_changes": [
    {
      "skin_contact": true,
      "recording_time_delta_milliseconds": 123
    }
  ]
}

Properties

Name Type Required Restrictions Description
source_device_id string false none none
start_time string(date-time) false none Measurement period start time (UTC)
end_time string(date-time) false none Measurement period end time (UTC)
modified_time string(date-time) false none Measurement period modified time (UTC)
skin_contact_changes [skin-contact-change] false none none

skin-contact-change

{
  "skin_contact": true,
  "recording_time_delta_milliseconds": 123
}

Properties

Name Type Required Restrictions Description
skin_contact boolean false none none
recording_time_delta_milliseconds integer(int64) false none none

ecg-test-result

{
  "source_device_id": "1111AAAA",
  "test_time": 1697787256,
  "time_zone_offset": 180,
  "average_heart_rate_bpm": 60,
  "heart_rate_variability_ms": 0,
  "heart_rate_variability_level": "ECG_HRV_LEVEL_NO_BASELINE",
  "rri_ms": 100,
  "pulse_transit_time_systolic_ms": 100,
  "pulse_transit_time_diastolic_ms": 100,
  "pulse_transit_time_quality_index": 100,
  "samples": [
    {
      "recording_time_delta_ms": 123,
      "amplitude_mv": 0.1
    }
  ],
  "quality_measurements": [
    {
      "recording_time_delta_ms": 123,
      "quality_level": "ECG_QUALITY_HIGH"
    }
  ]
}

Properties

Name Type Required Restrictions Description
source_device_id string false none none
test_time integer(int64) false none none
time_zone_offset integer(int32) false none none
average_heart_rate_bpm integer(uint32) false none none
heart_rate_variability_ms number(float) false none none
heart_rate_variability_level string false none none
rri_ms number(float) false none none
pulse_transit_time_systolic_ms number(float) false none none
pulse_transit_time_diastolic_ms number(float) false none none
pulse_transit_time_quality_index number(float) false none none
samples [ecg-sample] false none none
quality_measurements [quality-measurement] false none none

Enumerated Values

Property Value
heart_rate_variability_level ECG_HRV_LEVEL_NO_BASELINE
heart_rate_variability_level ECG_HRV_LEVEL_BELOW_USUAL
heart_rate_variability_level ECG_HRV_LEVEL_USUAL
heart_rate_variability_level ECG_HRV_LEVEL_ABOVE_USUAL

ecg-sample

{
  "recording_time_delta_ms": 123,
  "amplitude_mv": 0.1
}

Properties

Name Type Required Restrictions Description
recording_time_delta_ms integer(int32) false none none
amplitude_mv number(float) false none none

quality-measurement

{
  "recording_time_delta_ms": 123,
  "quality_level": "ECG_QUALITY_HIGH"
}

Properties

Name Type Required Restrictions Description
recording_time_delta_ms integer(int32) false none none
quality_level string false none none

Enumerated Values

Property Value
quality_level ECG_QUALITY_UNKNOWN
quality_level ECG_QUALITY_NO_CONTACT
quality_level ECG_QUALITY_LOW
quality_level ECG_QUALITY_HIGH

spo2-test-result

{
  "source_device_id": "1111AAAA",
  "test_time": 1697787256,
  "time_zone_offset": 180,
  "test_status": "SPO2_TEST_PASSED",
  "blood_oxygen_percent": 95,
  "spo2_class": "SPO2_CLASS_NORMAL",
  "spo2_value_deviation_from_baseline": "DEVIATION_NO_BASELINE",
  "spo2_quality_average_percent": 90,
  "average_heart_rate_bpm": 60,
  "heart_rate_variability_ms": 100,
  "spo2_hrv_deviation_from_baseline": "DEVIATION_NO_BASELINE",
  "altitude_meters": 50
}

Properties

Name Type Required Restrictions Description
source_device_id string false none none
test_time integer(int64) false none none
time_zone_offset integer(int32) false none none
test_status string false none none
blood_oxygen_percent integer(int32) false none none
spo2_class string false none none
spo2_value_deviation_from_baseline string false none none
spo2_quality_average_percent number(float) false none none
average_heart_rate_bpm integer(uint32) false none none
heart_rate_variability_ms number(float) false none none
spo2_hrv_deviation_from_baseline string false none none
altitude_meters number(float) false none none

Enumerated Values

Property Value
test_status SPO2_TEST_PASSED
test_status SPO2_TEST_INCONCLUSIVE_TOO_LOW_QUALITY_IN_SAMPLES
test_status SPO2_TEST_INCONCLUSIVE_TOO_LOW_OVERALL_QUALITY
test_status SPO2_TEST_INCONCLUSIVE_TOO_MANY_MISSING_SAMPLES
spo2_class SPO2_CLASS_UNKNOWN
spo2_class SPO2_CLASS_VERY_LOW
spo2_class SPO2_CLASS_LOW
spo2_class SPO2_CLASS_NORMAL
spo2_value_deviation_from_baseline DEVIATION_NO_BASELINE
spo2_value_deviation_from_baseline DEVIATION_BELOW_USUAL
spo2_value_deviation_from_baseline DEVIATION_USUAL
spo2_value_deviation_from_baseline DEVIATION_ABOVE_USUAL
spo2_hrv_deviation_from_baseline DEVIATION_NO_BASELINE
spo2_hrv_deviation_from_baseline DEVIATION_BELOW_USUAL
spo2_hrv_deviation_from_baseline DEVIATION_USUAL
spo2_hrv_deviation_from_baseline DEVIATION_ABOVE_USUAL

Appendix

Detailed sport info values in exercise entity

detailed-sport-info Sport in Polar Flow
AEROBICS Aerobics
AMERICAN_FOOTBALL Football
AQUATICS Aqua fitness
BACKCOUNTRY_SKIING Backcountry skiing
BADMINTON Badminton
BALLET_DANCING Ballet
BALLROOM_DANCING Ballroom
BASEBALL Baseball
BASKETBALL Basketball
BEACH_VOLLEYBALL Beach volley
BIATHLON Biathlon
BODY_AND_MIND Body&Mind
BOOTCAMP Bootcamp
BOXING Boxing
CIRCUIT_TRAINING Circuit training
CORE Core
CRICKET Cricket
CROSS_TRAINER Cross-trainer
CROSS_COUNTRY_RUNNING Cross-country running
CROSS-COUNTRY_SKIING Skiing
CYCLING Cycling
CLIMBING Climbing
CURLING Curling
DANCING Dancing
DOWNHILL_SKIING Downhill skiing
DUATHLON Duathlon
DUATHLON_CYCLING Cycling
DUATHLON_RUNNING Running
E_BIKE Electric biking
FIELD_HOCKEY Field hockey
FINNISH_BASEBALL Finnish baseball
FITNESS_DANCING Fitness dancing
FITNESS_MARTIAL_ARTS Fitness martial arts
FITNESS_STEP Step workout
FLOORBALL Floorball
FREE_MULTISPORT Multisport
FRISBEEGOLF Disc golf
FUNCTIONAL_TRAINING Functional training
FUTSAL Futsal
GOLF Golf
GROUP_EXERCISE Group exercise
GYMNASTICK Gymnastics
HANDBALL Handball
HIIT High-intensity interval training
HIKING Hiking
ICE_HOCKEY Ice hockey
ICE_SKATING Ice skating
INDOOR_CYCLING Indoor cycling
INDOOR_ROWING Indoor rowing
INLINE_SKATING Inline skating
JAZZ_DANCING Jazz
JOGGING Jogging
JUDO_MARTIAL_ARTS Judo
KETTLEBELL Kettlebell
KICKBOXING_MARTIAL_ARTS Kickboxing
LATIN_DANCING Latin
LES_MILLS_BARRE LES MILLS BARRE
LES_MILLS_BODYATTACK LES MILLS BODYATTACK
LES_MILLS_BODYBALANCE LES MILLS BODYBALANCE
LES_MILLS_BODYCOMBAT LES MILLS BODYCOMBAT
LES_MILLS_BODYJAM LES MILLS BODYJAM
LES_MILLS_BODYPUMP LES MILLS BODYPUMP
LES_MILLS_BODYSTEP LES MILLS BODYSTEP
LES_MILLS_CXWORKS LES MILLS CXWORX
LES_MILLS_GRIT_ATHLETIC LES MILLS GRIT Athletic
LES_MILLS_GRIT_CARDIO LES MILLS GRIT Cardio
LES_MILLS_GRIT_STRENGTH LES MILLS GRIT Strength
LES_MILLS_RPM LES MILLS RPM
LES_MILLS_SHBAM LES MILLS SH'BAM
LES_MILLS_SPRINT LES MILLS SPRINT
LES_MILLS_TONE LES MILLS TONE
LES_MILLS_TRIP LES MILLS TRIP
MOBILITY_DYNAMIC Mobility (dynamic)
MOBILITY_STATIC Mobility (static)
MODERN_DANCING Modern
MOTORSPORTS_CAR_RACING Car racing
MOTORSPORTS_ENDURO Enduro
MOTORSPORTS_HARD_ENDURO Hard Enduro
MOTORSPORTS_MOTOCROSS Motocorss
MOTORSPORTS_ROADRACING Road racing
MOTORSPORTS_SNOCROSS Snocross
MOUNTAIN_BIKING Mountain biking
NORDIC_WALKING Nordic walking
OFFROADDUATHLON Off-road duathlon
OFFROADDUATHLON_CYCLING Mountain biking
OFFROADDUATHLON_RUNNING Trail running
OFFROADTRIATHLON Off-road triathlon
OFFROADTRIATHLON_CYCLING Mountain biking
OFFROADTRIATHLON_RUNNING Trail running
OFFROADTRIATHLON_SWIMMING Open water swimming
OPEN_WATER_SWIMMING Open water swimming
ORIENTEERING Orienteering
ORIENTEERING_MTB Mountain bike orienteering
ORIENTEERING_SKI Ski orienteering
OTHER_INDOOR Other indoor
OTHER_OUTDOOR Other outdoor
PADEL Padel racing
PARASPORTS_WHEELCHAIR Wheelchair racing
PILATES Pilates
POOL_SWIMMING Pool swimming
RIDING Riding
ROAD_BIKING Road cycling
ROAD_RUNNING Road running
ROLLER_BLADING Roller skating
ROLLER_SKIING_CLASSIC Classic roller skiing
ROLLER_SKIING_FREESTYLE Freestyle roller skiing
ROWING Rowing
RUGBY Rugby
RUNNING Running
SHOW_DANCING Show
SKATEBOARDING Skateboarding
SKATING Skating
SNOWBOARDING Snowboarding
SNOWSHOE_TREKKING Snowshoe trekking
SOCCER Soccer
SPINNING Spinning
SUP SUP
SQUASH Squash
STREET_DANCING Street
STRENGTH_TRAINING Strength training
STRETCHING Stretching
SWIMMING Swimming
TABLE_TENNIS Table tennis
TAEKWONDO_MARTIAL_ARTS Taekwondo
TELEMARK_SKIING Telemark skiing
TENNIS Tennis
TRACK_AND_FIELD_RUNNING Track&field running
TRAIL_RUNNING Trail running
TREADMILL_RUNNING Treadmill running
TRIATHLON Triathlon
TRIATHLON_CYCLING Cycling
TRIATHLON_RUNNING Running
TRIATHLON_SWIMMING Open water swimming
TROTTING Trotting
ULTRARUNNING_RUNNING Ultra running
VERTICALSPORTS_WALLCLIMBING Climbing (indoor)
VERTICALSPORTS_OUTCLIMBING Climbing (outdoor)
VOLLEYBALL Volleyball
WALKING Walking
WATER_EXERCISE Water sports
WATER_RUNNING Water running
WATERSPORTS_CANOEING Canoeing
WATERSPORTS_KAYAKING Kayaking
WATERSPORTS_KITESURFING Kitesurfing
WATERSPORTS_SAILING Sailing
WATERSPORTS_SURFING Surfing
WATERSPORTS_WAKEBOARDING Wakeboarding
WATERSPORTS_WATERSKI Water skiing
WATERSPORTS_WINDSURFING Windsurfing
XC_SKIING_CLASSIC Classic XC skiing
XC_SKIING_FREESTYLE Freestyle XC skiing
YOGA Yoga

Sport type mapping in FIT-files

If Sport is not defined in following table, then it defaults to FIT sport type GENERIC.

Sport in Polar Flow FIT sport type (subsport if appl.)
Aerobics GENERIC
Australian football GENERIC
Football AMERICAN_FOOTBALL
Aqua fitness GENERIC
Backcountry skiing CROSS_COUNTRY_SKIING, SubSport: BACKCOUNTRY
Badminton GENERIC
Ballet GENERIC
Ballroom GENERIC
Baseball GENERIC
Basketball BASKETBALL
Beach volley GENERIC
Biathlon GENERIC
Body&Mind GENERIC
Bootcamp GENERIC
Boxing BOXING
Bowling GENERIC
Circuit training TRAINING
Core TRAINING
Cricket GENERIC
Curling GENERIC
High-intensity interval training TRAINING
Cross-trainer TRAINING, SubSport: INDOOR_RUNNING
Cycling CYCLING
Dancing GENERIC
Downhill skiing ALPINE_SKIING
(Duathlon) Cycling CYCLING
(Duathlon) Running RUNNING
Field hockey GENERIC
Finnish baseball GENERIC
Fitness dancing GENERIC
Martial arts GENERIC
Step workout GENERIC
Floorball GENERIC
Disc golf GENERIC
Functional training TRAINING
Futsal GENERIC
Golf GOLF
Group exercise TRAINING
Gymnastics GENERIC
Handball GENERIC
Hiking HIKING
Ice hockey GENERIC
Ice skating ICE_SKATING
Indoor cycling CYCLING, SubSport: INDOOR_CYCLING
Indoor rowing ROWING, SubSport: INDOOR_ROWING
Inline skating INLINE_SKATING
Jazz GENERIC
Jogging RUNNING
Judo GENERIC
Kettlebell GENERIC
Korfball GENERIC
Kickbike GENERIC
Kickboxing GENERIC
Latin GENERIC
Lacrosse GENERIC
Mobility (dynamic) GENERIC, SubSport: FLEXIBILITY_TRAINING
Mobility (static) GENERIC, SubSport: FLEXIBILITY_TRAINING
Modern GENERIC
Mountain biking CYCLING, SubSport: MOUNTAIN
Nordic walking WALKING
Netball GENERIC
(off road duathlon) Mountain biking CYCLING, SubSport: BACKCOUNTRY
(off road duathlon) Trail running RUNNING, SubSport: BACKCOUNTRY
(off road thiathlon) Mountain biking CYCLING, SubSport: BACKCOUNTRY
(off road thiathlon) Trail running RUNNING, SubSport: BACKCOUNTRY
(off road thiathlon) Open water swimming SWIMMING, SubSport: BACKCOUNTRY
Open water swimming SWIMMING, SubSport: OPEN_WATER
Orienteering GENERIC, SubSport: BACKCOUNTRY
Mountain bike orienteering CYCLING, SubSport: BACKCOUNTRY
Ski orienteering CROSS_COUNTRY_SKIING, SubSport: BACKCOUNTRY
Other indoor GENERIC
Other outdoor GENERIC
Obstacle course racing GENERIC
Wheelchair racing GENERIC
Pilates GENERIC, SubSport: PILATES
Pool swimming SWIMMING
Riding HORSEBACK_RIDING
Ringette GENERIC
Road cycling CYCLING, SubSport: ROAD
Road running RUNNING, SubSport: STREET
Roller skating GENERIC
Classic roller skiing GENERIC
Freestyle roller skiing GENERIC
Rowing ROWING
Rugby GENERIC
Running RUNNING, SubSport: STREET
Show GENERIC
Skating ICE_SKATING
Snowboarding SNOWBOARDING
Snowshoe trekking SNOWSHOEING
Soccer SOCCER
Spinning GENERIC, SubSport: INDOOR_CYCLING
Squash GENERIC
Skiing CROSS_COUNTRY_SKIING
Shooting sports GENERIC
Street GENERIC
Strength training TRAINING, SubSport: STRENGTH_TRAINING
Stretching GENERIC, SubSport: FLEXIBILITY_TRAINING
Swimming SWIMMING
Table tennis GENERIC
Telemark skiing ALPINE_SKIING
Tennis TENNIS
Track&field running RUNNING, SubSport: TRACK
Trail running RUNNING, SubSport: TRAIL
Treadmill running RUNNING, SubSport: TREADMILL
(Thriathlon) Cycling CYCLING
(Thriathlon) Running RUNNING
(Thriathlon) Open water swimming SWIMMING
Trotting GENERIC
Ultra running RUNNING
Walking WALKING
Canoeing KAYAKING
Kayaking KAYAKING
Kitesurfing KITESURFING
Sailing SAILING
Surfing SURFING
Wakeboarding WAKEBOARDING
Water skiing WATER_SKIING
Windsurfing WINDSURFING
Climbing (indoor) GENERIC
Volleyball GENERIC
Classic XC skiing CROSS_COUNTRY_SKIING
Freestyle XC skiing CROSS_COUNTRY_SKIING
Yoga GENERIC, SubSport: YOGA
LES MILLS BODYPUMP GENERIC
LES MILLS BODYATTACK GENERIC
LES MILLS BODYCOMBAT GENERIC
LES MILLS GRIT Cardio GENERIC
LES MILLS GRIT Strength GENERIC
LES MILLS GRIT Athletic GENERIC
LES MILLS SH'BAM GENERIC
LES MILLS RPM GENERIC
LES MILLS BODYJAM GENERIC
LES MILLS BODYSTEP GENERIC
LES MILLS SPRINT GENERIC
LES MILLS TONE GENERIC
LES MILLS BODYBALANCE GENERIC
LES MILLS THE TRIP GENERIC
LES MILLS CORE GENERIC
LES_MILLS_BARRE GENERIC
Skateboarding GENERIC
SUP STAND_UP_PADDLEBOARDING
Taekwondo GENERIC
Water running GENERIC
Water sports GENERIC
Motor sports DRIVING
Hard enduro MOTORCYCLING
Car racing DRIVING
Padel GENERIC
Electric biking E_BIKING
Cross-country running RUNNING, SubSport: BACKCOUNTRY
Climbing (outdoor) ROCK_CLIMBING
Enduro MOTORCYCLING
Road racing DRIVING
Snocross GENERIC
Motocross MOTORCYCLING

Exercise sample types

Key Sample type Unit
0 Heart rate bpm
1 Speed km/h
2 Cadence rpm
3 Altitude m
4 Power W
5 Power pedaling index %
6 Power left-right balance %
7 Air pressure hpa
8 Running cadence spm
9 Temperature °C
10 Distance m
11 RR Interval ms

RR interval samples can contain NULL samples, while other sample types always have a value. NULL sample indicates missing data. In order to get RR interval samples, training needs to be performed with Polar H6, H7, H9 or H10 heart rate sensors. More information.

Activity zone types

Index Activity zone Description
0 Sleep Sleep and rest, lying down
1 Sedentary Sitting and other passive behaviour
2 Light Standing work, light household chores
3 Moderate Walking, dancing, child play outdoor
4 Vigorous Jogging, football, floorball
5 Non Wear Device not worn

Activity zone time series

Example data if the device is synchronized between 04:00 and 05:00. Hour 01 is time between 00:00 - 00:59.59, hour 02 01:00-01:59.59 and so on.

Hour 01 02 03 04 05 06 07 08 09 10 11 ... 24
Zone 0 PT59M PT1H PT45M1S
Zone 1
Zone 2 PT14M59S
Zone 3
Zone 4
Zone 5 PT1M

The data is for specific hour and not cumulative. If there is no data after certain hour, the data is left empty.

Activity step time series

Example data if the device is synchronized between 09:00 and 10:00.

Hour 01 02 03 04 05 06 07 08 09 10 11 ... 24
Steps 5 15 15 8 0 755 1234 956

The data is for specific hour and not cumulative. If there is no data after certain hour, the data is left empty.

Changelog

21.03.2024

New features

05.03.2024

New features

18.01.2024

Improvements

19.12.2023

New features

25.09.2023

Improvements

28.06.2023

New features

13.03.2023

New features

16.11.2022

New features

19.10.2022

New features

06.10.2022

New features

21.09.2022

New features