Rune Labs Stream API

The Stream API is an HTTP API that allows clients to query data streams for a given patient.

It exposes endpoints for every type of data stream that can be queried (e.g. local field potentials, accelerometry, events, etc). Each endpoint is documented in detail, below.

Overview

Key Concepts

Throughout this document, the following terminology is used:

  • Patient refers to the user of a patient-facing app.
  • Client refers to the patient-facing app itself. A client accesses data programmatically, on behalf of a patient.
  • Device refers to the sensor serving as the datasource, such as a patient implant, phone, or wearable.

A client is associated with exactly one patient. Patients may have multiple clients, depending on how many apps are sending or accessing data. Patients and clients are resources in the Rune platform with unique identifiers, and they are used to control access to patient data.

Authentication

Authentication is required for all API requests. There are several authentication methods, which are described in detail below.

Access Tokens

An access token provides read access to all the patients in your organization.

To use an access token for authentication, the HTTP request must include two headers:

  • X-Rune-User-Access-Token-Id - access token ID
  • X-Rune-User-Access-Token-Secret - access token secret

It is highly recommended that you "rotate" your user access token every 3-6 months, by creating a new token and deactivating the old one.

Create a New Access Token

  1. Log in to the Rune web app
  2. Click on the profile icon in the top right corner.
  3. Click on User Settings.
  4. On the left sidebar, click on Access Tokens.
  5. Click CREATE ACCESS TOKEN.
  6. Copy the token ID and the token secret before closing the page. The secret will never be shown again.

Keep your access token secure and do not share.

Client Keys

Client keys provide read and write access to one patient.

In order to access the Rune API, clients use a client key pair, which is comprised of a key ID and an access key. These are analagous to a username and password for the client.

To use a client key pair for authentication, the HTTP request must include two headers:

  • X-Rune-Client-Key-Id - client key ID
  • X-Rune-Client-Access-Key - client access key (secret)

Note that each client may only fetch data for its associated patient.

Register a New Client

  1. Log in to the Rune web app as an admin user.
  2. Find the patient you want to access data for, and open Patient Settings.
  3. Open the Clients section.
  4. Create a new client. You can name it anything, though typically it is named after your app.
  5. A default client key pair will be created with the new client. Copy the key ID and the access key before closing the page. The access key will never be shown again.

Create New Client Keys

You can create any number of client keys for a given client, through the Rune web app. If you forget a key, you can always create a new key pair and disable the old.

It is highly recommended that you "rotate" keys for a patient every 3-6 months, by creating a new client key, configuring it in the client (e.g. the patient's app), then disabling the old key. You should do this immediately if you believe the key may have been compromised (e.g. stolen from the device, posted over any insecure/public communication channel, etc).

Response Format

Endpoint URLs ending in .json return JSON-formatted data. All resources support this data format. Endpoint URLs ending in .csv return CSV data. Some resources support this data format.

Errors

Standard HTTP status codes are used to indicate success or failure. In the event of most errors, the response body is JSON that includes additional information, with the following format:

{
  "success": false,
  "error": {
    "message": "Human-readable error description",
    "type": "EnumeratedErrorKind"
  }
}

Pagination

Both CSV and JSON endpoints return paginated data: each request will return a maximum number of points. If the queried time range contains more than one page’s worth of points, you must make multiple requests to fetch the complete result.

Two standard query parameters are involved:

  • page_size is the maximum number of points to return in a single request.
  • page indicates the page of data to return (i.e. the offset). By default, a request returns the first page of data, which is equivalent to page=0.

To request the next page of data for a paginated result, increment the page, keeping the rest of your parameters identical.

JSON Endpoints

If a JSON result is paginated, the response body will contain a next_page field to indicate the next page of the dataset. This field is not included in the response if there are no more pages of data.

{
    "success": true,
    "next_page": 1,
    "result": {
        "cardinality": 10000,
        ...
    }
}

To request the next page of data, simply include the value of next_page as the page query parameter in your request. Keep the rest of the query parameters identical.

The default and maximum page size is 10,000 points.

CSV Endpoints

To fetch a complete CSV query result, make multiple requests, incrementing the page query parameter each time (starting with page=0). When the result has been exhausted, the response body will be empty.

The default and maximum page size for CSV endpoints is 3,600,000 points. Clients should be careful about managing their memory usage when they request CSV data, as the responses may contain a large volume of data.

Next Page Token

If a response contains a X-Rune-Next-Page-Token header field, its value can be provided in a subsequent request within the next_page_token query string parameter to obtain the next page of data. Once the end of pagination has been reached, no X-Rune-Next-Page-Token header field will exist in the response. Endpoints that support the X-Rune-Next-Page-Token header will indicate so in their documentation.

Acceleration

Query accelerometry data for any device that records it. Acceleration values are always in units of Gs (9.8 m/s^2).

Acceleration (JSON)

A successful request returns a JSON object, with a result key containing timeseries data. The format of the result depends on several query parameters:

  • expression determines the structure of the result object.
  • timestamp determines the format of the timestamps.
  • partition_size segments each array into sub-arrays.

See details for each query parameter, as well as the response examples.

query Parameters
patient_id
required
string

Patient ID. If authenticating with a client key pair, this parameter may be omitted: the patient is inferred from the key pair.

device_id
required
string

ID of the device from which data was reported.

start_time
required
float

Unix timestamp with the start of the time range to query. This is inclusive: all returned timestamps will be >= start_time.

end_time
required
float

Unix timestamp with the end of the time range to query. This is exclusive: all returned timestamps will be < end_time.

expression
string
Default: "accel"
Enum: "accel" "user" "gravity" "availability(accel)"

Determines what kind of accelerometry data is returned.

  • accel - return the net acceleration. This may or may not include gravity, depending on the device type.
  • user - return just the user acceleration, i.e. acceleration of device without gravitational component. Not available for all device types.
  • gravity - return just acceleration due to gravity. Not available for all device types.
  • availability(accel) - return the availability of acceleration data: 1 if available, 0 otherwise. Defaults to 5min resolution, unless resolution or frequency are specified.
frequency
float

The time frequency (in Hz) of the returned timeseries. This is the reciprocal of the resolution parameter. At most one of frequency or resolution may be provided.

resolution
float

Time interval between returned points, in seconds. This is the reciprocal of the frequency parameter. At most one of frequency or resolution may be provided.

interpolation
string
Default: ""
Enum: "" "linear" null "previous" "zero"

How to fill in timestamps with no data, when frequency or resolution has been specified.

  • If this parameter is omitted or an empty string, timestamps with no data are skipped.
  • If linear, missing values are interpolated with a linear function connecting the last known value and the next.
  • If null, missing values are null.
  • If previous, missing values are filled in by repeating the last known value, until there is data again.
  • If zero, missing values are replaced with 0.0.
timestamp
string
Default: "unix"
Enum: "unix" "datetime" "iso"

Timestamp format.

timezone
integer
Default: 0

The timezone offset, in seconds, used to calculate string-based timestamp formats such as datetime and iso. For example, PST (UTC-0800) is represented as -28800. If omitted, the timezone is UTC.

page
integer >= 0
Default: 0

The page number, to be used if the query result exceeds the pagination limit. Numbering starts at 0 (i.e. page=0 returns the first page of the response).

next_page_token
string <byte>

A token provided in the request to obtain the subsequent set of records in a dataset. When providing this parameter, the page parameter must not be set. This token is obtained from the 'X-Rune-Next-Page-Token' response header field.

page_size
integer [ 0 .. 10000 ]
Default: 10000

Maximum number of events to return per page. If page_size=0, the default will be used.

partition_size
integer

If set, break up result data for each stream into subsets of partition_size number of points. The last partition returned may not necessarily contain partition_size points.

Responses

200

Successful request

400

Bad request

401

Not authorized to perform the request

404

Not found

429

Client IP throttled

500

Internal server error

503

Service unavailable

get /v1/accel.json
https://stream.runelabs.io/v1/accel.json

Response samples

Content type
application/json
Example
Copy
Expand all Collapse all
{
  • "success": true,
  • "result":
    {
    }
}

Acceleration (CSV)

A successful request returns CSV data. The format depends on several query parameters:

  • expression determines the columns of data that are returned.
  • timestamp determines the format of the timestamps.

See details for each query parameter, as well as the response examples.

query Parameters
patient_id
required
string

Patient ID. If authenticating with a client key pair, this parameter may be omitted: the patient is inferred from the key pair.

device_id
required
string

ID of the device from which data was reported.

start_time
required
float

Unix timestamp with the start of the time range to query. This is inclusive: all returned timestamps will be >= start_time.

end_time
required
float

Unix timestamp with the end of the time range to query. This is exclusive: all returned timestamps will be < end_time.

expression
string
Default: "accel"
Enum: "accel" "user" "gravity" "availability(accel)"

Determines what kind of accelerometry data is returned.

  • accel - return the net acceleration. This may or may not include gravity, depending on the device type.
  • user - return just the user acceleration, i.e. acceleration of device without gravitational component. Not available for all device types.
  • gravity - return just acceleration due to gravity. Not available for all device types.
  • availability(accel) - return the availability of acceleration data: 1 if available, 0 otherwise. Defaults to 5min resolution, unless resolution or frequency are specified.
frequency
float

The time frequency (in Hz) of the returned timeseries. This is the reciprocal of the resolution parameter. At most one of frequency or resolution may be provided.

resolution
float

Time interval between returned points, in seconds. This is the reciprocal of the frequency parameter. At most one of frequency or resolution may be provided.

interpolation
string
Default: ""
Enum: "" "linear" null "previous" "zero"

How to fill in timestamps with no data, when frequency or resolution has been specified.

  • If this parameter is omitted or an empty string, timestamps with no data are skipped.
  • If linear, missing values are interpolated with a linear function connecting the last known value and the next.
  • If null, missing values are null.
  • If previous, missing values are filled in by repeating the last known value, until there is data again.
  • If zero, missing values are replaced with 0.0.
timestamp
string
Default: "unix"
Enum: "unix" "datetime" "iso"

Timestamp format.

timezone
integer
Default: 0

The timezone offset, in seconds, used to calculate string-based timestamp formats such as datetime and iso. For example, PST (UTC-0800) is represented as -28800. If omitted, the timezone is UTC.

page
integer >= 0
Default: 0

The page number, to be used if the query result exceeds the pagination limit. Numbering starts at 0 (i.e. page=0 returns the first page of the response).

next_page_token
string <byte>

A token provided in the request to obtain the subsequent set of records in a dataset. When providing this parameter, the page parameter must not be set. This token is obtained from the 'X-Rune-Next-Page-Token' response header field.

page_size
integer [ 0 .. 3600000 ]
Default: 3600000

Maximum number of events to return per page. If page_size=0, the default will be used.

Responses

200

Successful request

400

Bad request

401

Not authorized to perform the request

404

Not found

429

Client IP throttled

500

Internal server error

503

Service unavailable

get /v1/accel.csv
https://stream.runelabs.io/v1/accel.csv

Response samples

Content type
text/csv
Example
Copy
time,x,y,z
1565304080.1,0,0.1,0.1
1565304080.2,1.4,0.3,0.7
1565304080.3,1,1.2,0.2

Events

Query patient events occurring within a given time range. Unlike other streams, events are discrete instances in time and have no notion of sampling frequency or interpolation.

Events are categorized into types through a nested, three-level classification in the form of namespace.category.enum.

  1. Namespace: specifies the general source of the event. The most common namespace is device, which includes all events generated by patient devices. Other namespaces include (but are not limited to) custom events recorded by researchers, clinicians, or sourced from external health databases.
  2. Category: general classification of different types of events (e.g. medication, settings, therapy, etc)
  3. Enum: a specific enumeration within the category. Not all events have an enumeration. For example, within the medication category, each specific medication that the patient has taken could be an enumerated event type. However, the device.implant event type does not have an enumeration.

When querying, event types can be selected at any of the three levels of classification. For example, specifying device.medication.propranolol would list all times the patient recorded specifically taking Propranolol, while querying for just device.medication would give you all medication events regardless of drug taken. Likewise, querying just device would return all events logged by/through a given patent device.

Event (JSON)

A successful request returns a JSON object. See response examples.

query Parameters
event
string

The type of event to query, in the form namespace.category.enum or some prefix of that (see description above). By default, all event types are returned.

patient_id
required
string

Patient ID. If authenticating with a client key pair, this parameter may be omitted: the patient is inferred from the key pair.

device_id
required
string

ID of the device from which data was reported.

start_time
float

Unix timestamp with the start of the time range to query. This is inclusive: all returned timestamps will be >= start_time.

end_time
float

Unix timestamp with the end of the time range to query. This is exclusive: all returned timestamps will be < end_time.

timestamp
string
Default: "unix"
Enum: "unix" "datetime" "iso"

Timestamp format.

timezone
integer
Default: 0

The timezone offset, in seconds, used to calculate string-based timestamp formats such as datetime and iso. For example, PST (UTC-0800) is represented as -28800. If omitted, the timezone is UTC.

page
integer >= 0
Default: 0

The page number, to be used if the query result exceeds the pagination limit. Numbering starts at 0 (i.e. page=0 returns the first page of the response).

page_size
integer [ 0 .. 10000 ]
Default: 10000

Maximum number of events to return per page. If page_size=0, the default will be used.

Responses

200

Successful request

400

Bad request

401

Not authorized to perform the request

404

Not found

429

Client IP throttled

500

Internal server error

503

Service unavailable

get /v1/event.json
https://stream.runelabs.io/v1/event.json

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    {
    },
  • "success": true
}

Heart Rate

Query heart rate data.

Heart Rate (JSON)

A successful request returns a JSON object, with a result key containing timeseries data. The format of the result depends on several query parameters:

  • expression determines the structure of the result object.
  • timestamp determines the format of the timestamps.
  • partition_size segments each array into sub-arrays.

See details for each query parameter, as well as the response examples.

query Parameters
patient_id
required
string

Patient ID. If authenticating with a client key pair, this parameter may be omitted: the patient is inferred from the key pair.

device_id
required
string

ID of the device from which data was reported.

start_time
required
float

Unix timestamp with the start of the time range to query. This is inclusive: all returned timestamps will be >= start_time.

end_time
required
float

Unix timestamp with the end of the time range to query. This is exclusive: all returned timestamps will be < end_time.

expression
string
Default: "bpm"
Enum: "bpm" "availability(bpm)"

Determines what kind of data is returned:

  • bpm - return heart rate measured as beats per minute (BPM).
  • availability(bpm) - return the availability of BPM data: 1 if available, 0 otherwise.
frequency
float

The time frequency (in Hz) of the returned timeseries. This is the reciprocal of the resolution parameter. At most one of frequency or resolution may be provided.

resolution
float

Time interval between returned points, in seconds. This is the reciprocal of the frequency parameter. At most one of frequency or resolution may be provided.

interpolation
string
Default: ""
Enum: "" "linear" null "previous" "zero"

How to fill in timestamps with no data, when frequency or resolution has been specified.

  • If this parameter is omitted or an empty string, timestamps with no data are skipped.
  • If linear, missing values are interpolated with a linear function connecting the last known value and the next.
  • If null, missing values are null.
  • If previous, missing values are filled in by repeating the last known value, until there is data again.
  • If zero, missing values are replaced with 0.0.
timestamp
string
Default: "unix"
Enum: "unix" "datetime" "iso"

Timestamp format.

timezone
integer
Default: 0

The timezone offset, in seconds, used to calculate string-based timestamp formats such as datetime and iso. For example, PST (UTC-0800) is represented as -28800. If omitted, the timezone is UTC.

page
integer >= 0
Default: 0

The page number, to be used if the query result exceeds the pagination limit. Numbering starts at 0 (i.e. page=0 returns the first page of the response).

next_page_token
string <byte>

A token provided in the request to obtain the subsequent set of records in a dataset. When providing this parameter, the page parameter must not be set. This token is obtained from the 'X-Rune-Next-Page-Token' response header field.

page_size
integer [ 0 .. 10000 ]
Default: 10000

Maximum number of events to return per page. If page_size=0, the default will be used.

partition_size
integer

If set, break up result data for each stream into subsets of partition_size number of points. The last partition returned may not necessarily contain partition_size points.

Responses

200

Successful request

400

Bad request

401

Not authorized to perform the request

404

Not found

429

Client IP throttled

500

Internal server error

503

Service unavailable

get /v1/heartrate.json
https://stream.runelabs.io/v1/heartrate.json

Response samples

Content type
application/json
Example
Copy
Expand all Collapse all
{
  • "result":
    {
    }
}

Heart Rate (CSV)

A successful request returns CSV data. The format depends on several query parameters:

  • expression determines the columns of data that are returned.
  • timestamp determines the format of the timestamps.

See details for each query parameter, as well as the response examples.

query Parameters
patient_id
required
string

Patient ID. If authenticating with a client key pair, this parameter may be omitted: the patient is inferred from the key pair.

device_id
required
string

ID of the device from which data was reported.

start_time
required
float

Unix timestamp with the start of the time range to query. This is inclusive: all returned timestamps will be >= start_time.

end_time
required
float

Unix timestamp with the end of the time range to query. This is exclusive: all returned timestamps will be < end_time.

expression
string
Default: "bpm"
Enum: "bpm" "availability(bpm)"

Determines what kind of data is returned:

  • bpm - return heart rate measured as beats per minute (BPM).
  • availability(bpm) - return the availability of BPM data: 1 if available, 0 otherwise.
frequency
float

The time frequency (in Hz) of the returned timeseries. This is the reciprocal of the resolution parameter. At most one of frequency or resolution may be provided.

resolution
float

Time interval between returned points, in seconds. This is the reciprocal of the frequency parameter. At most one of frequency or resolution may be provided.

interpolation
string
Default: ""