Byteflies Cloud API

CE mark

The Byteflies Cloud API is developed using a serverless infrastructure and documented using an OpenAPI 3.0 specification. This API is optimized for the purpose of retrieving health data in a structured and readable format.

Table of contents
  1. Overview
    1. Recording
    2. Docking Station
  2. Getting Started
    1. Breaking down a curl HTTP request
    2. Breaking down a JSON Response
    3. Byteflies Cloud RESTful API
    4. Authentication
      1. Retrieving an Authentication Token IdToken
      2. Making requests to the API Endpoints
      3. Token Expiration
  3. Exploring the API Endpoints
    1. The /groups Endpoint
    2. The /groups/{groupId}/recordings Endpoint
    3. The /groups/{groupId}/recordings/{recordingId} Endpoint
    4. Available Signals in a Recording
      1. Units of measurement
    5. The /groups/{groupId}/recordings/{recordingId}/algorithms/{algorithmId} Endpoint
    6. The /docks/{dockName}/config Endpoint

Overview

The Byteflies Cloud gathers sample-level Recordings from Sensor Dots via the Docking Station, which are associated with a User Account. It is an integral part of the Byteflies Kit (Model 1)**. Its instructions are discussed in a separate section for readability reasons but one cannot be used without the other. If you have not already done so, please review the IFU for the Byteflies Kit first which focuses on the hardware components of the system. All legal & regulatory information are linked in that document.

Signal
A physiologic or motion signal, as recorded by a Sensor Dot (e.g. ECG).
Channel
A Sensor Dot can record two biopotential Signals simultaneously and has two pairs of electrode connectors that each form a Channel.
Recording
The combination of all data recorded by a single Sensor Dot is grouped in a Recording.
Group
A Group combines one or more Docking Stations that are assigned to a specific study.
Patient ID
A unique string used to identify a study subject.
Patient Record
A list of pre-configured Patient IDs and the hardware they are associated with.
User Account
A Byteflies Cloud account that can contain one or more Groups and can only be accessed with a specific username and password.

Recording

Whenever a Sensor Dot is configured to start a Recording, the device initializes its sensors to start gathering data on all specified channels. At this specific point in time, the Sensor Dot captures the Recording timestamp, also known as startDate. The specifics of a Recording are discussed further.

Docking Station

The Docking Station can be thought as a relay of Recordings to the Byteflies Cloud. It reads a Recording from the Sensor Dot’s memory, and uploads it once it is online. It’s also used to calibrate and configure the Sensor Dot, and charge its batteries.

The Calibration function is only available to admin User Accounts.

Do not use the Calibration function without explicit instructions from Byteflies to do so. When in doubt, contact us.

Getting Started

In this manual, we introduce curl commands for interacting with the API. To execute curl commands, the MacOS terminal, Linux console, or Windows Command Prompt can be used. This software enables a User Account to send HTTP requests or data to web servers using HTTP methods, like GET or POST.

Breaking down a curl HTTP request

curl -X GET \
  -H 'Authorization: <id token>' \
  https://api.cloud.byteflies.net/{endpoint}

-X specifies the HTTP Request method to use when sending, in this case it is the GET HTTP method.

-H specifies an HTTP Request header to be used when sending the request, in this case it is a header named Authorization. More information can be found on curl’s official documentation.

The last parameter is the URL endpoint where the HTTP request will be sent, in this case https://api.cloud.byteflies.net/{endpoint}.

Breaking down a JSON Response

{
    "AuthenticationResult": {
        "AccessToken": "eyJ..",
        "ExpiresIn": 3600,
        "IdToken": "eyJ..",
        "RefreshToken": "eyJ...",
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {}
}

This response specifies a JSON object that contains the following name/value pairs:

  • AuthenticationResult
  • ChallengeParameters

Within the AuthenticationResult the following name/value pairs appear:

  • AccessToken
  • ExpiresIn
  • IdToken
  • RefreshToken
  • TokenType

A name/value pair is separated by a colon :, where the name is to the left of the colon and the value to the right. A more in-depth explanation can be found here.

Byteflies Cloud RESTful API

The sandbox API is available at the following URI:

https://api.cloud.byteflies.net

and currently has the following endpoints:

HTTP Method Endpoint Description
GET /groups Retrieve all Groups connected to your account
GET /groups/{groupId}/recordings Returns all Recordings of a specific Group
GET /groups/{groupId}/recordings/{recordingId} Retrieve the Recording details
GET /groups/{groupId}/recordings/{recordingId}/algorithms/{algorithmId} Retrieve algorithm details
PUT /docks/{dockName}/config Switch a Docking Station to configuration mode

Authentication

The access to the API is secured by authentication tokens generated by Amazon Cognito. This means that when someone makes a request without an authentication token, our API will refuse the request with a 403 Forbidden response. Valid requests can be sent to the API using these tokens on the HTTP Header Authentication, ensuring the restricted access to the resources on the Byteflies Cloud.

Retrieving an Authentication Token IdToken

In order to retrieve an authentication token, specifically the IdToken, the User Account has to log in the API with a username and password. You should have received a username and password from Byteflies to access your account. If you did not, contact us.

Byteflies Cloud accounts are only available for Trained Operators!

For demonstration purposes we have created a demo account with the following credentials:

username: demo@byteflies.com
password: 16yV&dXP

To login into our API, the following curl command can be executed:

curl -X POST \
  --data '{
    "ClientId": "5kgqk7n83evq9cbqnam1biqnbr",
    "AuthFlow": "USER_PASSWORD_AUTH",
    "AuthParameters": {"USERNAME": "demo@byteflies.com", "PASSWORD": "16yV&dXP"}}' \
  -H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
  -H 'Content-Type: application/x-amz-json-1.1' \
   https://cognito-idp.eu-west-1.amazonaws.com

The curl command sends a POST request to the https://cognito-idp.eu-west-1.amazonaws.com endpoint. This endpoint is part of the Amazon Cognito service from AWS, which handles the authentication of Byteflies Cloud users. To authenticate a User Account, the endpoint requires some parameters to be sent on the POST request data. Such parameters can be seen in the --data section of the request.

Noteworthy, on this line:

"AuthParameters": {"USERNAME": "demo@byteflies.com", "PASSWORD": "16yV&dXP"}}' \

The login credentials are included. To login as a different user, the USERNAME and PASSWORD fields need to be changed accordingly. To login to the environment, the ClientId field needs to be set to 5kgqk7n83evq9cbqnam1biqnbr.

As a response, this command gets the following JSON Response:

{
    "AuthenticationResult": {
        "AccessToken": "eyJ..",
        "ExpiresIn": 3600,
        "IdToken": "eyJ..",
        "RefreshToken": "eyJ...",
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {}
}

This response includes the parameter "IdToken": "eyJ..",, this value is required to make further requests to the API.

Making requests to the API Endpoints

Once the IdToken parameter is retrieved using the authentication steps above, the User Account can start making HTTP requests to the API endpoints.

For example, to request the list of Docking Stations associated with a User Account, the following command can be executed replacing <id token> with the value eyJ... retrieved in the "IdToken": "eyJ..", parameter from the previous response:

curl -X GET \
  -H 'Authorization: <id token>' \
  https://api.cloud.byteflies.net/groups/

This command sends a HTTP GET request to the https://api.cloud.byteflies.net/groups/ endpoint, which returns the list of Docking Stations associated with the User Account.

Token Expiration

Authentication Tokens are valid for the amount of time specified in the JSON response when authenticating. For instance, if the authentication responded with the following JSON response:

{
    "AuthenticationResult": {
        "AccessToken": "eyJ..",
        "ExpiresIn": 3600,
        "IdToken": "eyJ..",
        "RefreshToken": "eyJ...",
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {}
}

The response includes the "ExpiresIn": 3600 name/value pair. The value 3600 specifies the amount of time in seconds that the authentication tokens are valid from the time of authentication. If the tokens have expired, the API will respond with:

{
    "message": "The incoming token has expired"
}

If that is the case, re-authenticating and retrieving a new token will be necessary.

Exploring the API Endpoints

The /groups Endpoint

The list of Groups associated with a User Account

When sending a GET request to the /groups endpoint:

curl -X GET \
  https://api.cloud.byteflies.net/groups/ \
  -H 'Authorization: <id token>'

The endpoint responds with a JSON response:

[
    {
        "id": "1234",
        "name": "TestGroup",
        "description": "Description of group"
    }
]

This response includes a list of JSON Objects that include the Group associated with your User Account. In this particular response, there is only one Group named TestGroup associated with the User Account.

The /groups/{groupId}/recordings Endpoint

The list of Recordings associated to a Group

When sending a GET request to the /groups/{groupId}/recordings endpoint, the path parameter groupId needs to be swapped with the ID of a Group. Using the Group ID retrieved above with the /groups endpoint, the following command can be executed:

curl -X GET \
  -H 'Authorization: <id token>' \
  https://api.cloud.byteflies.net/groups/1234/recordings

The endpoint will respond with a list of recordings, for example:

[
    {
        "id": "33d8951c-999f-11e9-a2a3-2a2ae2dbcce4",
        "dotId": "24deb6f2e360",
        "dockName": "Dock-1234",
        "patient": "patient-ID",
        "signals": [
            {
                "id": "995f3a71-71c2-11eb-9f2c-be58546669d4",
                "type":"EEG",
                "quality":"FAIL",
                "channel": 2,
                "rawData": "https://..."
            },
            {
                "id": "995e4cb7-71c2-11eb-9f2c-be58546669d4",
                "type":"ACC",
                "rawData": "https://..."
            }
        ],
        "startDate": 1526919822.1422584,
        "endDate": 1526919921.5267422,
        "uploadDate": 1526939822.453,
        "duration": 99.384483839,
        "status": "done"
    }
]

This response includes a list of one Recording with the following values:

Name Description
id A unique identifier of the Recording
dotId A unique identifier of the Sensor Dot that performed the Recording
dockName A unique identifier of the Docking Station that was used to upload the Recording
patient A patient identifier
signals A list of Signal objects available in the Recording
signals.type The type of Signal
signals.quality The quality of the Signal. Can be PASS, CHECK or FAIL*
signals.channel The Channel number as described in the Byteflies Kit IFU
signals.rawData A link to download the data
startDate A UNIX timestamp in (fractional) seconds indicating the start of the Recording
endDate A UNIX timestamp in (fractional) seconds indicating the end of the Recording
uploadDate A UNIX timestamp in (fractional) seconds indicating the time of data upload
duration Total duration of a Recording in (fractional) seconds
status Indicates if the Byteflies Cloud is ready with generating the Insights

*Refer to the Clinical Insights section for more information.

The /groups/{groupId}/recordings/{recordingId} Endpoint

The details of a particular Recording

When sending a GET request to the /groups/{groupId}/recordings/{recordingId}, the path parameter {recordingId} needs to be swapped with the id of a Recording. The parameter {groupId} needs to be swapped with the id of the group in which this Recording was uploaded. Taking the recordingId 33d8951c-999f-11e9-a2a3-2a2ae2dbcce4 of the previous endpoint, the following command can be executed:

curl -X GET \
  -H 'Authorization: <id token>' \
  https://api.cloud.byteflies.net/groups/1234/recordings/33d8951c-999f-11e9-a2a3-2a2ae2dbcce4

The endpoint sends back a JSON response:

{
    "id": "33d8951c-999f-11e9-a2a3-2a2ae2dbcce4",
    "dockName": "Dock-8e6bde5ac7e7191caaf7e3c9",
    "dotId": "24deb6f2e360",
    "patient": "patient-ID",
    "groupid": "16bc09e1-4107-11ea-959c-ad5917d09f85",
    "startDate": 1526919822.1422584,
    "endDate": 1526957192.6380,
    "uploadDate": 1526939822.453,
    "duration": 37370.4958
    "firmwareVersion": "1.22.0",
    "signals": [...]
}

This response includes the following:

Name Description
id A unique identifier of the Recording
dotId A unique identifier of the Sensor Dot that performed the Recording
dockName A unique identifier of the Docking Station that was used to upload the Recording
patient A patient identifier
signals A list of Signal objects available in the Recording
startDate A UNIX timestamp in (fractional) seconds indicating the start of the Recording
endDate A UNIX timestamp in (fractional) seconds indicating the end of the Recording
uploadDate A UNIX timestamp in (fractional) seconds indicating the time of data upload
duration Total duration of a Recording in (fractional) seconds
firmwareVersion The version of the firmware that was on the Sensor Dot at the time of the Recording

The specifics of signals will be explained in detail in the next section.

Update the patient identifier

You can associate a Patient Identifier with your recording with this endpoint. To do so, make a PUTrequest to the /groups/{groupId}/recordings/{recordingId} endpoint.

The payload of the body should look like this :

{
    "patient": "Patient Identifier"
}

Rerun algorithms for all signals in a recording

You can rerun algorithms for all Signals in a specific Recording. This might be useful in case a new version of the algorithm was deployed or if for some reason, the algorithm was never triggered. You cannot choose which algorithm to run, this is linked to the Signal type. To (re)run the algorithms, make a PUT request to the /groups/{groupId}/recordings/{recordingId} endpoint.

The payload of the body should look like this :


{
    "triggerAlgorithms": true
}

Available Signals in a Recording

For each Recording, a list of signals is included in the response:

{
    ...
    "signals": [
      {
            "id": "d030cb6b-71c4-11eb-a965-9efcfcdd45da",
            "type": "ACC",
            "rawData": "https://...",
            "samplingRate": "25",
            "conversionFactor":0.000244140625
        },
        {
            "id": "d030cb6b-71c4-11eb-a965-9efcfcdd45da",
            "type": "EEG",
            "channel": 1,
            "quality": "CHECK",
            "rawData": "https://...",
            "samplingRate": "250",
            "conversionFactor":0.4808108585052719,
            "algorithms":[
                {
                    "type":"EEG_ARTFCTS",
                    "id":"09cdf800-7268-11ea-a8d6-a7682dc8f48c",
                    "added": 1613637847
                }
            ]
        },
        {
            "id": "d035f333-71c4-11eb-a965-9efcfcdd45da",
            "type": "ECG",
            "quality": "CHECK",
            "channel": 2,
            "rawData": "https://...",
            "samplingRate": "250",
            "conversionFactor":1.4424325755158156
        },
        {
            "id": "d036c3fd-71c4-11eb-a965-9efcfcdd45da",
            "type": "GYR",
            "rawData": "https://...",
            "samplingRate": "200",
            "conversionFactor":0.030517578125
        }
    ]
}

This signals list includes an entry for each of the Signals available in a Recording. In this particular example, there is an ACC, EEG, ECG, and a GYR signal available.

The response includes the following information:

Name Description
type The type of Signal
id A unique identifier of the Signal or Algorithm
channel The Channel number as described in the Byteflies Kit IFU
rawData A URL for the sample-level (raw) data
samplingRate The number of samples per second for the Signal
algorithms a list of available algorithm outputs containing the type of algorithm, the algorithmId and a UNIX timestamp when it was added
quality The quality of the Signal. Can be PASS, CHECK or FAIL*
conversionFactor a value to convert the sample-level data to physical units through multiplication

With this information, we know that the recording 33d8951c-999f-11e9-a2a3-2a2ae2dbcce4 has sample-level data in CSV format of Signal type ACC, which can be downloaded using the URL available in rawData. For example using the wget command:

wget \
-O 33d8951c-999f-11e9-a2a3-2a2ae2dbcce4.csv \
'https://bc-iot-platform-parseduploadsbucket-khbvk362f8kf.s3.eu-west-1.amazonaws.com/2018/05/21/33d8951c-999f-11e9-a2a3-2a2ae2dbcce4/719a0254-99a1-11e9-a2a3-2a2ae2dbcce4?AWSAccessKeyId=ASIA4GCJNCPO6RIVNIRY&Expires=1567770981&Signature=PwbiPzjeziQ9DGUQaGG504Kwoi0%3D&x-amz-security-token=AgoJb3JpZ2luX2VjEKT%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCWV1LXdlc3QtMSJIMEYCIQCgUhSo3YP6MaUsdHvKJwLAzNiHQvOVwsWJ1ngWlE9XrQIhAOz1Ja%2FcthQA7Wfc0Wnqx0XLfv%2FSbQtyynKMdlmsclXdKq4CCF0QABoMODM3NjcyNTcxODY5IgyWMiRcTX04GhdA4HIqiwKA4d2yKrQrzA2%2F4Sw%2FnevDMsXL1%2FCmzvszLpCha7pctguogMZ5RgMGtI8yc6jFAG900halbX8dtqwVI6Jfa3chE17pwJgAEQ%2BJ%2F%2BAkapORxcJ5sdxHY3cTzZo4KNezwbWEYpyUa5GlTbRLmqQNaarbKNqol1AA%2BtD3%2BbwUdNBUMeq5Ph16D4bZvC23a52bb4S8iSFUUdFvxfFng4jouPpssbnIIJixxzXNmQvNMLhEz9zVPTpuvqBe8VMGd22BeT%2F4kin9YyLqrU3d8lEemW8jY9EtX5CKe3hO3l6Wg079DGyMkIhg1nN22LEbDK0zp68Y8ANMUaUdoC6up02o%2FNbHGfDJmuEqDqPn02Awio7J6wU6swET3qHT342B1zNlp0kDKySNJch4iAADF1TzEVSZCzhC3p6RCMrPP8eLjaeUMECwxqSgfNeXVxXqqwK4UvNiof1%2F7QcX3a%2BWlSSJZbzbPsy0fppjMP1lB6GfBCv7qlROWhwN59NzRc7v7n2foFjGzRPh90pUmraGHPXWuaFUrzo2LqurLitNrSdcz1kdGtwNTvuW%2FcvOz4mCGKTbVKYghmUCaEY1YnUTzrIGzg0aJLiXFjgRmg%3D%3D'

This will download the file using the name 33d8951c-999f-11e9-a2a3-2a2ae2dbcce4.csv. Please note that this URL includes temporary credentials for downloading, which are only valid for 10 minutes.

Sample-level data (i.e. raw waveform data) for each Signal that is available for a Recording can be downloaded in Comma-Separated Value (CSV) format. Clinical Insights derived from sample-level data can also be downloaded as CSV files, as specified in the Clinical Insights documentation..

Units of measurement

The units of measurements depend on the signal type.

Type SI Unit Description
ExG nV nanovolt
ACC g g-force
GYR °/s degrees per second
BAT % % of total battery capacity

The /groups/{groupId}/recordings/{recordingId}/algorithms/{algorithmId} Endpoint

The details of a particular Algorithm

When sending a GET request to the /groups/{groupId}/recordings/{recordingId}/algorithms/{algorithmId}, the path parameter {recordingId} needs to be swapped with the id of a recording. The parameter {groupId} needs to be swapped with the id of the group in which this recording was uploaded. The parameter {algorithmId} needs to be swapped with the id of the algorithm.

Taking the recordingId 33d8951c-999f-11e9-a2a3-2a2ae2dbcce4 of the previous endpoint, and the algorithmId 09cdf800-7268-11ea-a8d6-a7682dc8f48c the following command can be executed:

curl -X GET \
  -H 'Authorization: <id token>' \
  https://api.cloud.byteflies.net/groups/1234/recordings/33d8951c-999f-11e9-a2a3-2a2ae2dbcce4/algorithms/09cdf800-7268-11ea-a8d6-a7682dc8f48c

This will download the file using the name 09cdf800-7268-11ea-a8d6-a7682dc8f48c-EEG_ARTFCTS.csv. Please note that this URL includes temporary credentials for downloading, which are only valid for 10 minutes.

The /docks/{dockName}/config Endpoint

You can set a Docking Station in one of your groups to CONFIGURATION or NORMAL mode. To do so, make a PUT request to the /docks/{dockName}/config endpoint.

The payload of the body should look like this to enter CONFIGURATION mode:

{
    "mode": "configuration",
    "configSignals": [
        {"type": "ECG", "fs": 250, "channel": 1},
        {"type": "EEG", "fs": 250, "channel": 2},
        {"type": "ACC", "fs": 25},
        {"type": "GYR", "fs": 25},
    ]
}
  • In case you do not want to measure a certain Signal, simple omit it.
  • Allowed signal types are: EEG, ECG, EOG, EMG, ACC, or GYR.
  • For any biopotential (ExG) Signal, you should define a Channel number (1 or 2) and the sampling frequency should be 250 Hz.
  • For ACC or GYR Signals, no Channel needs to be specified and the sampling frequency can be 25, 50, 100 or 200 Hz.

Follow the next steps in order to configure Sensor Dots:

  1. Indicate the Signal type and sampling frequency for Channel 1 and 2.
  2. Add the ACC and GYR Signals as desired and select the sample rate (25, 50, 100, or 200 Hz).
  3. Make sure all Sensor Dot(s) you wish to (re)configure are on the Docking Station.
  4. Enable the Configuration Mode of the Docking Station, indicated by a purple status LED on the back of the Docking Station.
  5. The status LED of the docked Sensor Dot(s) will blink green rapidly to indicate the new configuration has been set.
  6. Revert the Docking Stationback to normal interface to exit Configuration Mode. The Sensor Dot LEDs should turn solid green, or blinking green if the battery is still charging.
  7. Repeat this process if you need to send different configurations to other Sensor Dots (only one configuration can be send per configuration cycle).

To revert the Docking Station to NORMAL mode, set the payload as follows:

{
    "mode : "normal"
}


If, after attempting a configuration, a Sensor Dot’s LED is Red when taking it out of the Docking Station, the configuration may not have been correctly stored. Please try again. If that does not solve the issue, contact us.


Copyright © 2020 Byteflies