This manual is intended to help in accessing and downloading data from the cosinuss° Health Platform using a RESTful API. First, you will have an overview of the data structure and further below the API commands to download the respective data.
Every Gateway creates one data file per day. As soon as the day is over, the respective data file is “closed” and will be no longer modified. The data files have names (hash IDs) like “WSJJU7.HJZ3E3”, where the first part is the serial of the Gateway which created it (here: WSJJU7), the second part (HJZ3E3) just a randomly created key.
For each data file there is meta data that you can download separately. The following meta information is available:
An example for date_time_start would be: “Sat, 27 Jun 2020 20:04:29 GMT” That means the data file was created on the 27th of June 2020 at 8:04 p.m. and 29 seconds in Greenwich Mean Time (GMT). All downloadable x values are given in seconds relative to date_time_start. So if x is for example
x = 70.0 s
then the corresponding time stamp will be at 20:05 p.m. and 39.0 seconds.
There are several data types that can come with a data file like heart rate, battery level, temperature, … The meta information “cols” tells you, which data types are available in each specific data file. See here the complete list of data types with a short description:
x
For all datatypes, x is the time in s, relative to the start of this data file (date_time_start from the meta information).
heart_rate
rr_int
spo2
acc_x
acc_y
acc_z
ppg_green (Only for cosinuss° Three)
ppg_ir
ppg_red
ppg_ambient
battery
temperature
temperature_ct (Only for c-med° alpha)
temp_ir_ambient (Only for c-med° alpha)
perfusion_ir
quality
respiration_rate
ppg_quality
ppg_med
ble_packet_counter
ble_sample_counter
ble_sample_amount
This brief tutorial shows the basic RESTful API requests with a curl example. The return is always JSON. You may use your favorite HTTP/REST library available for your programming language to make HTTP calls to our API.
The BASE-URL is
https://health.cosinuss.com/api/v3/
Note:
Before a specific user account can use the API, an admin user must assign
to the API user account by selecting the user from the overview and then clicking “edit user”. If that is not done then, the API user has no access or might not receive all data.
The login route is simply
BASE-URL/login
Add username and password to the headers. Before the first request you need to login with a valid user account:
curl -H "username: alice" -H "password: Sec7e1Passw0rd" https://health.cosinuss.com/api/v3/login
You will get back a temporary token for authentication (expire time, a few hours):
{ "x_auth_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIudmlld2VyIiwiZXhwIjoxNTkzNDcwODkxfQ.wq_ohjm7aTo225dRdbgvFFO7lmAb2BvceffdAwCI69k" }
For any further request use this token in the header:
curl -H "X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIudmlld2VyIiwiZXhwIjoxNTkzNDcwODkxfQ.wq_ohjm7aTo225dRdbgvFFO7lmAb2BvceffdAwCI69k" https://health.cosinuss.com/api/v3/data_files
You can try all following API routes by simply using the base URL and the given API routes with the command line tool curl or any other library (e.g. requests in Python). The upper line would be
curl -H "X-AUTH-TOKEN: <TOKEN>" BASE-URL/date_files
For most routes the response JSON may either contain the keywords success
for positive outcomes or fail
if something went wrong (e.g. failed authentication or a a file was not found).
{ "status": "success", "message": "", "data": ... }
or
{ "status": "fail", "message": "some error message", "data": {} }
Get a list of all project IDs:
BASE-URL/projects
Get a list of all people IDs:
BASE-URL/people
Get a list of all people IDs of one project:
BASE-URL/people/project/<project id>
Get a list of people's meta data from all projects
BASE-URL/people/meta
Only get the meta data of people from a specific project
BASE-URL/people/meta/project/<project id>
Get the meta data of one specific person
BASE-URL/person/meta/<person id>
person id is the combination of project id and person Pseudonym generated by the server. You need to enter them both as person id like: project_id.person Pseudonym, for example: if A1B2 is project_id and ABCD is the person Pseudonym, then the person_id is: A1B2.ABCD
Example:
{ "data": { "hash_id": "A1B2.ABCD", "label": "patient001", "active": true, "project": "A1B2", "devices": [ "333YC2" ], "time_c": "2021-03-17 13:29:35.434000+01:00", "trigger_recording": null, "continuous_recording": false, "receivers": [ "ABC123" ] } }
Get a list of all data file IDs:
BASE-URL/data_files
Get a list of all data file IDs of one project:
BASE-URL/data_files/project/<project id>
Get a list of all data file IDs of one person:
BASE-URL/data_files/person/<person id>
Get a list of all data file IDs, which have been modified since a specific date and time (time_m in UTC):
BASE-URL/data_files/time_m/<time_m>
please pay attention to the <time_m> required format of <year-month-day> or <year-month-dayThour:minutes:seconds>, otherwise you would get a error message as:
{“error”:“wrong format for time_m (example: 2022-01-11T10:25:40)”}
And use UTC for time_m!
Get meta data of one data file:
BASE-URL/data_file/<data file id>/meta
Example:
BASE-URL/data_file/G1C2B5.UV4M1D/meta Response (formatted): { "data": { "cols": [ "battery", "ble_packet_counter", "ble_sample_amount", "ble_sample_counter", "heart_rate", "perfusion_ir", "ppg_ambient", "ppg_ir", "ppg_quality", "ppg_red", "quality", "respiration_rate", "rr_int", "spo2", "temperature" ], "comments": [], "date_time_end": "Sat, 27 Jun 2020 20:04:29 GMT", "date_time_start": "Fri, 26 Jun 2020 10:17:08 GMT", "device": "X6EE0F", "device_model": "two", "duration": 7412.4355829999995, "hash_id": "G1C2B5.UV4M1D", "person": "0RFM.5JW1", "person_label": "Testperson01", "project": "0RFM", "receiver": "G1C2B5", "status_closed": true } }
Get data for a given 'data type':
BASE-URL/data_file/<data file id>/<data type>/data
The available data types are listed in the meta data of each data file e.g.: 'battery', 'ble_packet_counter', 'ble_sample_amount', 'ble_sample_counter', 'heart_rate', 'perfusion_ir', 'ppg_ambient', 'ppg_ir', 'ppg_quality', 'ppg_red', 'quality', 'respiration_rate', 'rr_int', 'spo2', 'temperature', …
Example:
BASE-URL/data_file/G1C2B5.UV4M1D/heart_rate/data Response (formatted): { "data": { "x": [ 72.02425384521484, 72.85407257080078, 73.8526382446289, ..., 7408.6787109375, 7409.45751953125, 7410.48681640625 ], "y": [ 70.0, 69.0, 68.0, ..., 85.0, 86.0, 86.0 ] } }
The data get recorded in data chunks (default 15 min) and for every single chunk you can get a statistic of the contained data. So you get mean, max, min, median, etc. for each data chunk and data type.
For a known data file hash:
BASE-URL/data_file/<data_file_hash>/chunks
The shorted result will be a string like
BASE-URL/data_file/G1C2B5.UV4M1D/chunks { "data": [ { "battery": { "lower_quartile": 100.0, "max": 100.0, "mean": 100.0, "median": 100.0, "min": 100.0, "samples": 1, "upper_quartile": 100.0 }, "date_time_start": "2020-08-26 11:13:55.902000+02:00", "duration": 142.75, "heart_rate": { "lower_quartile": 52.0, "max": 52.0, "mean": 52.0, "median": 52.0, "min": 52.0, "samples": 1, "upper_quartile": 52.0 }, ..., "temperature": { "lower_quartile": 35.5, "max": 35.7, "mean": 35.55, "median": 35.6, "min": 35.4, "samples": 174, "upper_quartile": 35.6 }, "time_offset": 1092.808687 }, { "battery": { "lower_quartile": null, "max": null, "mean": null, "median": null, "min": null, "samples": 0, "upper_quartile": null }, "date_time_start": "2020-08-26 11:19:04.565000+02:00", "duration": 147.0, "heart_rate": { "lower_quartile": null, "max": null, "mean": null, "median": null, "min": null, "samples": 0, "upper_quartile": null }, ... }, ... ] }
This route is similar to Get Data Chunk Statistic but with this request you get kind of aggregated data, one data point per chunk and data type. For spo2 it's the max, for perfusion_ir it's the min and for all other data types it's the median.
For a known data file hash:
BASE-URL/data_file/<data_file_hash>/data_by_chunk
The result will be a string like
BASE-URL/data_file/G1C2B5.UV4M1D/data_by_chunk { "data": { "date_time_start": [ "2020-08-26 11:13:55.902000+02:00", "2020-08-26 11:19:04.565000+02:00", ... "2020-08-26 23:38:25.300000+02:00", "2020-08-26 23:41:51.694000+02:00" ], "heart_rate": [ 52.0, null, ... 55.0, 55.0 ], "perfusion_ir": [ 0.26, 0.13, ... 0.55, null ], "ppg_quality": [ null, null, ... 37.0, null ], "quality": [ 50.0, null, ... 27.0, 19.0 ], "respiration_rate": [ null, null, ... null, null ], "rr_int": [ null, null, ... 445.0, 1330.0 ], "spo2": [ 92.0, 94.0, ... 69.0, null ], "temperature": [ 35.6, 36.0, ... 37.0, 36.95 ], "time_offset": [ 1092.808687, 1401.471482, ... 45762.206182, 45968.60086 ], "duration": [ 142.75, 142.0, ... 142.2, 142.15 ] } }
You can get the parameters which are displayed on the Dash view of the cosinuss° Health Platform either for a single person or for all persons in a project. In the default setting of the Gateway, these values do not represent a single measurement point but either the minimum, maximum or median of all values that were recorded during the last recording cycle. If the receiver is set to send live data points (feature on request), the data will be the last recorded data point. The data is only available for 6 hours after it has been recorded and can then no longer be downloaded using this API call.
The following abbreviations are used in the results JSON string and the square brackets indicate the calculation method based on the corresponding recording cycle.
For a specific person (any device):
BASE-URL/vitals/person/<person id>
The result will be a string like
{ "data": { "bat": 17, "bat_time": 1645020003.586026, "hr": 74, "hr_time": 1645020010.2649384, "person_label": null, "pi": 0.13, "pi_time": 1645020008.7545307, "q": 28, "q_time": 1645020010.271199, "rr": 30.0, "rr_time": 1645019978.5482578, "seconds": 1645020011.2, "spo2": 95, "spo2_time": 1645020008.7074695, "temp": 35.62, "temp_time": 1645020003.9922724 } }
If there is no data for this person or if the last data for this person was received more than 6 hours ago, then the result will be empty.
{ "data": {} }
For a specific person and specific device:
BASE-URL/vitals/person/<person id>/<device_id>
For all persons in one project:
BASE-URL/vitals/project/<project id>
In this case the data of each person (here K4EXT1E4QP.17MV.251Z and K4EXT1E4QP.17MV.4URG) is listed under results. If the data of a person is older than 6 hours or not available, that person's data will be empty:
{ "data": { "0RFM.6UAX": {}, "0RFM.81LJ": { "bat": 17, "bat_time": 1645020003.586026, "hr": 74, "hr_time": 1645020010.2649384, "person_label": null, "pi": 0.13, "pi_time": 1645020008.7545307, "q": 28, "q_time": 1645020010.271199, "rr": 30.0, "rr_time": 1645019978.5482578, "seconds": 1645020011.2, "spo2": 95, "spo2_time": 1645020008.7074695, "temp": 35.62, "temp_time": 1645020003.9922724 }, "0RFM.AK13K": {}, } }
If you have created Person Events you can get them with the following URLs for either all persons, all persons in a project or for a specific person:
For all persons
BASE-URL/person_events
For all persons in a project
BASE-URL/person_events/project/<project id>
For a single person
BASE-URL/person_events/person/<person id>
The result will be a string like
{ "data": [ { "label": "Running", "person": "QNEV69NM1R.QGB0.8HRL", "project": "QNEV69NM1R.QGB0", "time": "2021-03-17 13:29:35.434000+01:00" }, { "label": "Walking", "person": "QNEV69NM1R.QGB0.8HRL", "project": "QNEV69NM1R.QGB0", "time": "2021-03-17 13:29:37.655000+01:00" }, { "label": "Sleeping", "person": "QNEV69NM1R.QGB0.8HRL", "project": "QNEV69NM1R.QGB0", "time": "2021-03-17 13:29:40.813000+01:00" } ] }
If there are no Person Events found, the result will be empty.
You can download any submitted Observation Events using the following URLs for either all persons, all persons in a project or for a specific person:
For all persons
BASE-URL/observations
For all persons in a project
BASE-URL/observations/project/<project id>
For a single person
BASE-URL/observations/person/<person id>
The result will be a string like
{ "data":[ { "comment":"spo2 value test", "data_type":"Spo2", "data_unit":"%", "data_value_1":95.0, "data_value_2":null, "device":"Finger clip", "person":"A7JR15WK56.JB50.1K04", "project":"A7JR15WK56.JB50", "time_created":"2021-09-28 14:31:12.758000+02:00", "time_recorded":"2021-09-28 08:30:52" }, { "comment":"BP test", "data_type":"systolic BP, diastolic BP", "data_unit":"mmHg", "data_value_1":120.0, "data_value_2":80.0, "device":"Blood pressure monitor", "person":"A7JR15WK56.JB50.1K04", "project":"A7JR15WK56.JB50", "time_created":"2021-09-28 14:33:50.577000+02:00", "time_recorded":"2021-09-23 08:31:47" } ] }
If no Observation is submitted, the result will be empty.
You can trigger a new recording for a specific person with a specified duration in seconds. The record will start the next time the Gateway is in contact with the server, which is by default once every 3 minutes.
BASE-URL/trigger_record/<person id>/<seconds>
The result will be a string like
{ "data": "trigger record 120 seconds of receiver "WSJJU7" from person "L6EH.EZ6Q"" }
This APIs have to be activated by cosinuss°.
You can add a new person to a project.
BASE-URL/person/new/<project_id>
The result will be the created person id
{ "data": { "person_id": "A1B2.ABCD" } }
You can edit the following attributes of a person:
active
: true/false (boolean)continuous_recording
: true/false (boolean)BASE-URL/person/edit
The json-data of the following POST-request
should follow this structure:
{ "person_id": "A1B2.ABCD", "active": false, "continuous_recording": false }
You can relate a device or receiver to a person.
BASE-URL/person/<person id>/relate/<serial>
You can release a device or receiver from a person.
BASE-URL/person/<person id>/release/<serial>
You can pull the current ppg-med data of the last 10 seconds.
BASE-URL/ppg_med/<person id>/<serial>
The result will look like this if ppg-med data available
{ "data": { "ppg_data": [[0.0, 0.4146428], [0.025, 0.39928573], [0.05, 0.36857146], [0.075, 0.33785713], [0.1, 0.30714285], ...] "min": -0.5912499999999999, "max": 0.7095, "time": "1694598676.7803364" } }
The result will look like this if no ppg-med data available
{ "data": { "ppg_data": [[0, 0]] "min": 0, "max": 0, "time": 0 } }
The result attributes will follow this structure:
ppg_data
: Array of datapoints (float) [[x1, y1], [x2, y2], ...]
min
: minimum used for plotting (float)max
: maximum used for plotting (float)time
: timestamp when data processed (integer or string)You may also be interested to download the Python example scripts and work with them in order to get an impression how the API works.
API Help: Python Guidelines helps you step by step on how to use python to work with API and learn more about its work flow.
You can fill in your user data and the script will download all available files and store it as .csv.