With start time and end time as input, this API returns the processed phsyiological timeseres data (such as respiratory rate, heart rate, steps etc) at 15 seconds interval. Since this API can result in a humungous amount of data, this API works in 2 steps -
Step 1 :- With first API request, API saves the data in a file inside secured Spire Health cloud. It returns URL of the file to download the data.
Step 2 :- Using URL of the file returned, download the data in CSV format.

Headers

This API requires the API Access Token available at the Research portal. Set this up as an HTTP header before calling the API.

Response format

Processed physiological timeseries data is sampled every 15 seconds (i.e. a row every 15 seconds). Since this API may result in a large amount of data, this API works in following steps -

  1. Once the API is called, processed physiological timeseries data is generated and stored as a gzip file (gzip of a CSV file) inside secured Spire Health's cloud.
  2. API returns URL of the gzip file in JSON format.
  3. Use the URL to download the data on your computer or to a storage system.
  4. In order to use the data in your program, unzip the file into a CSV format and use it inside your program (see the code sample below for details on how to implement through all the steps)
  5. This is how your downloaded CSV will look:
2402
Response CodeDescription
200Successful Operation
400Error messages for invalid input parameters. For example -
Only up to a month of data is allowed in a single call. Please adjust start and stop time accordingly
User with email doesn't exist or not authorized!
401Access token is missing or invalid
403Not a valid key value pair in Authorization header
404The requested API could not be found. Please review your URL
429Too many requests hit the API too quickly

Output Data

Output data is a time series with data returned at 15 seconds interval. Here is the format of data:

Field NameTypeDescription
user_idIntegerUnique ID to identify a user
device_idStringSpire Health wearable device that captured the data
timedate-timeLocal date & time where data was captured
time_zoneStringTimezone in which data was captured. For example - 'America/Chicago','Australia/Brisbane','Europe/Stockholm'. More detailed list available at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
rrFloatMean of the respiratory rate of the user for that 15 seconds interval
rr_conf (deprecated soon)FloatRespiratory rate conf interval. No device can predict respiratory rate 100% accurately. Confidence helps define a range in which true respiratory rate is likely to be there. There is a 95% probablity that true respiratory rate is within 2 respiratory rate confidence interval (i.e. between rr + 2rr_confidence and rr - 2rr_confidence) range. Based upon several tests conducted, it is recommended only to pick respiratory rate that has rr_confidence less than or equal to 0.6.
rr_confidenceBooleanThis field indicates the quality of respiratory rate data -
1 - High-Quality Respiratory Rate Data
0 - Not High Quality
It is recommended that you use only high quality respiratory rate data for your research purposes..
in_sleepBooleanThis field indicates whether the subject was sleeping during that interval -
1 - Subject was sleeping
0 - Subject was not sleeping
It is recommended that you use this field to figure out unique sleep minutes for a subject.
rrvFloatRespiratory rate variability (RRV) is measured firstly by taking each breath and calculating an instantaneous breath rate. So, for example, if the breath lasts 4 seconds, then this represents an instantaneous breath rate of 15 breaths per minute. An array of the last 20 breaths is maintained and the RRV is the median absolute deviation of the breath rates for these last 20 breaths
state_of_mindIntegerIndicates state of mind for the user
0-Neutral
1-Calm
2-Focus
3-Tense
4-Sleep
hrFloatHeart rate. Note that heart rate is not captured continuously by device all the time. Here are the rules for heart rate capture -
- While resting or sleeping, it's captured every 5 minutes
- While walking, every minute
- While running, it's captured continuously for every 15 seconds interval
Note value is null if data is not captured at a timestamp
hr_cfd (deprecated soon)IntegerHeart rate confidence level. Value of 75 and above indicates that HR is good quality data
hr_confidenceBooleanThis field indicates the quality of heart rate data -
1 - High-Quality Heart Rate Data
0 - Not High Quality
It is recommended that you use only high-quality heart rate data for your research purposes.
total_caloriesFloattotal calories burnt for a 15 seconds interval
stepsFloattotal number of steps taken in 15 seconds interval
activity_typeIntegerIndicates activity type for the 15 seconds interval
0-Resting
1-Active
2-Sleeping
algo_versionfloatIndicates the version of Spire algorithm that was used to generate this result

Program samples to test out API

Use the program samples below to test out APIs with your own research data:

cURL

Program below will return a URL for gzip file. Use that URL to download gzip file. Then, unzip to get CSV file with physiological timeseries data.

curl -X GET \
  'https://research-api.spire.io/v1/physio_timeseries?start_time=2019-02-01%2000:00:00&stop_time=2019-02-01%2023:59:59&[email protected]' \
  -H 'Authorization: Bearer 284e8f3320a8500c58ea5b8e7829bdd676ea941bb573bb250d51c0b82f68e19d'

Python

Python program sample below has steps to download physiological timeseries data in CSV format.

import requests
import gzip
import shutil
from http import HTTPStatus

### Get the URL for physiological timeseries data gzip file 
headers = {'Authorization': str('284e8f3320a8500c58ea5b8e7829bdd676ea941bb573bb250d51c0b82f68e19d'), 'Content-type': 'application/json'}
params = {'start_time': '2019-02-27 00:00:00', 'stop_time': '2019-02-27 23:59:59', 'email': '[email protected]'}
response_with_url = requests.get(f'https://research-api.spire.io/v1/physio_timeseries', params=params, headers=headers)

if response_with_url.status_code == HTTPStatus.OK:
    interval_data_url = response_with_url.json()['url']                        
else:
    print ("Returned status code is: " + str(response_with_url.status_code))
    print (response_with_url.text)
    


### File name to download gzip file
temp_file = "interval_data.gz"
### File name to store CSV file
interval_data_csv = "interval_data.csv"

#### Function to unzip a gzip file
def gunzip_shutil(source_filepath, dest_filepath, block_size=65536):
    with gzip.open(source_filepath, 'rb') as s_file, \
            open(dest_filepath, 'wb') as d_file:
        shutil.copyfileobj(s_file, d_file, block_size)

### Download gzip file containing physiological timeseries data
if response_with_url.status_code == HTTPStatus.OK:
    gzip_file = requests.get(url=interval_data_url, stream=True)
    if gzip_file.status_code == HTTPStatus.OK:
        with open(temp_file, 'wb') as gf:
            for chunk in gzip_file.iter_content(chunk_size=65536):
                gf.write(chunk)
        ### Unzip gzip file to a CSV file that can be used with a Python program
        gunzip_shutil(temp_file,interval_data_csv)
    else:
        print ("Returned status code is: " + str(gzip_file.status_code))
        print (gzip_file.text)

Language
Authorization
Bearer
JWT
URL