NAV
cURL Python

HeartKey® Developer Documentation (On-Premises Deployment)

HeartKey Rhythm Overview

The HeartKey Rhythm ECG Analysis Software Library is Software as a Medical Device (SaMD) which can be integrated into different ECG platforms such as ECG management systems, ECG analysis platforms or remote patient monitoring platforms.

The available algorithms are capable of removing ECG noise and enhancing signal clarity to deliver health data with actionable wellness insights for both medical and consumer applications.

If you require more information about any of the libraries covered above, please contact either your B-Secur representative or the B-Secur customer support team at: support@b-secur.com

Cautions

The following items are cautions for HeartKey Rhythm. Note these are not exhaustive

Usage Information

The usage of HeartKey is monitored and managed based on several flexible metrics. Any limits may be found in the appropriate legal agreements. If a limit change or assistance with usage tracking is required, please contact either your B-Secur representative or the B-Secur customer support team at: support@b-secur.com

Software Specifications

The HeartKey Rhythm software shall be able to run on a PC OR server with the minimum specifications below along the configuration required from a cybersecurity perspective:

Specification PC Server
RAM 16 GB 32 GB
CPU Intel® Core i7 or similar Intel® Xeon® Silver 4208 or similar

HeartKey Rhythm supports the following inputs data types:

The input for all features is a Raw ECG Signal, in JSON, CSV, or EDF / EDF+ format, input as mV or counts.

The data must be greater than 20 seconds in length and less than 24 hours in length. If files greater than 24 hours in length are to be processed, the integrator should split the data up, in individual files containing up to 24 hours of ECG data, and process them separately, combining the outputs as required.

Rate Limiting

To ensure optimal performance and stability, we recommend implementing rate limiting for incoming requests. This should be based on best practices and typical usage patterns, of which we found the following threshold to be suggested

Limit Refresh Period: 60 seconds Requests per Period: 500 requests Timeout Duration: 0 seconds

Regularly monitor your application’s traffic and performance metrics to ensure that the rate limit is appropriate for your installation and set up. Based on your monitoring, you may need to adjust the rate limit to better fit your application's needs. For example, if you notice frequent rate limit hits and the application is stable, consider increasing the allowed requests per period, or if you require a higher throughput of requests, consider increasing the requests per period. You may also want to keep the threshold per running instance and increase the number or running instances.

OpenAPI Specification YAML

For the complete API specification in OpenAPI YAML format, please view or download the file.

HeartKey Rhythm v1

Replace [host] and [port] with the actual host name and port number where the endpoints are hosted.

Base URLs:

Authentication

HeartKey Rhythm - Signal Processing Engine

Signal Processing APIs

getSignalProcessingEngine

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine

Signal Processing of ECG data from Raw Data

Body parameter

{
  "rawEcgSamples": {
    "data": [
      0.1
    ],
    "leadsOn": [
      true
    ],
    "dataFormat": "MILLIVOLTS"
  },
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RawSignal true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Hardware Configuration is Required"
  }
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "exception message"
  }
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
500 Internal Server Error Internal Server Error ErrorResponse

getSignalProcessingEngineFromEdfFile

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/edf-file \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/signal-processing-engine/edf-file

Signal Processing of ECG Data From EDF File

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true EDF file to upload
» config body object false Configuration Settings
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgChannelName body string false Location of EKG signal within the EDF(+) file. A default value of "ECG" will be assumed if not provided.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getProcessedSignalEdfFileWebhook

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/edf-file/webhook \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/signal-processing-engine/edf-file/webhook

Signal Processing of ECG Data From EDF File Webhook

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true EDF file to upload
» config body object true Configuration Settings
»» responseUrl body string true URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgChannelName body string false Location of EKG signal within the EDF(+) file. A default value of "ECG" will be assumed if not provided.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromEDFDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/edf-file/download \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine/edf-file/download

Signal Processing of ECG Data From EDF File Download

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromEdfFileWebhookDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/edf-file/download/webhook \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine/edf-file/download/webhook

Signal Processing of ECG Data From EDF File Download Webhook

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromFile

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/ecg-file \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/signal-processing-engine/ecg-file

Signal Processing of ECG Data From ECG File

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true ECG file to upload
» config body object false Configuration Settings
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getProcessedSignalEcgFileWebhook

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/ecg-file/webhook \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/signal-processing-engine/ecg-file/webhook

Signal Processing of ECG Data From ECG File Webhook

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true ECG file to upload
» config body object true Configuration Settings
»» responseUrl body string true URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromURL

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/ecg-file/download \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine/ecg-file/download

Signal Processing of ECG Data From ECG File Download

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromFileDownloadAsync

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/ecg-file/download/webhook \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine/ecg-file/download/webhook

Signal Processing of ECG Data From ECG File Download Webhook

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromCsvFile

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/csv-file \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/signal-processing-engine/csv-file

Signal Processing of ECG Data From CSV File

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true CSV file to upload
» config body object true Configuration Settings
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig true Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgColumnIndex body integer(int32) false The index of the column in the CSV file that contains ECG data for processing. Column numbering begins at 0.
»» leadsOnColumnIndex body integer(int32) false The index of the column in the CSV file that contains leads-on data for processing. Column numbering begins at 0.
»» hasHeaders body boolean true Whether the CSV file for processing has a header row
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromCsvFileAsync

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/csv-file/webhook \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/signal-processing-engine/csv-file/webhook

Signal Processing of ECG Data From CSV File Webhook

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true CSV file to upload
» config body object true Configuration Settings
»» responseUrl body string true URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig true Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgColumnIndex body integer(int32) false The index of the column in the CSV file that contains ECG data for processing. Column numbering begins at 0.
»» leadsOnColumnIndex body integer(int32) false The index of the column in the CSV file that contains leads-on data for processing. Column numbering begins at 0.
»» hasHeaders body boolean true Whether the CSV file for processing has a header row
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromUrlCSVData

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/csv-file/download \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine/csv-file/download

Signal Processing of ECG Data From CSV File Download

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK SPEResponse
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getSignalProcessingEngineFromDownloadCsvFileAsync

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/signal-processing-engine/csv-file/download/webhook \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/signal-processing-engine/csv-file/download/webhook

Signal Processing of ECG Data From CSV File Download Webhook

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

HeartKey Rhythm - Arrhythmia Analysis

Arrhythmia Analysis APIs

getContinuousArrhythmiaFromRawObject

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis

Arrhythmia analysis of ECG data from raw data object

Body parameter

{
  "rawEcgSamples": {
    "data": [
      0.1
    ],
    "leadsOn": [
      true
    ],
    "dataFormat": "MILLIVOLTS"
  },
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RawSignal true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

{
  "arrhythmiaClassifications": [
    {
      "arrClassification": "INCONCLUSIVE",
      "durationSamples": 0,
      "durationTime": 0,
      "startSample": 0,
      "endSample": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "heartRateMetrics": {
        "min": 0.1,
        "max": 0.1,
        "avg": 0.1
      },
      "beatCount": 0
    }
  ],
  "beatClusters": [
    {
      "beatLevel": {
        "beatClassification": "Q",
        "beatClusterIndex": 0,
        "rpeakLocationSampleIndices": [
          0
        ],
        "rpeakLocationTimestampsUTC": [
          "2019-08-24T14:15:22Z"
        ],
        "rpeakLocationTimestampsMs": [
          0
        ]
      },
      "beatClusterLevel": {
        "template": [
          0.1
        ],
        "numberOfBeats": 0,
        "numberOfClusters": 0
      }
    }
  ],
  "heartRates": [
    {
      "heartRate": 0,
      "sampleIndex": 0,
      "timestampMs": 0,
      "timestampUTC": "2019-08-24T14:15:22Z",
      "displayStatus": "DO_NOT_DISPLAY"
    }
  ],
  "rhythmBurdens": {
    "INCONCLUSIVE": 0.05,
    "NORMAL": 0.5,
    "ATRIAL_FIBRILLATION": 0.1,
    "BRADYCARDIA": 0.05,
    "TACHYCARDIA": 0.1,
    "PAUSE": 0.01,
    "UNREADABLE": 0.01
  },
  "beatBurdens": {
    "Q": 0.4,
    "N": 0.2,
    "V": 0.1,
    "S": 0.05,
    "F": 0.05
  },
  "ectopicBeatBurdens": {
    "ISOLATED_PVC": {
      "total": 10,
      "burden": 0.5
    }
  },
  "arrhythmiaAnalysisConfig": {
    "bradycardiaThreshold": 0,
    "tachycardiaThreshold": 0,
    "absolutePauseThreshold": 0.1,
    "relativePauseThreshold": 0
  },
  "heartRateTrend": {
    "min": 0,
    "max": 0,
    "average": 0.1
  }
}

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Hardware Configuration is Required"
  }
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "exception message"
  }
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

Responses

Status Meaning Description Schema
200 OK OK ArrhythmiaAnalysisInfo
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
500 Internal Server Error Internal Server Error ErrorResponse

getContinuousArrhythmiaFromEdfFile

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/edf-file \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: application/json' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/arrhythmia-analysis/edf-file

Arrhythmia Analysis of ECG data from EDF file.

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true The EDF file to upload
» config body object false Configuration Settings
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgChannelName body string false Location of EKG signal within the EDF(+) file. A default value of "ECG" will be assumed if not provided.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
»» bradycardiaThreshold body integer(int32) false Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
»» tachycardiaThreshold body integer(int32) false Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
»» absolutePauseThreshold body number(double) false Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
»» relativePauseThreshold body integer(int32) false Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

{
  "arrhythmiaClassifications": [
    {
      "arrClassification": "INCONCLUSIVE",
      "durationSamples": 0,
      "durationTime": 0,
      "startSample": 0,
      "endSample": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "heartRateMetrics": {
        "min": 0.1,
        "max": 0.1,
        "avg": 0.1
      },
      "beatCount": 0
    }
  ],
  "beatClusters": [
    {
      "beatLevel": {
        "beatClassification": "Q",
        "beatClusterIndex": 0,
        "rpeakLocationSampleIndices": [
          0
        ],
        "rpeakLocationTimestampsUTC": [
          "2019-08-24T14:15:22Z"
        ],
        "rpeakLocationTimestampsMs": [
          0
        ]
      },
      "beatClusterLevel": {
        "template": [
          0.1
        ],
        "numberOfBeats": 0,
        "numberOfClusters": 0
      }
    }
  ],
  "heartRates": [
    {
      "heartRate": 0,
      "sampleIndex": 0,
      "timestampMs": 0,
      "timestampUTC": "2019-08-24T14:15:22Z",
      "displayStatus": "DO_NOT_DISPLAY"
    }
  ],
  "rhythmBurdens": {
    "INCONCLUSIVE": 0.05,
    "NORMAL": 0.5,
    "ATRIAL_FIBRILLATION": 0.1,
    "BRADYCARDIA": 0.05,
    "TACHYCARDIA": 0.1,
    "PAUSE": 0.01,
    "UNREADABLE": 0.01
  },
  "beatBurdens": {
    "Q": 0.4,
    "N": 0.2,
    "V": 0.1,
    "S": 0.05,
    "F": 0.05
  },
  "ectopicBeatBurdens": {
    "ISOLATED_PVC": {
      "total": 10,
      "burden": 0.5
    }
  },
  "arrhythmiaAnalysisConfig": {
    "bradycardiaThreshold": 0,
    "tachycardiaThreshold": 0,
    "absolutePauseThreshold": 0.1,
    "relativePauseThreshold": 0
  },
  "heartRateTrend": {
    "min": 0,
    "max": 0,
    "average": 0.1
  }
}

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK ArrhythmiaAnalysisInfo
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEdfFileWebhook

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/edf-file/webhook \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/arrhythmia-analysis/edf-file/webhook

Arrhythmia Analysis of ECG data from EDF file and sent to webhook url.

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true The EDF file to upload
» config body object true Configuration Settings
»» responseUrl body string true URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgChannelName body string false Location of EKG signal within the EDF(+) file. A default value of "ECG" will be assumed if not provided.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
»» bradycardiaThreshold body integer(int32) false Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
»» tachycardiaThreshold body integer(int32) false Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
»» absolutePauseThreshold body number(double) false Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
»» relativePauseThreshold body integer(int32) false Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEdfFileDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/edf-file/download \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis/edf-file/download

Arrhythmia Analysis of ECG data from EDF file downloaded from file storage.

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

{
  "arrhythmiaClassifications": [
    {
      "arrClassification": "INCONCLUSIVE",
      "durationSamples": 0,
      "durationTime": 0,
      "startSample": 0,
      "endSample": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "heartRateMetrics": {
        "min": 0.1,
        "max": 0.1,
        "avg": 0.1
      },
      "beatCount": 0
    }
  ],
  "beatClusters": [
    {
      "beatLevel": {
        "beatClassification": "Q",
        "beatClusterIndex": 0,
        "rpeakLocationSampleIndices": [
          0
        ],
        "rpeakLocationTimestampsUTC": [
          "2019-08-24T14:15:22Z"
        ],
        "rpeakLocationTimestampsMs": [
          0
        ]
      },
      "beatClusterLevel": {
        "template": [
          0.1
        ],
        "numberOfBeats": 0,
        "numberOfClusters": 0
      }
    }
  ],
  "heartRates": [
    {
      "heartRate": 0,
      "sampleIndex": 0,
      "timestampMs": 0,
      "timestampUTC": "2019-08-24T14:15:22Z",
      "displayStatus": "DO_NOT_DISPLAY"
    }
  ],
  "rhythmBurdens": {
    "INCONCLUSIVE": 0.05,
    "NORMAL": 0.5,
    "ATRIAL_FIBRILLATION": 0.1,
    "BRADYCARDIA": 0.05,
    "TACHYCARDIA": 0.1,
    "PAUSE": 0.01,
    "UNREADABLE": 0.01
  },
  "beatBurdens": {
    "Q": 0.4,
    "N": 0.2,
    "V": 0.1,
    "S": 0.05,
    "F": 0.05
  },
  "ectopicBeatBurdens": {
    "ISOLATED_PVC": {
      "total": 10,
      "burden": 0.5
    }
  },
  "arrhythmiaAnalysisConfig": {
    "bradycardiaThreshold": 0,
    "tachycardiaThreshold": 0,
    "absolutePauseThreshold": 0.1,
    "relativePauseThreshold": 0
  },
  "heartRateTrend": {
    "min": 0,
    "max": 0,
    "average": 0.1
  }
}

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK ArrhythmiaAnalysisInfo
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEdfFileWebhookDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/edf-file/download/webhook \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis/edf-file/download/webhook

Arrhythmia Analysis of ECG data from EDF file downloaded from file storage and sent to webhook url.

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEcgFile

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/ecg-file \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: application/json' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/arrhythmia-analysis/ecg-file

Arrhythmia Analysis of ECG data from ECG file.

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true The ECG file to upload
» config body object false Configuration Settings
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
»» bradycardiaThreshold body integer(int32) false Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
»» tachycardiaThreshold body integer(int32) false Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
»» absolutePauseThreshold body number(double) false Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
»» relativePauseThreshold body integer(int32) false Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

{
  "arrhythmiaClassifications": [
    {
      "arrClassification": "INCONCLUSIVE",
      "durationSamples": 0,
      "durationTime": 0,
      "startSample": 0,
      "endSample": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "heartRateMetrics": {
        "min": 0.1,
        "max": 0.1,
        "avg": 0.1
      },
      "beatCount": 0
    }
  ],
  "beatClusters": [
    {
      "beatLevel": {
        "beatClassification": "Q",
        "beatClusterIndex": 0,
        "rpeakLocationSampleIndices": [
          0
        ],
        "rpeakLocationTimestampsUTC": [
          "2019-08-24T14:15:22Z"
        ],
        "rpeakLocationTimestampsMs": [
          0
        ]
      },
      "beatClusterLevel": {
        "template": [
          0.1
        ],
        "numberOfBeats": 0,
        "numberOfClusters": 0
      }
    }
  ],
  "heartRates": [
    {
      "heartRate": 0,
      "sampleIndex": 0,
      "timestampMs": 0,
      "timestampUTC": "2019-08-24T14:15:22Z",
      "displayStatus": "DO_NOT_DISPLAY"
    }
  ],
  "rhythmBurdens": {
    "INCONCLUSIVE": 0.05,
    "NORMAL": 0.5,
    "ATRIAL_FIBRILLATION": 0.1,
    "BRADYCARDIA": 0.05,
    "TACHYCARDIA": 0.1,
    "PAUSE": 0.01,
    "UNREADABLE": 0.01
  },
  "beatBurdens": {
    "Q": 0.4,
    "N": 0.2,
    "V": 0.1,
    "S": 0.05,
    "F": 0.05
  },
  "ectopicBeatBurdens": {
    "ISOLATED_PVC": {
      "total": 10,
      "burden": 0.5
    }
  },
  "arrhythmiaAnalysisConfig": {
    "bradycardiaThreshold": 0,
    "tachycardiaThreshold": 0,
    "absolutePauseThreshold": 0.1,
    "relativePauseThreshold": 0
  },
  "heartRateTrend": {
    "min": 0,
    "max": 0,
    "average": 0.1
  }
}

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK ArrhythmiaAnalysisInfo
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEcgFileWebhook

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/ecg-file/webhook \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/arrhythmia-analysis/ecg-file/webhook

Arrhythmia Analysis of ECG data from ECG file and sent to webhook url.

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true The ECG file to upload
» config body object true Configuration Settings
»» responseUrl body string true URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
»» hardwareConfig body HardwareConfig false Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
»» bradycardiaThreshold body integer(int32) false Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
»» tachycardiaThreshold body integer(int32) false Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
»» absolutePauseThreshold body number(double) false Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
»» relativePauseThreshold body integer(int32) false Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEcgFileDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/ecg-file/download \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis/ecg-file/download

Arrhythmia Analysis of ECG data from ECG file downloaded from file storage.

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

{
  "arrhythmiaClassifications": [
    {
      "arrClassification": "INCONCLUSIVE",
      "durationSamples": 0,
      "durationTime": 0,
      "startSample": 0,
      "endSample": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "heartRateMetrics": {
        "min": 0.1,
        "max": 0.1,
        "avg": 0.1
      },
      "beatCount": 0
    }
  ],
  "beatClusters": [
    {
      "beatLevel": {
        "beatClassification": "Q",
        "beatClusterIndex": 0,
        "rpeakLocationSampleIndices": [
          0
        ],
        "rpeakLocationTimestampsUTC": [
          "2019-08-24T14:15:22Z"
        ],
        "rpeakLocationTimestampsMs": [
          0
        ]
      },
      "beatClusterLevel": {
        "template": [
          0.1
        ],
        "numberOfBeats": 0,
        "numberOfClusters": 0
      }
    }
  ],
  "heartRates": [
    {
      "heartRate": 0,
      "sampleIndex": 0,
      "timestampMs": 0,
      "timestampUTC": "2019-08-24T14:15:22Z",
      "displayStatus": "DO_NOT_DISPLAY"
    }
  ],
  "rhythmBurdens": {
    "INCONCLUSIVE": 0.05,
    "NORMAL": 0.5,
    "ATRIAL_FIBRILLATION": 0.1,
    "BRADYCARDIA": 0.05,
    "TACHYCARDIA": 0.1,
    "PAUSE": 0.01,
    "UNREADABLE": 0.01
  },
  "beatBurdens": {
    "Q": 0.4,
    "N": 0.2,
    "V": 0.1,
    "S": 0.05,
    "F": 0.05
  },
  "ectopicBeatBurdens": {
    "ISOLATED_PVC": {
      "total": 10,
      "burden": 0.5
    }
  },
  "arrhythmiaAnalysisConfig": {
    "bradycardiaThreshold": 0,
    "tachycardiaThreshold": 0,
    "absolutePauseThreshold": 0.1,
    "relativePauseThreshold": 0
  },
  "heartRateTrend": {
    "min": 0,
    "max": 0,
    "average": 0.1
  }
}

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK ArrhythmiaAnalysisInfo
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromEcgFileWebhookDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/ecg-file/download/webhook \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis/ecg-file/download/webhook

Arrhythmia Analysis of ECG data from ECG file downloaded from file storage and sent to webhook url.

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromCsvFile

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/csv-file \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/arrhythmia-analysis/csv-file

Arrhythmia Analysis of ECG data from CSV file.

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true The CSV file to upload
» config body object true Configuration Settings
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig true Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgColumnIndex body integer(int32) false The index of the column in the CSV file that contains ECG data for processing. Column numbering begins at 0.
»» leadsOnColumnIndex body integer(int32) false The index of the column in the CSV file that contains leads-on data for processing. Column numbering begins at 0.
»» hasHeaders body boolean true Whether the CSV file for processing has a header row
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
»» bradycardiaThreshold body integer(int32) false Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
»» tachycardiaThreshold body integer(int32) false Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
»» absolutePauseThreshold body number(double) false Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
»» relativePauseThreshold body integer(int32) false Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

Enumerated Values

Property Value
arrClassification INCONCLUSIVE
arrClassification NORMAL
arrClassification ATRIAL_FIBRILLATION
arrClassification BRADYCARDIA
arrClassification TACHYCARDIA
arrClassification PAUSE
arrClassification UNREADABLE
beatClassification Q
beatClassification N
beatClassification V
beatClassification S
beatClassification F
displayStatus DO_NOT_DISPLAY
displayStatus ESTIMATED
displayStatus ACCURATE
fileType ECG
fileType EDF
fileType CSV

getContinuousArrhythmiaFromCsvFileWebhook

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/csv-file/webhook \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -F 'file=@/path/to/file' 
  -F 'config={request-config};type=application/json'

POST /api/arrhythmia-analysis/csv-file/webhook

Arrhythmia Analysis of ECG data from CSV file and sent to webhook url.

Replace {request-config} with JSON representation of Request Config

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body object false none
» file body string(binary) true The CSV file to upload
» config body object true Configuration Settings
»» responseUrl body string true URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
»» returnFormat body integer(int32) false Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
»» hardwareConfig body HardwareConfig true Hardware Configuration settings
»»» ecgRangeMinUv body integer(int32) false The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» ecgRangeMaxUv body integer(int32) false The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
»»» samplingFrequency body integer(int32) false The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
»»» adcRange body integer(int64) false The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
»»» ecgLeadConfig body string false must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.
»» dataFormat body string false Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
»» ecgColumnIndex body integer(int32) false The index of the column in the CSV file that contains ECG data for processing. Column numbering begins at 0.
»» leadsOnColumnIndex body integer(int32) false The index of the column in the CSV file that contains leads-on data for processing. Column numbering begins at 0.
»» hasHeaders body boolean true Whether the CSV file for processing has a header row
»» responseIndexFormat body string false The desired format of the timestamp/duration response outputs from the algorithm.
»» responseTimeIndexUnit body string false The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
»» recordingStartTime body string(date-time) false The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
»» bradycardiaThreshold body integer(int32) false Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
»» tachycardiaThreshold body integer(int32) false Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
»» absolutePauseThreshold body number(double) false Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
»» relativePauseThreshold body integer(int32) false Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other
»»» ecgLeadConfig UNKNOWN
»»» ecgLeadConfig LEAD_I
»»» ecgLeadConfig LEAD_II
»»» ecgLeadConfig LEAD_III
»»» ecgLeadConfig MCL
»»» ecgLeadConfig ML_I
»»» ecgLeadConfig ML_II
»»» ecgLeadConfig ML_III
»»» ecgLeadConfig LEAD_STERNUM
»» dataFormat MILLIVOLTS
»» dataFormat COUNTS
»» dataFormat UNKNOWN
»» responseIndexFormat TIME
»» responseIndexFormat SAMPLES
»» responseIndexFormat BOTH
»» responseTimeIndexUnit MILLISECONDS
»» responseTimeIndexUnit UTC

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

getContinuousArrhythmiaFromCsvFileDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/csv-file/download \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis/csv-file/download

Arrhythmia Analysis of ECG data from CSV file downloaded from file storage.

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

Enumerated Values

Property Value
arrClassification INCONCLUSIVE
arrClassification NORMAL
arrClassification ATRIAL_FIBRILLATION
arrClassification BRADYCARDIA
arrClassification TACHYCARDIA
arrClassification PAUSE
arrClassification UNREADABLE
beatClassification Q
beatClassification N
beatClassification V
beatClassification S
beatClassification F
displayStatus DO_NOT_DISPLAY
displayStatus ESTIMATED
displayStatus ACCURATE
fileType ECG
fileType EDF
fileType CSV

getContinuousArrhythmiaFromCsvFileWebhookDownload

Code samples

# You can also use wget
curl -X POST http://{host}:{port}/api/arrhythmia-analysis/csv-file/download/webhook \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'
  -d "{request-body}"

POST /api/arrhythmia-analysis/csv-file/download/webhook

Arrhythmia Analysis of ECG data from CSV file downloaded from file storage and sent to webhook url.

Body parameter

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values
body body RequestConfig true none

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Constraint Violation

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Constraint Violations",
  "errors": {
    "1": "Raw Data Samples are Required",
    "2": "Sampling Frequency is Required"
  }
}

Missing Request Part

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Missing Servlet Request Part",
  "errors": {
    "cause": "Required part 'file' is not present."
  }
}

Max File Size Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "Max Request Size Exceeded. Max size: 500MB"
}

Illegal Argument Exception

{
  "status": "Bad Request",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "A method has been passed an inappropriate argument",
  "errors": {
    "cause": "Illegal Argument"
  }
}

Unsupported Media Type

{
  "timestamp": "2024-06-11T10:00:00Z",
  "status": "415",
  "error": "Unsupported Media Type"
}

Processing Exception

{
  "status": "Internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An error occurred during processing of the raw signal"
}

IO Exception

{
  "status": "internal Server Error",
  "timestamp": "2024-06-11T10:00:00Z",
  "message": "An internal error occurred when reading the file"
}

Responses

Status Meaning Description Schema
200 OK OK AsyncAck
400 Bad Request Bad Request ErrorResponse
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
406 Not Acceptable Not Acceptable None
415 Unsupported Media Type Unsupported Media Type None
500 Internal Server Error Internal Server Error ErrorResponse

Response Schema

version-controller

getVersion

Code samples

# You can also use wget
curl -X GET http://{host}:{port}/api/version \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h' \
  -H 'Authorization: Bearer {access-token}'

GET /api/version

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK string
400 Bad Request Bad Request Inline
401 Unauthorized Unauthorized None

Response Schema

health-controller

getHealthCheck

Code samples

# You can also use wget
curl -X GET http://{host}:{port}/ \
  -H 'Accept: */*' \
  -H 'study-id: 123456789' \
  -H 'study-type: holter-24h'

GET /

Parameters

Name In Type Required Description
study-id header string false must be 1-9 digits long
study-type header string false The Study Type must be one of the specified values

Enumerated Values

Parameter Value
study-type holter-24h
study-type holter-48h
study-type holter-72h
study-type extended-holter-3-7d
study-type extended-holter-8-14d
study-type MCT
study-type event-monitor
study-type other

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK string
400 Bad Request Bad Request Inline

Response Schema

Schemas

ErrorResponse

{
  "status": "string",
  "timestamp": "string",
  "message": "string",
  "errors": {
    "property1": "string",
    "property2": "string"
  }
}

Error Response data

Properties

Name Type Required Restrictions Description
status string false none Error response status code
timestamp string false none Error occurred time
message string false none Error message describing the issue
errors object false none error description
» additionalProperties string false none none

HardwareConfig

{
  "ecgRangeMinUv": 0,
  "ecgRangeMaxUv": 0,
  "samplingFrequency": 0,
  "adcRange": 0,
  "ecgLeadConfig": "UNKNOWN"
}

Hardware Configuration settings

Properties

Name Type Required Restrictions Description
ecgRangeMinUv integer(int32) false none The lower limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
ecgRangeMaxUv integer(int32) false none The higher limit of the dynamic range relating to the input voltage at the EKG electrodes at a resolution of 1uV per bit. Required when processing data in counts, but should always be included to guarantee optimal algorithm performance
samplingFrequency integer(int32) false none The number of samples recorded per second at a resolution of 1Hz. Must be between 125 and 500
adcRange integer(int64) false none The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Required when processing data in counts
ecgLeadConfig string false none must be one of LEAD_II, ML_II, UNKNOWN for ArrhythmiaAnalysis. ML_I and MCL are deprecated and subject to removal in a future release.

Enumerated Values

Property Value
ecgLeadConfig UNKNOWN
ecgLeadConfig LEAD_I
ecgLeadConfig LEAD_II
ecgLeadConfig LEAD_III
ecgLeadConfig MCL
ecgLeadConfig ML_I
ecgLeadConfig ML_II
ecgLeadConfig ML_III
ecgLeadConfig LEAD_STERNUM

RawDataSamples

{
  "data": [
    0.1
  ],
  "leadsOn": [
    true
  ],
  "dataFormat": "MILLIVOLTS"
}

Raw data samples for processing

Properties

Name Type Required Restrictions Description
data [number] false none Raw EKG sample data for analysis. When processing counts data, if any ECG counts samples are negative, the library will assume that all samples are signed. Otherwise, all samples will be assumed to be unsigned
leadsOn [boolean] false none The electrode-contact status of sample readings. Recommended for optimal algorithm performance
dataFormat string false none Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.

Enumerated Values

Property Value
dataFormat MILLIVOLTS
dataFormat COUNTS
dataFormat UNKNOWN

RawSignal

{
  "rawEcgSamples": {
    "data": [
      0.1
    ],
    "leadsOn": [
      true
    ],
    "dataFormat": "MILLIVOLTS"
  },
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Raw Signal data containing hardware configuration data and raw ecg samples

Properties

Name Type Required Restrictions Description
rawEcgSamples RawDataSamples true none Raw data samples for processing
hardwareConfig HardwareConfig true none Hardware Configuration settings
responseIndexFormat string false none The desired format of the timestamp/duration response outputs from the algorithm.
responseTimeIndexUnit string false none The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
recordingStartTime string(date-time) false none The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
bradycardiaThreshold integer(int32) false none Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
tachycardiaThreshold integer(int32) false none Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
absolutePauseThreshold number(double) false none Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
relativePauseThreshold integer(int32) false none Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Property Value
responseIndexFormat TIME
responseIndexFormat SAMPLES
responseIndexFormat BOTH
responseTimeIndexUnit MILLISECONDS
responseTimeIndexUnit UTC

ArrhythmiaAnalysisConfig

{
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Arrhythmia Analysis configuration settings

Properties

Name Type Required Restrictions Description
bradycardiaThreshold integer(int32) false none Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
tachycardiaThreshold integer(int32) false none Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
absolutePauseThreshold number(double) false none Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
relativePauseThreshold integer(int32) false none Threshold for defining relative pause. Limited to 150, 175, 200

ArrhythmiaAnalysisInfo

{
  "arrhythmiaClassifications": [
    {
      "arrClassification": "INCONCLUSIVE",
      "durationSamples": 0,
      "durationTime": 0,
      "startSample": 0,
      "endSample": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "heartRateMetrics": {
        "min": 0.1,
        "max": 0.1,
        "avg": 0.1
      },
      "beatCount": 0
    }
  ],
  "beatClusters": [
    {
      "beatLevel": {
        "beatClassification": "Q",
        "beatClusterIndex": 0,
        "rpeakLocationSampleIndices": [
          0
        ],
        "rpeakLocationTimestampsUTC": [
          "2019-08-24T14:15:22Z"
        ],
        "rpeakLocationTimestampsMs": [
          0
        ]
      },
      "beatClusterLevel": {
        "template": [
          0.1
        ],
        "numberOfBeats": 0,
        "numberOfClusters": 0
      }
    }
  ],
  "heartRates": [
    {
      "heartRate": 0,
      "sampleIndex": 0,
      "timestampMs": 0,
      "timestampUTC": "2019-08-24T14:15:22Z",
      "displayStatus": "DO_NOT_DISPLAY"
    }
  ],
  "rhythmBurdens": {
    "INCONCLUSIVE": 0.05,
    "NORMAL": 0.5,
    "ATRIAL_FIBRILLATION": 0.1,
    "BRADYCARDIA": 0.05,
    "TACHYCARDIA": 0.1,
    "PAUSE": 0.01,
    "UNREADABLE": 0.01
  },
  "beatBurdens": {
    "Q": 0.4,
    "N": 0.2,
    "V": 0.1,
    "S": 0.05,
    "F": 0.05
  },
  "ectopicBeatBurdens": {
    "ISOLATED_PVC": {
      "total": 10,
      "burden": 0.5
    }
  },
  "arrhythmiaAnalysisConfig": {
    "bradycardiaThreshold": 0,
    "tachycardiaThreshold": 0,
    "absolutePauseThreshold": 0.1,
    "relativePauseThreshold": 0
  },
  "heartRateTrend": {
    "min": 0,
    "max": 0,
    "average": 0.1
  }
}

Arrhythmia Analysis Information

Properties

Name Type Required Restrictions Description
arrhythmiaClassifications [RhythmClassifications] false none Response outputs related to the arrhythmia classifications
beatClusters [RhythmClusters] false none Response outputs related to beat clustering based on rhythm similarity
heartRates [HeartRates] false none Heart Rate data
rhythmBurdens object false none Rhythm burdens mapped by classification type
» INCONCLUSIVE number(double) false none Rhythm Burdens for INCONCLUSIVE Type
» NORMAL number(double) false none Rhythm Burdens for NORMAL Type
» ATRIAL_FIBRILLATION number(double) false none Rhythm Burdens for ATRIAL_FIBRILLATION Type
» BRADYCARDIA number(double) false none Rhythm Burdens for BRADYCARDIA Type
» TACHYCARDIA number(double) false none Rhythm Burdens for TACHYCARDIA Type
» PAUSE number(double) false none Rhythm Burdens for PAUSE Type
» UNREADABLE number(double) false none Rhythm Burdens for UNREADABLE Type
beatBurdens object false none Beat burdens mapped by beat classification type
» Q number(double) false none Burden for Q type
» N number(double) false none Burden for N type
» V number(double) false none Burden for V type
» S number(double) false none Burden for S type
» F number(double) false none Burden for F type
ectopicBeatBurdens object false none Ectopic beat burdens mapped by beat type
» ISOLATED_PVC EctopicBeatStatistics false none Ectopic Beat Statistics
arrhythmiaAnalysisConfig ArrhythmiaAnalysisConfig false none Arrhythmia Analysis configuration settings
heartRateTrend HeartRateTrend false none Metrics containing min, max and average heart rate data

ArrhythmiaHeartRateMetrics

{
  "min": 0.1,
  "max": 0.1,
  "avg": 0.1
}

Min , Max and Average Heart Rate Metrics

Properties

Name Type Required Restrictions Description
min number(double) false none Minimum heart rate in this arrhythmia classification window
max number(double) false none Maximum heart rate in this arrhythmia classification window
avg number(double) false none Average heart rate in this arrhythmia classification window

BeatClusterLevel

{
  "template": [
    0.1
  ],
  "numberOfBeats": 0,
  "numberOfClusters": 0
}

Beat Cluster level outputs containing number of beats and cluster data

Properties

Name Type Required Restrictions Description
template [number] false none Averaged heart beat template of the beat cluster level
numberOfBeats integer(int32) false none Number of beats within the beat cluster level
numberOfClusters integer(int32) false none Number of clusters within the beat cluster level

BeatLevel

{
  "beatClassification": "Q",
  "beatClusterIndex": 0,
  "rpeakLocationSampleIndices": [
    0
  ],
  "rpeakLocationTimestampsUTC": [
    "2019-08-24T14:15:22Z"
  ],
  "rpeakLocationTimestampsMs": [
    0
  ]
}

Response outputs related to the beat level generated from clustering

Properties

Name Type Required Restrictions Description
beatClassification string false none Beat Level Classification
beatClusterIndex integer(int32) false none Beat cluster index position
rpeakLocationSampleIndices [integer] false none Position of R peak locations expressed as a sample number
rpeakLocationTimestampsUTC [string] false none Position of R peak locations expressed in Coordinate Universal Time (UTC)
rpeakLocationTimestampsMs [integer] false none Position of R peak location expressed as a time value since library initialisation

Enumerated Values

Property Value
beatClassification Q
beatClassification N
beatClassification V
beatClassification S
beatClassification F

EctopicBeatStatistics

{
  "ISOLATED_PVC": {
    "total": 10,
    "burden": 0.5
  }
}

Ectopic Beat Statistics

Properties

Name Type Required Restrictions Description
total number(double) false none The total number of ectopic beats relating to a specific beat annotation
burden number(double) false none The burden of ectopic beats relating to a specific beat annotation

HeartRateTrend

{
  "min": 0,
  "max": 0,
  "average": 0.1
}

Metrics containing min, max and average heart rate data

Properties

Name Type Required Restrictions Description
min integer(int32) false none Overall minimum heart rate
max integer(int32) false none Overall maximum heart rate
average number(double) false none Overall average heart rate

HeartRates

{
  "heartRate": 0,
  "sampleIndex": 0,
  "timestampMs": 0,
  "timestampUTC": "2019-08-24T14:15:22Z",
  "displayStatus": "DO_NOT_DISPLAY"
}

Heart rate Metrics

Properties

Name Type Required Restrictions Description
heartRate integer(int32) false none Heart rate
sampleIndex integer(int32) false none Sample position index of heart rate output
timestampMs integer(int32) false none Time of heart rate output since library initialisation
timestampUTC string(date-time) false none Time of heart rate output expressed in Coordinate Universal Time (UTC)
displayStatus string false none Heart Rate Display Status

Enumerated Values

Property Value
displayStatus DO_NOT_DISPLAY
displayStatus ESTIMATED
displayStatus ACCURATE

RhythmClassifications

{
  "arrClassification": "INCONCLUSIVE",
  "durationSamples": 0,
  "durationTime": 0,
  "startSample": 0,
  "endSample": 0,
  "startTimestampMs": 0,
  "endTimestampMs": 0,
  "startTimestampUTC": "2019-08-24T14:15:22Z",
  "endTimestampUTC": "2019-08-24T14:15:22Z",
  "heartRateMetrics": {
    "min": 0.1,
    "max": 0.1,
    "avg": 0.1
  },
  "beatCount": 0
}

Response outputs related to the arrhythmia classifications

Properties

Name Type Required Restrictions Description
arrClassification string false none Arrhythmia Classification
durationSamples integer(int32) false none Duration of the analysed ECG segment expressed as a sample number
durationTime integer(int32) false none Duration of the analysed ECG segment expressed as a time value
startSample integer(int32) false none The start position index of the analysed ECG segment
endSample integer(int32) false none The end position index of the analysed ECG segment
startTimestampMs integer(int32) false none The start position of the analysed ECG segment expressed as a time value since library initialisation
endTimestampMs integer(int32) false none The end position of the analysed ECG segment expressed as a time value since library initialisation
startTimestampUTC string(date-time) false none The start position of the analysed segment denoted in Coordinate Universal Time (UTC)
endTimestampUTC string(date-time) false none The end position of the analysed segment denoted in Coordinate Universal Time (UTC)
heartRateMetrics ArrhythmiaHeartRateMetrics false none Min , Max and Average Heart Rate Metrics
beatCount integer(int32) false none Number of beats captured in the analysed ECG segment

Enumerated Values

Property Value
arrClassification INCONCLUSIVE
arrClassification NORMAL
arrClassification ATRIAL_FIBRILLATION
arrClassification BRADYCARDIA
arrClassification TACHYCARDIA
arrClassification PAUSE
arrClassification UNREADABLE

RhythmClusters

{
  "beatLevel": {
    "beatClassification": "Q",
    "beatClusterIndex": 0,
    "rpeakLocationSampleIndices": [
      0
    ],
    "rpeakLocationTimestampsUTC": [
      "2019-08-24T14:15:22Z"
    ],
    "rpeakLocationTimestampsMs": [
      0
    ]
  },
  "beatClusterLevel": {
    "template": [
      0.1
    ],
    "numberOfBeats": 0,
    "numberOfClusters": 0
  }
}

Response outputs related to beat clustering based on rhythm similarity

Properties

Name Type Required Restrictions Description
beatLevel BeatLevel false none Response outputs related to the beat level generated from clustering
beatClusterLevel BeatClusterLevel false none Beat Cluster level outputs containing number of beats and cluster data

ProcessedDataSamples

{
  "processedValues": [
    0.1
  ],
  "leadsOn": [
    true
  ]
}

Response outputs containing processed values and leads on data

Properties

Name Type Required Restrictions Description
processedValues [number] false none Filtered ECG sample values
leadsOn [boolean] false none The electrode-contact status of sample readings

ProcessedSignal

{
  "processedDataSamples": {
    "processedValues": [
      0.1
    ],
    "leadsOn": [
      true
    ]
  },
  "validRPeakLocs": [
    0
  ],
  "samplingFrequency": 0
}

Response outputs containing processed samples, valid R peak location and sampling frequency

Properties

Name Type Required Restrictions Description
processedDataSamples ProcessedDataSamples false none Response outputs containing processed values and leads on data
validRPeakLocs [integer] false none The position index of R peaks within the ECG input samples
samplingFrequency integer(int32) false none The sampling frequency of the processed data

SPEResponse

{
  "processedSignal": {
    "processedDataSamples": {
      "processedValues": [
        0.1
      ],
      "leadsOn": [
        true
      ]
    },
    "validRPeakLocs": [
      0
    ],
    "samplingFrequency": 0
  },
  "sigQualityInfo": {
    "sigQualityRatings": [
      {
        "startSample": 0,
        "endSample": 0,
        "durationSamples": 0,
        "startTimestampMs": 0,
        "endTimestampMs": 0,
        "durationTime": 0,
        "startTimestampUTC": "2019-08-24T14:15:22Z",
        "endTimestampUTC": "2019-08-24T14:15:22Z",
        "sigQualityRating": "LOW"
      }
    ],
    "burdens": {
      "LOW": 30,
      "HIGH": 70
    }
  },
  "processedFile": "string"
}

Signal processing engine response outputs

Properties

Name Type Required Restrictions Description
processedSignal ProcessedSignal false none Response outputs containing processed samples, valid R peak location and sampling frequency
sigQualityInfo SigQualityInfo false none Signal Quality response containing signal quality ratings
processedFile string(byte) false none The response represented as a Base64 encoded string. Only populated when the "returnFormat" request parameter evaluates to true

SigQualityInfo

{
  "sigQualityRatings": [
    {
      "startSample": 0,
      "endSample": 0,
      "durationSamples": 0,
      "startTimestampMs": 0,
      "endTimestampMs": 0,
      "durationTime": 0,
      "startTimestampUTC": "2019-08-24T14:15:22Z",
      "endTimestampUTC": "2019-08-24T14:15:22Z",
      "sigQualityRating": "LOW"
    }
  ],
  "burdens": {
    "LOW": 30,
    "HIGH": 70
  }
}

Signal Quality response containing signal quality ratings

Properties

Name Type Required Restrictions Description
sigQualityRatings [SigQualityRatingSummary] false none Contains data relating to signal quality
burdens object false none burdens mapped by signal quality
» LOW number(double) false none Burden for signal quality LOW
» HIGH number(double) false none Burden for signal quality HIGH

SigQualityRatingSummary

{
  "startSample": 0,
  "endSample": 0,
  "durationSamples": 0,
  "startTimestampMs": 0,
  "endTimestampMs": 0,
  "durationTime": 0,
  "startTimestampUTC": "2019-08-24T14:15:22Z",
  "endTimestampUTC": "2019-08-24T14:15:22Z",
  "sigQualityRating": "LOW"
}

Signal Quality Rating summary

Properties

Name Type Required Restrictions Description
startSample integer(int32) false none The start position index of the analysed ECG window
endSample integer(int32) false none The end position index of the analysed ECG window
durationSamples integer(int32) false none Duration of the analysed ECG window expressed as a sample number
startTimestampMs integer(int32) false none The start position of the analysed ECG window expressed as a time value since library initialisation
endTimestampMs integer(int32) false none The end position of the analysed ECG window expressed as a time value since library initialisation
durationTime integer(int32) false none Duration of the analysed ECG window expressed as a time value
startTimestampUTC string(date-time) false none The start position of the analysed ECG segment denoted in Coordinate Universal Time (UTC)
endTimestampUTC string(date-time) false none The end position of the analysed ECG segment denoted in Coordinate Universal Time (UTC)
sigQualityRating string false none Signal Quality Rating

Enumerated Values

Property Value
sigQualityRating LOW
sigQualityRating HIGH

RequestConfig

{
  "fileUrl": "https://example.com/ecg.edf",
  "responseUrl": "https://example.com/return",
  "returnFormat": 0,
  "hardwareConfig": {
    "ecgRangeMinUv": 0,
    "ecgRangeMaxUv": 0,
    "samplingFrequency": 0,
    "adcRange": 0,
    "ecgLeadConfig": "UNKNOWN"
  },
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 0,
  "hasHeaders": true,
  "ecgChannelName": "string",
  "responseIndexFormat": "TIME",
  "responseTimeIndexUnit": "MILLISECONDS",
  "recordingStartTime": "2019-08-24T14:15:22Z",
  "bradycardiaThreshold": 0,
  "tachycardiaThreshold": 0,
  "absolutePauseThreshold": 0.1,
  "relativePauseThreshold": 0
}

Configuration Settings

Properties

Name Type Required Restrictions Description
fileUrl string true none URL pointing to an ECG, CSV or EDF(+) file for downloading and processing, must be a valid https URL. Required for download endpoints
responseUrl string true none URL of the return location of the response, must be a valid https URL. Required for webhook endpoints
returnFormat integer(int32) false none Whether the algorithm output should be returned in the response JSON format or in the same file format as the request input EKG file. 0 for JSON, 1 for same file format
hardwareConfig HardwareConfig true none Hardware Configuration settings
dataFormat string false none Informs the library whether to treat provided EKG samples as millivolts, counts or unknowns.
ecgColumnIndex integer(int32) false none The index of the column in the CSV file that contains ECG data for processing. Column numbering begins at 0.
leadsOnColumnIndex integer(int32) false none The index of the column in the CSV file that contains leads-on data for processing. Column numbering begins at 0.
hasHeaders boolean true none Whether the CSV file for processing has a header row
ecgChannelName string false none Location of EKG signal within the EDF(+) file. A default value of "ECG" will be assumed if not provided.
responseIndexFormat string false none The desired format of the timestamp/duration response outputs from the algorithm.
responseTimeIndexUnit string false none The desired unit of the timestamp response outputs from the algorithm. Required when a time format is specified
recordingStartTime string(date-time) false none The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Required when a Coordinated Universal Time format is specified
bradycardiaThreshold integer(int32) false none Threshold for defining bradycardia. Limited to 30, 35, 40, 45, 50, 55, 60
tachycardiaThreshold integer(int32) false none Threshold for defining tachycardia. Limited to 100, 110, 120, 130, 140, 150
absolutePauseThreshold number(double) false none Threshold for defining absolute pause. Limited to 1.5, 2, 2.5, 3, 3.5, 4, 4.5
relativePauseThreshold integer(int32) false none Threshold for defining relative pause. Limited to 150, 175, 200

Enumerated Values

Property Value
dataFormat MILLIVOLTS
dataFormat COUNTS
dataFormat UNKNOWN
responseIndexFormat TIME
responseIndexFormat SAMPLES
responseIndexFormat BOTH
responseTimeIndexUnit MILLISECONDS
responseTimeIndexUnit UTC

AsyncAck

{
  "requestId": "string"
}

Asynchronous Request Id for webhook API

Properties

Name Type Required Restrictions Description
requestId string false none Request Id

FileResponse

{
  "fileType": "ECG",
  "returnedFile": "string"
}

File Response output data

Properties

Name Type Required Restrictions Description
fileType string false none The file type
returnedFile string(byte) false none Returned processed File

Enumerated Values

Property Value
fileType ECG
fileType EDF
fileType CSV

User Management

HeartKey provides several services to assist in managing the following:

For the avoidance of doubt, "users" refers to you as the integrator and your company. It does not refer to the users of your systems e.g. Physicians / Patients. You are responsible for managaging the users in your product, you must not use HeartKey to manage users of your product.

HeartKey Account(s)

To access and utilise HeartKey, a user account must be created and authorised by B-Secur. The user account must be registered prior to calling upon any of the algorithm endpoints for the first time.

The HeartKey user account credentials consist of a username (email address) and password. After an account is created by a member of the B-Secur team, these details are automatically distributed by email from the following address: no-reply@verificationemail.com

Reset Password

A HeartKey account password can be reset by the user using the Forgot Password URL followed by the Confirm Forgot Password URL.

In the event that authorisation problems continue to persist or a password cannot be reset, please contact either your B-Secur representative or the B-Secur customer support team at: support@b-secur.com

Forgot Password URL

Request Example

curl --location --request POST 'https://heartkey.cloud/api/v1/auth/forgot-password' \
--header 'Content-Type: application/json' \
--data-raw '{
"username": "<username>"
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "username": "<username>"
})

# Send request
response = requests.post("https://heartkey.cloud/api/v1/auth/forgot-password", 
                         headers={'Content-Type': 'application/json'},
                         data=payload)

# Print response
print(response.text)

The Forgot Password URL requires only the email of the HeartKey account ("username") to be included in the request payload with no authorisation necessary. After the request has been successfully received, a verification email containing a Confirmation Code will be sent to the email address linked to the user account.

https://heartkey.cloud/api/v1/auth/forgot-password

Confirm Forgot Password URL

Request Example

curl --location --request POST 'https://heartkey.cloud/api/v1/auth/confirm-forgot-password' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "<username>",
    "newPassword": "<new_password>",
    "confirmationCode": "<confirmation_code>"
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "username": "<username>",
    "newPassword": "<new_password>",
    "confirmationCode": "<confirmation_code>"
})

# Send request
response = requests.post("https://heartkey.cloud/api/v1/auth/confirm-forgot-password", 
                         headers={'Content-Type': 'application/json'},
                         data=payload)

# Print response
print(response.text)

The Confirm Forgot Password URL requires the following variables to be included in the request payload:

After the request has been successfully processed, the user may gain authorisation using the updated password.

https://heartkey.cloud/api/v1/auth/confirm-forgot-password

Authorisation and Authentication

HeartKey utilises OAuth 2.0 to securely authorise access to endpoint data, without exposing user credentials. The full specification of this framework is documented in the IETF RFC-6749 standard.

Successful authorisation is a pre-requisite for interacting with any of the HeartKey Rhythm algorithm endpoints. The authorisation process involves several steps:

  1. Acquire an access token and refresh token
  2. Use the access token to make authorised requests
  3. If required, refresh the access token after expiration

Token Management

An access token is an object that encapsulates the required security credentials for gaining access to HeartKey Rhythm and must be included in the header of requests made to any of the algorithm endpoints.

A generated access token will only stay valid for 1 hour. Upon the expiry of an access token, a 401 Unauthorised HTTP Status Code will be displayed if a request to one of the HeartKey Rhythm algorithm endpoints is made.

In event of this, a new access token must be generated either by repeating the full authorisation flow or by using a refresh token in order to continue accessing the HeartKey Rhythm. Utilising a refresh token re-enables the client application without the need to authorise again, thereby removing the need to collect credentials each time an access token expires.

Token URL

The Token URL simplifies the OAuth2.0 flow, enabling the generation of access tokens and refresh tokens without the need for a client ID, client secret, or authorisation URL.

https://heartkey.cloud/api/v1/auth/token

Authenticating for the first time

Request Example

curl --location --request POST 'https://heartkey.cloud/api/v1/auth/token' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "<username>",
    "password": "<password>",
    "newPassword": "<new_password>",
    "companyId": "123456",
    "authFlow": "USER_PASSWORD_AUTH"
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "username": "<username>",
    "password": "<password>",
    "newPassword": "<new_password>",
    "companyId": "123456",
    "authFlow": "USER_PASSWORD_AUTH"
})

# Send request
response = requests.post("https://heartkey.cloud/api/v1/auth/token", 
                         headers={'Content-Type': 'application/json'}, 
                         data=payload)

# Print response
print(response.text)

The HeartKey Rhythm account password sent via email is temporary and will expire after 7 days. When authenticating to HeartKey Rhythm for the first time using the Token URL, the temporary password must be updated to a permanent password.

The following five fields must be included within the request body when making a request to the token endpoint for the first time.

If the request is successful, an access token and refresh token will be returned in the response body. The temporary password will have become inactive and been replaced with the chosen permanent password, which should be used for all future authentication requests.

Acquire Tokens

After a user has set up a permanent password, there exists two ways to obtain an access token.

Both of these methods of authentication involve sending a request to the token endpoint

https://heartkey.cloud/api/v1/auth/token

Password Authentication

Request Example

curl --location --request POST 'https://heartkey.cloud/api/v1/auth/token' \
--header 'Content-Type: application/json' \
--data-raw '{
"username": "<username>",
"password": "<password>",
"authFlow": "USER_PASSWORD_AUTH",
"companyId": "123456"
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "username": "<username>",
    "password": "<password>",
    "authFlow": "USER_PASSWORD_AUTH",
    "companyId": "123456"
})

# Send request
response = requests.post("https://heartkey.cloud/api/v1/auth/token", 
                         headers={'Content-Type': 'application/json'}, 
                         data=payload)

# Print response
print(response.text)

When using a password, the following four fields must be included within the request body when making a request to the token endpoint.

If the request is successful, a new access token and refresh token will be returned in the response body.

Refresh Token Authentication

Request Example

curl --location --request POST 'https://heartkey.cloud/api/v1/auth/token' \
--header 'Content-Type: application/json' \
--data-raw '{
"username": "<username>",
"refreshToken": "<refresh_token>",
"authFlow": "REFRESH_TOKEN_AUTH",
"companyId": "123456"
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "username": "<username>",
    "refreshToken": "<refresh_token>",
    "authFlow": "REFRESH_TOKEN_AUTH",
    "companyId": "123456"
})

# Send request
response = requests.post("https://heartkey.cloud/api/v1/auth/token", 
                         headers={'Content-Type': 'application/json'}, 
                         data=payload)

# Print response
print(response.text)

When using a refresh token, the following four fields must be included within the request body when making a request to the token endpoint.

If the request is successful, a new access token will be returned in the response body.

Revoke Token

Request Example

curl --location --request POST POST 'https://heartkey.cloud/api/v1/auth/token' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "<username>",
    "refreshToken" : "<refreshToken>",
    "authFlow": "REVOKE_TOKEN",
    "companyId": "123456"
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "username": "<username>",
    "refreshToken": "<refresh_token>",
    "authFlow": "REVOKE_TOKEN",
    "companyId": "123456"
})

# Send request
response = requests.post("https://heartkey.cloud/api/v1/auth/token", 
                         headers={'Content-Type': 'application/json'}, 
                         data=payload)

# Print response
print(response.text)

To revoke a refresh token, the following four fields must be included within the request body when making a request to the token endpoint.

If the request is successful, token will be revoked and success message is displayed.

For security reasons, we recommend regularly utilizing the REVOKE_TOKEN functionality to revoke tokens as a best practice.

HeartKey Rhythm Algorithms

HeartKey® Rhythm is B-Secur's latest generation of signal processing and arrhythmia analysis algorithms. HeartKey Rhythm currently hosts 2 algorithm services:

Cautions

The following items are cautions for HeartKey Rhythm :

Signal Processing Engine

Overview

The HeartKey Signal Processing Engine consists of the Signal Conditioning, ECG Display Filter, QRS Detection, and Signal Quality algorithms.

ECGs are characterised by five main features (P, Q, R, S, T waves) pertaining to the direction of the electrical signal propagation throughout the heart at various times of a contraction cycle. Analysis of these features allows diagnostic information to be extracted relating to the existence of various arrhythmias such as Atrial Fibrillation, among many others.

HeartKey Rhythm's intelligent and adaptive ECG Display Filter applies signal conditioning to remove noise artefacts from ECG data to enhance usability, thereby improving diagnostic outcomes and increasing the efficiency of the clinical pathway.

The HeartKey Signal Quality algorithm classifies the quality of the ECG signal through quantifying the level of noise corruption within. By enabling cardiac healthcare professionals to focus on inspecting ECG strips of sufficient quality, the Signal Quality algorithm can help to optimise the efficiency of the ECG review process.

Algorithm Definition
SPE - Signal Conditioning Reduce the noise artefact present in the input ECG signal
SPE - QRS Detection Detect the QRS complexes of the input ECG signal
SPE - Signal Quality Identify and classify the ECG segments’ signal quality from the input ECG signal
SPE - ECG Display Filter Filtered ECG intended to be displayed to a qualified healthcare professional to interpret the ECG

The Signal Quality algorithm grades the quality of the input ECG signal using the following classifications:

Status Description
Low ("LOW") The signal is unsuitable for any analysis which may lead to unreliable QRS complex detected or other feature extraction.
High ("HIGH") TThe signal is of suitable quality to allow QRS complexes within the signal to be successfully detected.

Example User Interface

The screenshot below is provided as an example of how HeartKey Rhythm results can be displayed by an end platform that integrates the software. This figures are included just for guidance, the end platform that integrates HeartKey will have a different User Interface.

From a rhythm analysis perspective, HeartKey Rhythm provides summary analytics such as the rhythms burden and the minimum, maximum and mean heart rate of the ECG file. It also provides the following outputs for every arrhythmia episode that allows the platform integrating HeartKey Rhythm to display to the physician:

Example Web App Rhythm NSR

Response Parameters

After successfully making an API call to a Signal Processing Engine algorithm endpoint, the returned response object will contain the following output parameters in a text (JSON) format by default:

Table: Top level fields

Variable Unit Data Type Description
"processedSignal" N/A Object Contains data relating to processed signal. See processedSignal table.
"sigQualityInfo" N/A Object Contains "sigQualityRatings" and "burdens" data. See sigQualityInfo table.
"rawEcgSamples" N/A Object Contains data relating to raw signal. See rawEcgSamples table.
"processedFile" N/A String The response represented as a Base64 encoded string. Only populated when the "returnFormat" request parameter evaluates to true. Otherwise a 'null' value is returned.

Table: processedSignal

Variable Unit Data Type Description
"processedDataSamples" N/A Object of arrays Contains "processedValues" and "leadsOn" data. See processedDataSamples table.
"validRPeakLocs" Sample index Array of integers The position index of R peaks within the ECG input samples
"samplingFrequency" Hertz Integer The sampling frequency of the processed data

Table: processedDataSamples

Variable Unit Data Type Description
"processedValues" Millivolts Array of doubles Filtered ECG sample values
"leadsOn" N/A Array of booleans The electrode-contact status of sample readings (0 = Leads-Off, 1 = Leads-On)

A 0 within the "leadsOn" array corresponds to the signal being deemed unavailable. During this period of unavailability, the "processedValues" will return the raw sample values from the request.

Table: sigQualityInfo

Variable Unit Data Type Description
"sigQualityRatings" N/A Array Contains data relating to signal quality. See sigQualityRatings table.
"burdens" N/A Array Contains "LOW" and "HIGH" burden data. See burdens table.

Table: sigQualityRatings

Variable Unit Data Type Description
"startSample" Sample index Integer The start position index of the analysed ECG window
"endSample" Sample index Integer The end position index of the analysed ECG window
"durationSamples" Samples Integer Duration of the analysed ECG window expressed as a sample number
"startTimestampMs" Milliseconds Integer The start position of the analysed ECG window expressed as a time value since library initialisation
"endTimestampMs" Milliseconds Integer The end position of the analysed ECG window expressed as a time value since library initialisation
"durationTime" Milliseconds Integer Duration of the analysed ECG window expressed as a time value
"startTimestampUTC" Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") String The start position of the analysed ECG segment denoted in Coordinate Universal Time (UTC)
"endTimestampUTC" Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") String The end position of the analysed ECG segment denoted in Coordinate Universal Time (UTC)
"sigQualityRating" N/A String Signal Quality status ("LOW" or "HIGH")

Table: burdens

Variable Unit Data Type Description
"LOW" Percentage Double The proportion of time that the analysed segment is deemed to be in a low quality state
"HIGH" Percentage Double The proportion of time that the analysed segment is deemed to be in a high quality state

Table: rawEcgSamples

Variable Unit Data Type Description
"data" N/A Array of doubles Raw ECG sample values
"leadsOn" N/A Array of booleans The electrode-contact status of sample readings (0 = Leads-Off, 1 = Leads-On)
"dataFormat" N/A String The data format of the raw ECG sample values. Either "MILLIVOLTS" or "COUNTS"

Arrhythmia Analysis

Overview

HeartKey Rhythm's Arrhythmia Analysis algorithm analyses the input ECG signal and returns a range of rhythm and beat annotations. These annotations can be provided to a clinician, helping them focus on the specific problem areas within the ECG.

Example User Interface

The screenshot below is provided as an example of how HeartKey Rhythm results can be displayed by an end platform that integrates the software. This figures are included just for guidance, the end platform that integrates HeartKey will have a different User Interface.

From a beat analysis perspective, HeartKey Rhythm provides summary analytics such as the beat types burden and the number of beat types within the ECG file. It also provides the following outputs that allow the physician to visualise:

Other outputs such as the beat locations, the ECG display signal and the signal quality are also available to the physician.

Example Web App Rhythm

Response Parameters

After successfully making an API call to an Arrhythmia Analysis endpoint, the returned response object will contain the following output parameters in a text (JSON) format:

Table: Arrhythmia Analysis Top Level Fields

Variable Unit Data Type Description
"arrhythmiaClassifications" N/A Array of objects Stores all response outputs related to the arrhythmia classifications. See arrhythmiaClassifications table.
"beatClusters" N/A Array of values Stores response outputs related to beat clustering based on rhythm similarity. See beatClusters table.
"heartRates" N/A Array of objects Stores all response outputs related to heart rate. See heartRates table.
"rhythmBurdens" N/A Object Contains burden data relating to rhythms. See rhythmBurdens table.
"beatBurdens" Percentage Object Stores burden data relating to beats. See beatBurdens table.
"ectopicBeatBurdens" N/A Object Stores burden data relating to ectopic beats. See ectopicBeatBurdens table.
"arrhythmiaAnalysisConfig" N/A Object Stores the configuration settings used during algorithm analysis. See arrhythmiaAnalysisConfig table.
"heartRateTrend" N/A Object Stores min, max and average heart rate. See heartRateTrends table.

Table: arrhythmiaClassifications

Variable Unit Data Type Description
"arrClassification" N/A String Arrhythmia classification
"durationSamples" Samples Integer Duration of the analysed ECG segment expressed as a sample number
"durationTime" Milliseconds Integer Duration of the analysed ECG segment expressed as a time value
"startSample" Sample index Integer The start position index of the analysed ECG segment
"endSample" Sample index Integer The end position index of the analysed ECG segment
"startTimestampMs" Milliseconds Integer The start position of the analysed ECG segment expressed as a time value since library initialisation
"endTimestampMs" Milliseconds Integer The end position of the analysed ECG segment expressed as a time value since library initialisation
"startTimestampUTC" Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") String The start position of the analysed segment denoted in Coordinate Universal Time (UTC)
"endTimestampUTC" Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") String The end position of the analysed segment denoted in Coordinate Universal Time (UTC)
"heartRateMetrics" Heart Rate Metrics data Object Min , Max and Average Heart Rate Metrics. See heartRateMetrics table.
"beatCount" Beats Integer Number of beats captured in the analysed ECG segment

Table: heartRateMetrics

Variable Unit Data Type Description
"min" Beats per minute Double Minimum heart rate in this arrhythmia classification window
"max" Beats per minute Double Maximum heart rate in this arrhythmia classification window
"avg" Beats per minute Double Average heart rate in this arrhythmia classification window

Table: beatClusters

Variable Unit Data Type Description
"beatLevel" N/A Object of values Stores all response outputs related to the beat level generated from clustering. See beatLevel table.
"beatClusterLevel" N/A Object of values Stores all outputs related to the beat cluster level. See beatClusterLevel table.

Table: beatLevel

Variable Unit Data Type Description
"beatClassification" N/A String Beat classification
"beatClusterIndex" Beat cluster index Integer Beat cluster index position
"rpeakLocationSampleIndices" Sample index Integer Position of R peak locations expressed as a sample number
"rpeakLocationTimestampsMs" Milliseconds Integer Position of R peak location expressed as a time value since library initialisation
"rpeakLocationTimestampsUTC" Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") String Position of R peak locations expressed in Coordinate Universal Time (UTC)

Table: beatClusterLevel

Variable Unit Data Type Description
"template" Millivolts Array of doubles Averaged heart beat template of the beat cluster level
"numberOfBeats" Beats Integer Number of beats within the beat cluster level
"numberofClusters" Clusters Integer Number of clusters within the beat cluster level

Table: heartRates

Variable Unit Data Type Description
"heartRate" Beats per minute Integer Heart rate
"sampleIndex" Sample index Integer Sample position index of heart rate output
"timestampMs" Milliseconds Integer Time of heart rate output since library initialisation
"timestampUTC" Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") String Time of heart rate output expressed in Coordinate Universal Time (UTC)
"displayStatus" N/A String Display status of heart rate output ("DO_NOT_DISPLAY", "ESTIMATED" or "ACCURATE")

Table: rhythmBurdens

Variable Unit Data Type Description
"UNCLASSIFIED" Percentage Float Burden of unclassified rhythms
"INCONCLUSIVE" Percentage Float Burden of Inconclusive rhythms
"NORMAL" Percentage Float Burden of normal rhythms
"ATRIAL_FIBRILLATION" Percentage Float Burden of atrial fibrillation rhythms
"BRADYCARDIA" Percentage Float Burden of bradycardia rhythms
"TACHYCARDIA" Percentage Float Burden of tachycardia rhythms
"VENTRICULAR_BIGEMINY" Percentage Float Burden of ventricular bigeminy rhythms
"VENTRICULAR_TRIGEMINY" Percentage Float Burden of ventricular trigeminy rhythms
"VENTRICULAR_QUADRIGEMINY" Percentage Float Burden of ventricular quadrigeminy rhythms
"VENTRICULAR_COUPLET" Percentage Float Burden of ventricular couplet rhythms
"VENTRICULAR_TACHYCARDIA" Percentage Float Burden of ventricular tachycardia rhythms
"PAUSE" Percentage Float Burden of pause rhythms
"UNREADABLE" Percentage Float Burden of unreadable rhythms
"UNKNOWN" Percentage Float Burden of unknown rhythms

Table: beatBurdens

Variable Unit Data Type Description
"Q" Percentage Float Burden of Q beats
"N" Percentage Float Burden of normal beats
"V" Percentage Float Burden of PVC beats
"S" Percentage Float Burden of Supraventricular ectopic beats
"F" Percentage Float Burden of Fusion beats
"UNKNOWN" Percentage Array Burden of unknown beats

Table: ectopicBeatBurdens

Variable Unit Data Type Description
"ISOLATED_PVC" N/A Object Stores the total number and burden of isolated PVC ectopic beats. See ectopicBeatBurdens burdens table.

Table: ectopicBeatBurdens burdens

Variable Unit Data Type Description
"total" Beats Integer The total number of ectopic beats relating to a specific beat annotation
"burden" Percentage Float The burden of ectopic beats relating to a specific beat annotation

Table: arrhythmiaAnalysisConfig

Variable Unit Data Type Description
"bradycardiaThreshold" BPM Integer Threshold for defining bradycardia used during algorithm analysis
"tachycardiaThreshold" BPM Integer Threshold for defining tachycardia used during algorithm analysis
"absolutePauseThreshold" Seconds Float Threshold for defining absolute pause used during algorithm analysis
"relativePauseThreshold" BPM Integer Threshold for defining relative pause used during algorithm analysis

Table: heartRateTrend

Variable Unit Data Type Description
"min" Beats per minute Integer Overall minimum heart rate
"max" Beats per minute Integer Overall maximum heart rate
"avg" Beats per minute Double Overall average heart rate

Endpoint Types

The HTTP endpoints connected to each HeartKey algorithm can be categorised based on their operation type (synchronous or asynchronous) and the input ECG format they accept. Additionally, the available endpoints offer a variety of input and response delivery options to the user, further expanding the flexibility of HeartKey. The types of endpoints are summarised in the following table:

Endpoint Type Operation Type Input ECG Format URL Request Parameters Input ECG File Location Response Delivery Location Input ECG Data Upload Limit
JSON Synchronous Raw JSON N/A N/A Client application 24 hours
File Upload Synchronous CSV or EDF(+) N/A Local storage accessible via the client application Client application 500 MB
File Upload Webhook Asynchronous CSV or EDF(+) "responseUrl" Local storage accessible via the client application Custom online location accessible to HeartKey ("responseUrl") 500 MB
File Download Webhook Asynchronous CSV or EDF(+) "fileUrl" and "responseUrl" Online location made accessible to HeartKey ("fileUrl") Custom online location accessible to HeartKey ("responseUrl") 24 hours

For each data-processing URL, it is possible to formulate the algorithm-specific version by replacing the <algorithm_name> string with one of the algorithm names listed at the beginning of the HeartKey Rhythm Algorithms section.

Base URL

The base URL is specific to each user's deployment. Usually the base URL should be updated to the hostname and port where the application was deployed. For example, if it's running locally on port 8080, it would be http://localhost:8080. If you deployed it on another service or server, http://ip number:port

Synchronous

When a call is made to a synchronous endpoint, the client application/code execution block will wait until a response is returned before continuing.

JSON

Request Example

curl --location --request POST '<base_url>/<algorithm_name>' \
--header 'Authorization: Bearer  <access_token>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "rawEcgSamples": {
        "dataFormat": "MILLIVOLTS",
        "data": [-1.000000,-1.100000,-1.200000,-1.300000],
        "leadsOn": [1,1,1,1]
    },
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "adcRange": 65536,
        "ecgLeadConfig": "UNKNOWN"
    }
}'
# Import packages
import requests

# Define payload
payload = {
    "rawEcgSamples": {
        "dataFormat": "MILLIVOLTS",
        "data": [
        -1.000000,-1.100000,-1.200000,-1.300000],
        "leadsOn": [1,1,1,1]
    },
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "adcRange": 65536,
        "ecgLeadConfig": "UNKNOWN"
    }
}

# Send request
response = requests.post('<base_url>/<algorithm_name>', 
                        headers={'Authorization': 'Bearer <access_token>'},
                        json=payload)

# Print response
response = print(response.text)

JSON endpoints support synchronous requests containing input ECG data in JSON format within the request body.

<base_url>/<algorithm_name>

CSV File Upload URL

Request Example

curl --location '<base_url>/<algorithm_name>/csv-file' \
--header 'Authorization: Bearer <access_token>' \
--form 'file=@"<path_to_csv_file>"' \
--form 'config="{
    \"dataFormat\": \"MILLIVOLTS\",
    \"hardwareConfig\": { 
        \"ecgRangeMinUv\": -32768,
        \"ecgRangeMaxUv\": 32767,
        \"samplingFrequency\": 500,
        \"ecgLeadConfig\": \"UNKNOWN\",
        \"adcRange\": 65536
    },
    \"hasHeaders\": true,
    \"ecgColumnIndex\": 0,
    \"leadsOnColumnIndex\": 1
}";type=application/json'
# Import packages
import json
import requests

# Define config
config = {
    "dataFormat": "MILLIVOLTS",
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "ecgLeadConfig": "UNKNOWN",
        "adcRange": 65536,
    },
    "hasHeaders": True,
    "ecgColumnIndex": 0,
    "leadsOnColumnIndex": 1
}

# Define payload
payload = {
    "file": (
        "file",
        open("<path_to_csv_file>", "rb"),
        "application/octet-stream",
        {"Content-Disposition": "form/data"}
    ),
    "config": (
        "config",
        json.dumps(config),
        "application/json",
        {"Content-Disposition": "form/data"}
    )
}

# Send request
response = requests.post("<base_url>/<algorithm_name>/csv-file",
                        headers={"Authorization": "Bearer <access_token>"},
                        files=payload)

# Print response
print(response.text)

The CSV File Upload URL supports synchronous requests containing input ECG data stored in CSV files.

<base_url>/<algorithm_name>/csv-file

EDF(+) File Upload URL

Request Example

curl --location '<base_url>/<algorithm_name>/edf-file' \
--header 'Authorization: Bearer <access_token>' \
--form 'file=@"<path_to_edf_file>"' \
--form 'config="{
    \"ecgChannelName\": \"ECG\",
    \"hardwareConfig\" : { 
        \"ecgLeadConfig\": \"UNKNOWN\"
    }
}";type=application/json'
# Import packages
import json
import requests

# Define config
config = {
    "ecgChannelName": "ECG",
    "hardwareConfig": { 
      "ecgLeadConfig": "UNKNOWN"
    }
}

# Define payload
payload = {
    "file": (
        "file",
        open("<path_to_edf_file>", "rb"),
        "application/octet-stream",
        {"Content-Disposition": "form/data"}
    ),
    "config": (
        "config",
        json.dumps(config),
        "application/json",
        {"Content-Disposition": "form/data"}
    )
}

# Send request
response = requests.post("<base_url>/<algorithm_name>/edf-file",
                         headers={"Authorization": "Bearer <access_token>"},
                         files=payload

# Print response
response = print(response.text)

The EDF(+) File Upload URL supports synchronous requests containing input ECG data stored in EDF or EDF+ files.

<base_url>/<algorithm_name>/edf-file

CSV File Download URL

Request Example

curl --location '<base_url>/<algorithm_name>/csv-file/download' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
    "fileUrl": "<file_url>",
    "dataFormat": "MILLIVOLTS",
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "ecgLeadConfig": "UNKNOWN",
        "adcRange": 65536
    },
    "hasHeaders": true,
    "ecgColumnIndex": 0,
    "leadsOnColumnIndex": 1
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "fileUrl": "<file_url>",
    "dataFormat": "MILLIVOLTS",
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "ecgLeadConfig": "UNKNOWN",
        "adcRange": 65536
    },
  "hasHeaders": True,
  "ecgColumnIndex": 0,
  "leadsOnColumnIndex": 1
})

# Send request
response = requests.post("<base_url>/<algorithm_name>/csv-file/download",
                         headers={"Authorization": "Bearer <access_token>", "Content-Type": "application/json"},
                         data=payload)

# Print response
response = print(response.text)

The CSV File Download URL supports synchronous requests to enable the downloading of input ECG data stored in CSV files, accessible via direct download links, for algorithm analysis.

<base_url>/<algorithm_name>/csv-file/download

EDF(+) File Download URL

Request Example

curl --location '<base_url>/<algorithm_name>/edf-file/download' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
    "fileUrl": "<file_url>",
    "ecgChannelName": "ECG",
    "hardwareConfig": { 
        "ecgLeadConfig": "UNKNOWN"
    }
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "fileUrl": "<file_url>",
    "ecgChannelName": "ECG",
    "hardwareConfig": { 
        "ecgLeadConfig": "UNKNOWN"
    }
})

# Send request
response = requests.post("<base_url>/<algorithm_name>/edf-file/download",
                         headers={"Authorization": "Bearer <access_token>", "Content-Type": "application/json"},
                         data=payload)

# Print response
response = print(response.text)

The EDF(+) File Download URL supports synchronous requests to enable the downloading of input ECG data stored in EDF or EDF+ files, accessible via direct download links, for algorithm analysis.

<base_url>/<algorithm_name>/edf-file/download

Asynchronous (Webhooks)

Webhooks offer a resource-light method to facilitate data sharing via event reactions. Subscribing to the webhook infrastructure embedded in HeartKey enables request processing to be configured asynchronously, meaning that the client application does not have to wait for a response using the same, single HTTP connection. As a result, HeartKey webhooks are particularly efficient when processing large volumes of ECG data.

Webhook-Specific Response Parameters

When a request to a webhook-supporting endpoint is successfully processed, the following parameters will be returned to the response URL ("responseUrl") in a text (JSON) format by default:

JSON Parameter Data Type Description
"requestId" String Request ID in a UUID RFC-4122 format that is unique to each processed request. Also returned to the client application to acknowledge that the request has been received and to facilitate payload recognition
"status" String HTTP response status
"Data" Array of values Contains algorithm-specific response data. The JSON Parameter name varies depending on the name of the algorithm connected to the endpoint detailed in the request

CSV File Upload Webhook URL

Request Example

curl --location '<base_url>/<algorithm_name>/csv-file/webhook' \
--header 'Authorization: Bearer <access_token>' \
--form 'file=@"<path_to_csv_file>"' \
--form 'config="{ 
    \"responseUrl\": \"<response_url>\",
    \"dataFormat\": \"MILLIVOLTS\",
    \"hardwareConfig\" : { 
        \"ecgRangeMinUv\": -32768,
        \"ecgRangeMaxUv\": 32767,
        \"samplingFrequency\": 500,
        \"ecgLeadConfig\": \"UNKNOWN\",
        \"adcRange\": 65536
   },
   \"hasHeaders\": true,
   \"ecgColumnIndex\": 0,
   \"leadsOnColumnIndex\": 1
}";type=application/json'
# Import packages
import requests
import json

# Define config
config = {
    "responseUrl": "<response_url>",
    "dataFormat": "MILLIVOLTS",
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "ecgLeadConfig": "UNKNOWN",
        "adcRange": 65536
    },
    "hasHeaders": True,
    "ecgColumnIndex": 0,
    "leadsOnColumnIndex": 1
}

# Define payload
payload = {
    "file": (
        "file", 
        open("<path_to_csv_file>", "rb"),
        "application/octet-stream", 
        {"Content-Disposition": "form/data"}
    ),
    "config": (
        "config",
        json.dumps(config),
        "application/json",
        {"Content-Disposition": "form/data"}
    )
}

# Send request
response = requests.post("<base_url>/<algoritm-name>/csv-file/webhook",
                         headers={"Authorization": "Bearer <access_token>"}, 
                         files=payload)

# Print response
print(response.text)

The CSV File Upload Webhook URL supports asynchronous requests via webhooks, enabling the uploading of ECG data stored in CSV files for algorithm analysis, whilst allowing responses to be delivered to a custom URL.

<base_url>/<algorithm_name>/csv-file/webhook

EDF(+) File Upload Webhook URL

Request Example

curl --location '<base_url>/<algorithm_name>/edf-file/webhook' \
--header 'Authorization: Bearer <access_token>' \
--form 'file=@"<path_to_edf_file>"' \
--form 'config="{
    \"responseUrl\": \"<response_url>\",
    \"ecgChannelName\": \"ECG\",
    \"hardwareConfig\": { 
        \"ecgLeadConfig\": \"UNKNOWN\"
    }
}";type=application/json'
# Import packages
import requests
import json

# Define config
config = {
    "responseUrl": "<response_url>",
    "ecgChannelName": "ECG",
    "hardwareConfig": { 
      "ecgLeadConfig": "UNKNOWN"
    }
}

# Define payload
payload = {
    "file": (
        "file", 
        open("<path_to_edf_file>", "rb"),
        "application/octet-stream", 
        {"Content-Disposition": "form/data"}
    ),
    "config": (
        "config",
        json.dumps(config),
        "application/json",
        {"Content-Disposition": "form/data"}
    )
}

# Send request
response = requests.post("<base_url>/<algorithm_name>/edf-file/webhook",
                         headers={"Authorization": "Bearer <access_token>"}, 
                         files=payload)

# Print response
print(response.text)

The EDF(+) File Upload Webhook URL supports asynchronous requests via webhooks, enabling the uploading of ECG data stored in EDF or EDF+ files for algorithm analysis, whilst allowing responses to be delivered to a custom URL.

<base_url>/<algorithm_name>/edf-file/webhook

CSV File Download Webhook URL

Request Example

curl --location '<base_url>/<algorithm_name>/csv-file/download/webhook' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
    "fileUrl": "<file_url>",
    "responseUrl": "<response_url>",
    "dataFormat": "MILLIVOLTS",
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "ecgLeadConfig": "UNKNOWN",
        "adcRange": 65536
    },
    "hasHeaders": true,
    "ecgColumnIndex": 0,
    "leadsOnColumnIndex": 1
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "fileUrl": "<file_url>",
    "responseUrl": "<response_url>",
    "dataFormat": "MILLIVOLTS",
    "hardwareConfig": {
        "ecgRangeMinUv": -32768,
        "ecgRangeMaxUv": 32767,
        "samplingFrequency": 500,
        "ecgLeadConfig": "UNKNOWN",
        "adcRange": 65536
    },
    "hasHeaders": True,
    "ecgColumnIndex": 0,
    "leadsOnColumnIndex": 1
})

# Send request
response = requests.post("<base_url>/<algorithm_name>/csv-file/download/webhook",
                         headers={"Authorization": "Bearer <access_token>", "Content-Type": "application/json"},
                         data=payload)

# Print response
response = print(response.text)

The CSV File Download Webhook URL supports asynchronous requests via webhooks. This endpoint enables the downloading of ECG data stored in CSV files, accessible via direct download links, for algorithm analysis whilst allowing for responses to be delivered to a custom URL.

<base_url>/<algorithm_name>/csv-file/download/webhook

EDF(+) File Download Webhook URL

Request Example

curl --location '<base_url>/<algorithm_name>/edf-file/download/webhook' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
    "fileUrl": "<file_url>",
    "responseUrl": "<response_url>",
    "ecgChannelName": "ECG",
    "hardwareConfig" : { 
        "ecgLeadConfig": "UNKNOWN"
    }
}'
# Import packages
import requests
import json

# Define payload
payload = json.dumps({
    "fileUrl": "<file_url>",
    "responseUrl": "<response_url>",
    "ecgChannelName": "ECG",
    "hardwareConfig": { 
        "ecgLeadConfig": "UNKNOWN"
    }
})

# Send request
response = requests.post("<base_url>/<algorithm_name>/edf-file/download/webhook",
                         headers={"Authorization": "Bearer <access_token>", "Content-Type": "application/json"},
                         data=payload)

# Print response
response = print(response.text)

The EDF(+) File Download Webhook URL supports asynchronous requests via webhooks. This endpoint enables the downloading of ECG data stored in EDF or EDF+ files, accessible via direct download links, for algorithm analysis whilst allowing for responses to be delivered to a custom URL.

<base_url>/<algorithm_name>/edf-file/download/webhook

API Parameters

Although all HeartKey algorithms accept ECG data as an input, the outputs from each algorithm vary significantly due to differences in purpose and design. This variation is reflected in the respective request and response data types of each algorithm.

Each algorithm service is connected to multiple HTTP endpoints that accept POST requests. Together, these support varying input ECG formats and upload methods.

Global Request Parameters

When making a data-processing API request to HeartKey Rhythm, there are specific parameters within the request payload which must be configured correctly to prevent errors and ensure optimum algorithm performance. These parameters relate to the technical properties of the input ECG data and are detailed in the table below:

JSON Parameter Unit Data Type Acceptable Value Raw JSON Object Name Description
"dataFormat" N/A String "MILLIVOLTS", "COUNTS" or "UNKNOWN" "rawEcgSamples" Informs the library whether to treat provided ECG samples as millivolts ("MILLIVOLTS"), counts ("COUNTS") or unknowns ("UNKNOWN").
"data" Millivolts, Counts Array of doubles if expressed in voltage, or an array of int or uint values if expressed in counts Numerical values (size of values vary depending on ADC range if data is represented in counts) "rawEcgSamples" Raw ECG sample data for analysis. When processing counts data ("dataFormat": "COUNTS"), if any ECG counts samples are negative, the library will assume that all samples are signed. Otherwise, all samples will be assumed to be unsigned
"leadsOn" N/A Array of boolean values Numerical values of either 0 or 1 "rawEcgSamples" The electrode-contact status of sample readings (0 = Leads-Off, 1 = Leads-On). Recommended for optimal algorithm performance, but not essential
"ecgRangeMinUv" Microvolts Integer Numerical value ≥ -2000000 "hardwareConfig" The lower limit of the dynamic range relating to the input voltage at the ECG electrodes at a resolution of 1uV per bit. Only strictly necessary when processing data in counts ("dataFormat": "COUNTS"), but should always be included to guarantee optimal algorithm performance
"ecgRangeMaxUv" Microvolts Integer Numerical value ≤ 2000000 "hardwareConfig" The higher limit of the dynamic range relating to the input voltage at the ECG electrodes at a resolution of 1uV per bit. Only strictly necessary when processing data in counts ("dataFormat": "COUNTS"), but should always be included to guarantee optimal algorithm performance
"samplingFrequency" Hertz Integer 125 ≤ Numerical value ≤ 500 "hardwareConfig" The number of samples recorded per second at a resolution of 1Hz. Decimal values are not currently supported.
"ecgLeadConfig" N/A String "LEAD_I", "LEAD_II", "LEAD_III", "MLII", "MLIII", "STERNUM" or "UNKNOWN" (default) "hardwareConfig" The lead configuration used to acquire the input ECG data. Inclusion is optional, but recommended for achieving optimal algorithm performance. Arrhythmia Analysis only supports Lead II or Modified Lead II input ECG signals.
"adcRange" ADC Counts Integer 4096 (12-bit ADC) ≤ Numerical value ≤ 16777216 (24-bit ADC) "hardwareConfig" The range of signal amplitudes which the ADC can resolve at a resolution of 1 count. Only strictly necessary when processing data in counts ("dataFormat": "COUNTS").
"returnFormat" N/A Boolean 0 (default) or 1 N/A Whether the algorithm output should be returned in the response in a text (JSON) format or in the same file format as the request input ECG file (0 = JSON, 1 = Same File Format).
"responseIndexFormat" N/A String "TIME" (default), "SAMPLES" or "BOTH" "rawEcgSamples" The desired format of the timestamp/duration response outputs from the algorithm.
"responseTimeIndexUnit" N/A String "MILLISECONDS" (default) or "UTC" "rawEcgSamples" The desired unit of the timestamp response outputs from the algorithm. Only impactful when a time format is specified ("responseIndexFormat": "TIME" or "BOTH").
"recordingStartTime" N/A String Date and time in an ISO 8601 format ("YYYY-MM-DDTHH:mm:ss.sssZ") "rawEcgSamples" The starting time to which all response timestamp outputs from the algorithm will be calculated in relation to. Only impactful when a Coordinated Universal Time format is specified ("responseIndexFormat": "TIME" or "BOTH" and "responseTimeIndexUnit": "UTC")
"useExtendedClassifications N/A boolean true or false (default) N/A Whether extended rhythm classifications should be returned in response, Setting 'true' would send extended rhythm classifications

Algorithm-Specific Request Parameters

The HeartKey Rhythm Arrhythmia Analysis algorithm enables the user to set the threshold parameters for particular features. These parameters may be included within the request payload using a text (JSON) format:

JSON Parameter Unit Data Type Acceptable Value Raw JSON Object Name Description
"bradycardiaThreshold" BPM Integer 60, 55, 50 (default), 45, 40, 35 or 30 "rawEcgSamples" Threshold for defining bradycardia
"tachycardiaThreshold" BPM Integer 100 (default), 110, 120, 130, 140 or 150 "rawEcgSamples" Threshold for defining tachycardia
"absolutePauseThreshold" Seconds Float 1.5, 2.0, 2.5 (default), 3.0, 3.5, 4.0 or 4.5 "rawEcgSamples" Threshold for defining absolute pause
"relativePauseThreshold" BPM Integer 150, 175, 200 "rawEcgSamples" Threshold for defining relative pause

URL Request Parameters

As detailed in the Endpoint Types section, certain endpoints require additional URL parameters to be provided when making an API call. Depending on the endpoint type, one or both of the following parameters must be included within the request payload using a text (JSON) format:

JSON Parameter Data Type Acceptable Value Description
"fileUrl" String Download URL URL pointing to an ECG, CSV or EDF(+) file for downloading and processing. Only https URLs are permitted
"responseUrl" String Exposed URL URL pointing to a valid response delivery location. Only https URLs are permitted

Please refer to the Direct Download Links section for URL setup guidance.

File Request Parameters

HeartKey Rhythm can process input ECG data stored in a variety of file formats as explained in the Input ECG Formats section. Endpoints designed for processing certain file types require additional parameters to be included within the request payload in a text (JSON) format:

File Type JSON Parameter Data Type Acceptable Value Description
CSV "hasHeaders" String true or false Whether the CSV file for processing has a header row (true = header present, false = no header present)
CSV "ecgColumnIndex" Integer Numerical value The index of the column in the CSV file that contains ECG data for processing. Column numbering begins at 0.
CSV "leadsOnColumnIndex" Integer Numerical value The index of the column in the CSV file that contains leads-on data for processing. Column numbering begins at 0.
EDF(+) "ecgChannelName" String Any string Location of ECG signal within the EDF(+) file. A default value of "ECG" will be assumed if not provided.

Tutorials

Audit Logs

Format

Every request made to the application is logged in an audit log file. The following details are captured:

Getting the image from the artifact registry

Getting your image from the Google Artifact Registry differs slightly depending on whether you are signed up with a Google Cloud Platform (GCP) account.

With a GCP account

  1. Log into your GCP account and access the Google Artifact Registry - the URL will be provided directly by B-Secur.
  2. Using the docker pull command, pull the HeartKey Docker Image from the registry.

Without a GCP account

  1. Access and download the JSON authentication key from the following location. The "cus-num" value will be provided to you by B-Secur - https://console.cloud.google.com/storage/browser/cus-num
  2. Using your auth key, authenticate with Google Artifact Registry by using the Standalone Credential Helper.
  3. Using the docker pull command, pull the HeartKey Docker Image from the registry. The registry URL will be provided to you directly by B-Secur.

Cloud Deployment Options Guide

HeartKey Rhythm is a software library that is integrated into a wider software ecosystem. There are many deployment options; this section will provide an overview on how deploy software like HeartKey Rhythm on various cloud computing services like GCP, AWS, and Azure. This is not an exhaustive guide and you must consult the official documentation for your chosen cloud provider.

You are responsible for ensuring the full system meets its regulatory obligations.

Google Cloud Platform (GCP)

Google Cloud Platform (GCP) is a suite of cloud computing services provided by Google. It offers a wide range of cloud-based solutions for computing, storage, data analytics, machine learning.

Deploy using Cloud Run

Cloud Run is a managed compute platform that automatically scales containerized applications. You can deploy Docker containers as stateless HTTP services, and Cloud Run handles the scaling and traffic management.

Link to Google documentation for deploying using Cloud Run: Deploy Using Cloud Run

Deploy using Compute Engine

Compute Engine is a computing and hosting service that lets you create and run virtual machines on Google infrastructure. Compute Engine offers scale, performance, and value that lets you easily launch large compute clusters on Google's infrastructure.

Link to Google documentation for deploying VM’s: Deploy using Compute Engine

Deploy using GKE (Google Kubernetes Engine)

GKE is a managed Kubernetes service on GCP. You can create a Kubernetes cluster and deploy Docker containers directly into it. Kubernetes supports various container runtimes, including Docker.

Link to Google documentation for deploying: Deploy Using GKE

Amazon Web Services (AWS)

Amazon Web Services (AWS) is a comprehensive and widely used cloud computing platform provided by Amazon.com. AWS offers a vast array of cloud-based services, including computing power, storage, databases, machine learning, analytics, content delivery, and more. These services allow individuals and organizations to build, deploy, and scale applications and infrastructure without the need to invest in and manage physical hardware.

Deploy using Amazon ECS

Amazon Elastic Container Service (ECS) allows you to deploy and manage Docker containers on EC2 instances. You can create task definitions and services to specify how your containers should run.

Link to AWS documentation: Deploy using ECS

Guidelines to deploy a docker image obtained from B-Secur using Amazon ECS

Deploy using Amazon EKS (Elastic Kubernetes Service)

EKS is a managed Kubernetes service on AWS. You can create a Kubernetes cluster and deploy Docker containers directly into it. Kubernetes supports various container runtimes, including Docker.

Link to AWS Documentation: Deploy using EKS

Deploy using ECR

Pushing an image

You can use the AWS Command Line Interface (CLI) or Docker CLI to push your Docker images to ECR.

Link to AWS Documentation: Push an image to ECR

Integration with ECS and EKS

ECR is tightly integrated with Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS), making it a popular choice for container deployments on AWS.

Link to AWS Documentation to host images using ECS: Integration using ECS

Link to AWS Documentation to host images using EKS: Integration using EKS

Deploy Using AWS Lambda

AWS Lambda is a serverless computing service provided by Amazon Web Services (AWS). It lets you run your code without provisioning or managing servers. AWS Lambda automatically handles the compute fleet that runs your code.

Link to AWS Documentation to host images as Lambda: Deploy to AWS Lambda

Azure

Azure, also known as Microsoft Azure, is a comprehensive and widely used cloud computing platform and service provided by Microsoft. Azure offers a broad set of cloud-based services that include computing, analytics, storage, databases, networking, artificial intelligence (AI), Internet of Things (IoT), and more. These services enable individuals and organizations to build, deploy, and manage applications and infrastructure in the cloud.

Deploy using Azure AKS

Azure Kubernetes Service is a managed Kubernetes service that simplifies deploying, managing, and scaling containerized applications using Kubernetes.

Link to Azure documentation: Deploy using AKS

Deploy using Azure ACI

Azure Container Instances is a serverless container service that allows you to deploy Docker containers quickly without managing underlying infrastructure. You can create containers using the Azure CLI, Azure PowerShell, or Azure Portal.

Link to Azure Documentation: Deploy using ACI

Deploy Using Azure Functions

Azure Functions is a serverless compute service provided by Microsoft Azure, allowing you to run event-triggered code without explicitly provisioning or managing infrastructure.

Link to Azure Documentation: Deploy to Azure Function

Cloud Application Deployment Guide - Kubernetes

This section provides a more specific example workflow on how to deploy HeartKey Rhythm using Kubernetes. Kubernetes is a container orchestration service that handles the automatic deployment, configuration, and scaling of software containers. These platforms provide many configuration options, and you should consult the documentation to select the most appropriate option for your use case and product.

Step 1: Create a Kubernetes Cluster

In this example, we will use a Kubernetes environment. Kubernetes makes building and running complex applications much simpler. Other options are available, as mentioned in the section above. Each provider offers managed Kubernetes services:

AWS Elastic Kubernetes Service (EKS)

AWS's managed Kubernetes service. For creating clusters, use the AWS Management Console or the eksctl CLI tool. See AWS EKS Documentation.

Google Kubernetes Engine (GKE)

GCP's managed Kubernetes service. Clusters can be created using the GCP Console or the gcloud CLI tool. See GKE Documentation.

Azure Kubernetes Service (AKS):

Azure's managed Kubernetes service. Use the Azure portal or the az CLI tool for cluster creation. See AKS Documentation.

Step 2: Configure Cluster Security and Networking

Next you should configure your cluster for enhanced security and network isolation. Before starting, you should consider using service accounts and leveraging cloud-specific IAM (Identity and Access Management) roles with Principle of Least Privilege. The following links provide some further guidance on doing this within AWS / GCP / Azure:

It's recommended you enable private clusters; this will restrict public internet access, reducing the ability for opportunistic attacks. The following links provide further information for the cloud providers:

Finally, you should implement appropriate network policies for internal traffic within the cluster. This can help decouple and restrict the impact of a single service e.g. if one service starts to take too much resource, or if an attacker gains access to one of the services. The following links provide further information for the cloud providers:

Step 3: Deploy and Manage Applications

In order to store and manage Docker images securely, we will need to make use of a container registry. This is not a necessity, but recommended.

The application can be deployed on Kubernetes using Kubernetes Deployments. If you want to know more about this, you can visit this link explaining Kubernetes Workloads.

The applications will be exposed through Kubernetes Services and Ingresses; it is recommended to use ClusterIP service type for internal cluster communication and Ingress for external communication. You may consider using a cloud-managed API Gateway for advanced traffic routing and security. Click here if you want to read about Kubernetes Networking.

Step 4: Data Integrity

Secure Communications

It is essential that SSL/TLS certificate services are leveraged with upto date SSL Policies (TLS versions 1.2 or 1.3) to secure traffic in transit i.e. Encryption in Flight via HTTPS. See the appropriate link for your cloud provider below.

It is also recommended to use encryption in flight for internal cluster traffic. Please refer to the corresponding Cloud Provider documentation for detail:

Authentication and Authorisation

It is advised that you secure any exposing endpoints using OAuth 2.0 to add appropriate authentication and access control.

You may want to make use of identity providers to manage those users when using OAuth 2.0, here are examples of those within your selected cloud provider.

Step 5: Monitoring and Observability

It is important to closely monitor the cluster to ensure it functions effectively and meets expectations. This involves regularly reviewing and analyzing data, either in real-time or at predetermined intervals, to detect anomalies and assess system performance

Enabling logging is essential, as it assists developers and administrators in monitoring system behavior. This functionality is crucial for identifying and resolving potential issues or errors, and for gaining insights into system performance and usage

Let's have a look at how we can set up logging in your selected cloud provider.

Cybersecurity Controls

HeartKey is intended to be integrated into other Rhythm systems as a library; many cybersecurity measures and controls occur in separate modules outside the library and are the responsibility of the system owner. The Cybersecurity Controls section of the "B012-009-002 Draft Physicians Guide" document outlines some considerations the system owner should take when integrating HeartKey Rhythm to ensure the safety of their patients and their product. If you have not received this document, please contact either your B-Secur representative or the B-Secur customer support team at: support@b-secur.com

The user shall store tokens in a secure location.

Internal APIs are hidden and obfuscated. Only public APIs are available to be viewed.

In the event of detecting an incident, including cybersecurity incidents, relating to HeartKey Rhythm, please notify B-Secur as soon as possible via support@b-secur.com.

Caution :

Cloud providers offer various security measures to protect the integrity of the deployed environments against numerous threats. However, these tools alone are insufficient for establishing a comprehensive secure system. We strongly recommend that you and your organization consult the FDA's extensive guidelines on cybersecurity to enhance system security. Familiarize yourself with these guidelines at the FDA’s Digital Health Center of Excellence here.

AWS

GCP

Azure

Third party Antivirus and Malware Protection

Integrating third-party antivirus protection with Kubernetes services enhances security measures by introducing an additional layer of defence against malware and cyber threats. These solutions extend malware detection capabilities through advanced security features, essential for detecting and mitigating sophisticated threats. Furthermore, they facilitate the enforcement of uniform security policies across multi-cloud configurations, ensuring comprehensive protection.

When deploying, it's important to choose solutions that are designed for containerised environments and are frequently updated to defend against the latest security threats. It is also recommended to use solutions with centralised management console to monitor and manage alerts across all clusters effectively.

There are many third party tools available. An example of two that can be used are:

Microsoft Defender

Microsoft Defender for cloud

Microsoft Defender for Cloud is a cloud-native application protection platform (CNAPP) that is made up of security measures and practices that are designed to protect cloud-based applications from various cyber threats and vulnerabilities.

To deploy: - AWS: Connect your AWS account to Microsoft Defender for Cloud - Azure: Connect your Azure subscriptions - GCP: Connect your GCP project to Microsoft Defender for Cloud

Rapid7 InsightCloudSec

Rapid7 InsightCloudSec

InsightCloudSec is a fully-integrated cloud-native security platform CNAPP (Cloud Native Application Protection Platform). Helps teams protect even the most complex multi-cloud and container environments from misconfiguration, policy violations, threats, and identity and access management (IAM) challenges.

To deploy you can follow through the following start guide: - InsightCloudSec start guide

By adding an extra layer of defence, third-party antivirus tools not only complement the built-in security measures of cloud providers but also offer options to meet specific organisational needs, making them an invaluable part of a cyber-security strategy.

It is possible to implement a multi-cloud failover strategy, this can further enhance the systems resilience against cyber threats and infrastructure failures. This involves integrating cloud services from multiple providers to create a redundant system where, in the event of a failure or security breach in one cloud environment, the system can automatically failover to another cloud environment. This approach requires careful planning and synchronisation of data and services across cloud platforms which is beyond the scope of this integration guide. If you are interested, please feel free to read this example.

Anti-virus policy

No issues are known regarding the compatibility between HeartKey and Anti-virus software.

B-Secur recommends to use an up-to-date anti-virus software on the device where HeartKey is installed. B-Secur also recommends to activate real time protection and to perform periodically definition update and scans when the system is not actively in use.

Phishing Guidance

Phishing is the practice of sending fraudulent communications that appear to come from a legitimate and reputable source, typically through email and text messaging. Its aim is to steal money, access sensitive data and login information, or install malware on the victim's device.

B-Secur recommends several best practices to help customers avoid phishing attempts:

These practices are crucial for safeguarding against phishing attacks and maintaining the security of systems where HeartKey is utilized.

Disclaimer

This library is not for public use. This is for Authorised Client use only. This library is designed to run on the client infrastructure only, and needs to be secured via the most appropriate means.

Containerising The HeartKey Executable

The HeartKey executable can be containerised using various containerisation tools such as Docker, Kubernetes, OpenShift, and more. The example below demonstrates the process of containerisation using Docker.

Build A Docker Image

From the HeartKey Rhythm application root folder, run this command to build a Docker image containing the HeartKey executable using dockerfile located at 'dockerFileLocation'.
docker build -f <dockerFileLocation> --build-arg <variable-name> = {heartkeyExecutable} -t {name}:{tag}

The docker build command is used to create a Docker image from a Dockerfile, which is a script-like configuration file that defines the steps and instructions to build an image.

Let's assume that HeartKey Rhythm executable named heartkey-rhythm lies in target /heartkey-rhythm and Docker file lies in target/DockerFile, docker build command looks like

docker build -f target\DockerFile --build-arg APP_FILE =./target/heartkey-rhythm -t heartkey:v1

A docker image will be created with name and tag heartkey:v1

Query A Docker Image

The newly built docker image can be verified using the below command: docker images

The docker images command is used to list the Docker images that are available on your local system. When you run this command in your terminal, it will display a list of images along with their repository name, tag, image ID, creation date, and size. This information provides an overview of the images you have pulled or built on your system.

An example of the output of this command is captured below:

REPOSITORY TAG IMAGE ID CREATED SIZE
heartkey v1 abcdef123456 2 hours ago 64.2MB
nginx 1.21.1 789xyz456789 3 days ago 133MB

Run A Docker Image

The docker run command can be used to create and start a new Docker container based on a specified image.

docker run --name <container-name> -d -p <host_port>:<container_port> {dockerImageName}:{tag}

If the user wants to create a docker container with the name heartkey-rhythm and assigning host port and container port as 8080, the following command should be run:

docker run --name heartkey-rhythm -d -p 8080:8080 heartkey:v1

This will create a docker container named heartkey-rhythm exposed on port 8080 and the application endpoints can be accessed from port 8080.

Accessing Endpoints

Endpoints can be accessed through the curl command:

Curl [endpoint]

Once the Docker image is running, we can now access the HeartKey Rhythm endpoints. The following examples are assuming they are running at localhost and port 8080. These should be adjusted based on the specific settings you've chosen.

To access HeartKey Rhythm Services, users must be authorised by generating a token using their HeartKey Rhythm username and password. Tokens can be generated through the User Management service.

To retrieve Arrhythmia Analysis information from a .edf file, we can provide a .edf file to the following endpoint:

curl -X POST -F 'file=@path/to/your/file' http://localhost:8080/api/arrhythmia-analysis/edf-file

To retrieve Signal Quality information from a .csv file located at a specific URL we can provide the URL along with the hardware configuration to the following endpoint:

curl -X POST --data 'key=value' http://localhost:8080/api/signal-quality/csv-file/download

In a similar way other endpoints can be accessed by providing relevant data.

Docker File

A Dockerfile is a text file that contains instructions for building a Docker image. It defines the steps needed to create a reproducible and self-contained environment for running an application or service inside a Docker container. Dockerfiles are used with the docker build command to create images that can then be used to run containers.

Basic Structure: FROM {base_image}:{tag} ARG variable_name EXPOSE port_number COPY ${variable_name} app ENTRYPOINT ["executable", “param”]

The provided example Dockerfile has an APP_FILE variable which is used to get a HeartKey Rhythm executable through the docker build command and can be used in the subsequent steps to build the image.

FROM gcr.io/distroless/base  
ARG APP_FILE  
EXPOSE 8080  
COPY target/${APP_FILE} app  
ENTRYPOINT ["/app"]  

Integration Test

Following the integration of HeartKey Rhythm, the system's functionality and operational status can be verified by accessing the health check and version endpoints.

Test 1 : Health Check

A health check is used to monitor and verify the status and overall health of an application.

GET Request:
http://[host]:[port]/

Expected Response:

Signal Processing health check good

Example Request :

curl --location http://[host]:[port]/

Test 2 : Version

Version Endpoint returns the integrated HeartKey Rhythm Version which can be used to confirm the successful integration of the product

GET Request:
http://[host]:[port]/api/version

Expected Response:

4.3.0

Example Request :

curl --location 'http://[host]:[port]/api/version' \
--header 'Authorization: Bearer [token]'

Post Integration Test

Signal Processing Engine

To verify that the signal-processing engine returns the expected results, run the following requests using the attached sample data. The expected response is also provided for comparison.

Test 1 : Raw Data Request

POST Request:
http://[host]:[port]/api/signal-processing-engine

Sample Raw Signal data input:
Raw Signal Input

Expected Response :

Signal Processing Response

Example Request :

curl --location 'http://[host]:[port]/api/signal-processing-engine' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer [token]' \
--data '[raw-signal-input]'

Test 2 : CSV File Request

POST Request:
http://[host]:[port]/api/signal-processing-engine/csv-file

Sample CSV File :
CSV File

Request Config : Use attached request config json

{
  "hardwareConfig": {
    "ecgRangeMinUv": -32767,
    "ecgRangeMaxUv": 32767,
    "samplingFrequency": 500,
    "adcRange": 65536,
    "ecgLeadConfig": "LEAD_I"
  },
  "hasHeaders": true,
  "returnFormat": 0,
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0
}

Expected Response :
Signal Processing Response

Example Request :

curl --location 'http://[host]:[port]/api/signal-processing-engine/csv-file' \
--header 'Authorization: Bearer [token]' \
--form 'file=@"[csv-file-path]"' \
--form 'config="{
\"hardwareConfig\": {
\"ecgRangeMinUv\": -32767,
\"ecgRangeMaxUv\": 32767,
\"samplingFrequency\": 500,
\"adcRange\": 65536,
\"ecgLeadConfig\": \"LEAD_I\"
},
\"hasHeaders\": true,
\"returnFormat\": 0,
\"dataFormat\": \"MILLIVOLTS\",
\"ecgColumnIndex\": 0
}";type=application/json'

Test 3 : EDF File Request

POST Request:
http://[host]:[port]/api/signal-processing-engine/edf-file

Sample EDF File :
EDF File

Request Config : Use attached request config json

{
  "hardwareConfig": {
    "ecgLeadConfig": "LEAD_I"
  },
  "returnFormat": 0,
  "ecgChannelName": "ecgChannelName"
}

Expected Response :
Signal Processing Response

Example Request :

curl --location 'http://[host]:[port]/api/signal-processing-engine/edf-file' \
--header 'Authorization: Bearer [token]' \
--form 'file=@"[edf-file-path]"' \
--form 'config="{
  \"hardwareConfig\": {
    \"ecgLeadConfig\": \"LEAD_I\"
  },
  \"returnFormat\": 0,
  \"ecgChannelName\": \"ecgChannelName\"
}";type=application/json'

Arrhythmia Analysis

To verify that the arrhythmia-analysis returns the expected results, run the following requests using the attached sample data. The expected response is also provided for comparison.

Test 1 : Raw Data Request

POST Request:
http://[host]:[port]/api/api/arrhythmia-analysis

Sample Raw Signal data input:
Raw Signal Input

Expected Response :
Arrhythmia Analysis Response

Example Request :

curl --location 'http://[host]:[port]/api/arrhythmia-analysis' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer [token]' \
--data '[raw-signal-input]'

Test 2 : CSV File Request

POST Request:
http://[host]:[port]/api/arrhythmia-analysis/csv-file

Sample CSV File :
CSV File

Request Config : Use attached request config json

{
  "hardwareConfig": {
    "ecgRangeMinUv": -32768,
    "ecgRangeMaxUv": 32768,
    "samplingFrequency": 500,
    "adcRange": 65536,
    "ecgLeadConfig": "LEAD_II"
  },
  "hasHeaders": true,
  "returnFormat": 0,
  "dataFormat": "MILLIVOLTS",
  "ecgColumnIndex": 0,
  "responseIndexFormat": "BOTH",
  "bradycardiaThreshold": 50,
  "tachycardiaThreshold": 100,
  "absolutePauseThreshold": 2.5,
  "relativePauseThreshold": 200
}

Expected Response :
Arrhythmia Analysis Response

Example Request :

curl --location 'http://[host]:[port]/api/arrhythmia-analysis/csv-file' \
--header 'Authorization: Bearer [token]' \
--form 'file=@"[csv-file-path]"' \
--form 'config="{
  \"hardwareConfig\": {
    \"ecgRangeMinUv\": -32768,
    \"ecgRangeMaxUv\": 32768,
    \"samplingFrequency\": 500,
    \"adcRange\": 65536,
    \"ecgLeadConfig\": \"LEAD_II\"
  },
  \"hasHeaders\": true,
  \"returnFormat\": 0,
  \"dataFormat\": \"MILLIVOLTS\",
  \"ecgColumnIndex\": 0,
  \"responseIndexFormat\": \"BOTH\",
  \"bradycardiaThreshold\": 50,
  \"tachycardiaThreshold\": 100,
  \"absolutePauseThreshold\": 2.5,
  \"relativePauseThreshold\": 200
}";type=application/json'

Test 3 : EDF File Request

POST Request:
http://[host]:[port]/api/arrhythmia-analysis/edf-file

Sample EDF File :
EDF File

Request Config : Use attached request config json

{
  "hardwareConfig": {
    "ecgLeadConfig": "LEAD_II"
  },
  "returnFormat": 0,
  "ecgChannelName": "ecgChannelName",
  "bradycardiaThreshold": 50,
  "tachycardiaThreshold": 100,
  "absolutePauseThreshold": 2.5,
  "relativePauseThreshold": 200
}

Expected Response :
Arrhythmia Analysis Response

Example Request :

curl --location 'http://[host]:[port]/api/arrhythmia-analysis/edf-file' \
--header 'Authorization: Bearer [token]' \
--form 'file=@"[edf-file-path]"' \
--form 'config="{
  \"hardwareConfig\": {
    \"ecgLeadConfig\": \"LEAD_II\"
  },
  \"returnFormat\": 0,
  \"ecgChannelName\": \"ecgChannelName\",
  \"bradycardiaThreshold\": 50,
  \"tachycardiaThreshold\": 100,
  \"absolutePauseThreshold\": 2.5,
  \"relativePauseThreshold\": 200
}";type=application/json'

Integration Test Results

Integration Test Completion Form

Customer:_______________________________________________

Project:_______________________________________________

Date of Completion:_______________________________________________

Integration Test Results

Complete the Result column with 'Pass', 'Fail' or 'Not Tested' for each test to indicate the result.

Test ID Test Name Result Comments
1 Health Check
2 Version Check

Post-Integration Test Results

Complete the Result column with 'Pass', 'Fail' or 'Not Tested' for each test to indicate the result. Some of these tests may not be completed if the applicable feature is not present in a particular variant of the HeartKey Rhythm.

Signal Processing Engine

Test ID Test Name Result Comments
1 Raw Data Request
2 CSV File Request
3 EDF File Request

Arrhythmia Analysis

Test ID Test Name Result Comments
1 Raw Data Request
2 CSV File Request
3 EDF File Request

Signature

Name:_______________________________________________

Date:_______________________________________________

Job Title:_______________________________________________

Signature:_______________________________________________

Support

ECG Range Calculations

What are the hardware configuration settings and why are they necessary?

The Hardware Configuration information refers to the settings of the ECG acquisition device used to capture the ECG data. Such information includes the ECG data sampling frequency, the ADC range, minimum ECG range, maximum ECG range and lead configuration. It is mandatory to enter accurate values for each field in the hardware configuration data structure in order to configure the HeartKey ECG library correctly for the specific application hardware. Failure to do so may result in degraded performance.

What calculations are required to calculate the dynamic range of the input ECG voltage across the electrodes?

Dynamic Range Calculation Example

    # Define Parameters
    ADC Reference Voltage Range = 0 to 3V
    Voltage Gain = 100
    adcRange = 65536 counts

    # Calculate Dynamic Range
    Dynamic Range = (Upper Limit Of ADC Reference Voltage Range - Lower Limit Of ADC Reference Voltage Range) / Voltage Gain
    Dynamic Range = (3-0)/100
    Dynamic Range = 0.03 V

    # Convert Dynamic Range Voltage to Microvolts
    Dynamic Range Microvolts = Dynamic Range Voltage * 1000000
    Dynamic Range Microvolts = 0.03 * 1000000
    Dynamic Range Voltage = 30000 μV

    # Determine ecgRangeMaxUv
    ecgRangeMaxUv = 15000 μV

    # Determine ecgRangeMinUv
    ecgRangeMinUv = -15000 μV

The dynamic range of the input voltage at the ECG electrodes can be calculated by dividing the voltage range of the ADC reference in the hardware by the voltage gain applied to the signal.

As in the adjacent example, if an ADC reference voltage range of 0 to 3V is applied while using a voltage gain of 100, then the dynamic range of the input voltage at the ECG electrodes is (3-0)/100 = 30,000μV. Based on this value, the "ecgRangeMinUv" and "ecgRangeMaxUv" request parameters in the can be set to -15,000μV and 15,000μV respectively.

Change Log

ADF MS

[4.3.0] - 2025-05-20

Added

Fixed

[4.2.0] - 2025-02-13

Added

Fixed

[4.1.0] - 2024-11-07

Changed

Added

Removed

Fixed

[4.0.0] - 2024-07-12

Added

Changed

Fixed

[3.3.0] - 2023-11-08

Added

Changed

[3.2.0] - 2023-11-07

Added

[3.1.0] - 2023-10-25

Added

[3.0.0] - 2023-10-16

Added

[2.3.1] - 2023-07-16

Changed

[2.2.1] - 2023-06-06

Fixed

[2.2.0] - 2023-05-26

Added

[2.1.0] - 2023-05-04

Added

[2.0.0] - 2023-04-20

Added

Changed

[1.1.0] - 2023-07-05

Added

[1.0.1] - 2023-04-05

Changed

[1-0-0] - 2023-03-14

Added

Changed