Introduction
Welcome! On this page you can learn how to use the Pylo API and webhooks.
Here is a summary of the services we offer:
Devices Service: API service where you can get information about devices currently possessed by your company.
Readings Service: API service where you can get device measurement readings.
Fulfillment Service: API service where you can place orders and get order status.
Webhooks: Webhooks enable you to subscribe your application to our system so that it can be notified when new measurement readings have been received.
You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. If you do not see your programming language of choice, please let us know and we will add examples for it.
API Setup and General Usage
Authentication
Please review the following authentication information before using any of the services listed in this documentation.
To authorize, use this code:
# Set your api in the request header as shown below:
headers = {
'x-api-key': 'your-api-key'
}
# With shell, you can just pass the correct header with each request
curl -X GET 'https://api.pylo.com/orders' \
-H 'x-api-key: your-api-key'
Make sure to replace
your-api-key
with your API key.
The Pylo API uses API keys to allow access to the API. You can register a new Pylo API key at our developer portal.
Pylo expects for the API key to be included in all API requests to the server in a header that looks like the following:
'x-api-key': 'your-api-key'
Pagination
import requests
headers = {
'x-api-key': 'your-api-key'
}
payload = {
'cursor': None
}
# Get first page
response = requests.get('https://api.pylo.com/devices', headers=headers).json()
payload['cursor'] = response['page_info']['cursor_token'] # Store for next page
# Do stuff with this page of items
print(response)
# Get subsequent pages
while payload['cursor'] is not None:
response = requests.get('https://api.pylo.com/devices', headers=headers, params=payload).json()
payload['cursor'] = response['page_info']['cursor_token'] # Store for next page
# Do stuff with this page of items
print(response)
Some resources may return a large response, so we employ the use of pagination in these cases. Usage is simple and does not require you to keep track of pages. How it works is with each response there is a "cursor_token". This cursor signifies where in your response we last left off. If the cursor_token is ever null, there are no more items to fetch. In other words, while there is a token_cursor in the response, there are additional pages to be fetched; get the next page by including the cursor_token in your next request.
An example of the business logic for getting all items is shown on the right.
Devices Service
The Devices resource enables you to get information about your company's devices. This is a suggested starting place if you haven't yet mapped device identifiers to your patients.
Get All Devices
You can get information about all of your company's devices by sending a
GET request to:
https://api.pylo.com/devices
A limit of 1000 devices will be returned per request. If there are more than 1000 devices, a "cursor_token" will be returned. If you would like to get the next 1000 devices, supply the cursor token as a query parameter. See Pagination for more information.
HTTP Request
GET https://api.pylo.com/devices
GET https://api.pylo.com/devices?cursor=YOUR_TOKEN
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
payload = {
'cursor': None
}
# Get first page
response = requests.get('https://api.pylo.com/devices', headers=headers).json()
payload['cursor'] = response['page_info']['cursor_token'] # Store for next page
# Do stuff with this page of items
print(response)
# Get subsequent pages
while payload['cursor'] is not None:
response = requests.get('https://api.pylo.com/devices', headers=headers, params=payload).json()
payload['cursor'] = response['page_info']['cursor_token'] # Store for next page
# Do stuff with this page of items
print(response)
curl -X GET 'https://api.pylo.com/devices' \
-H 'x-api-key: your-api-key'
The following optional parameter should be supplied in the query parameters if using pagination.
Query String Parameter | Type | Description |
---|---|---|
cursor_token | string | The token returned from the previous page. Supply this token in another request to get the subsequent page. See Pagination for more information. |
Response Body
The above command returns all devices possessed by your company in an array of JSONs structured like this:
{
"count": 100,
"devices": [
{
"device_imei": "imei1",
"device_sim": "sim1",
"device_id": "id1",
"device_type": "type1",
"patient_id": "patient_id1",
"practice_id": "practice_id1",
"billing_status": "active",
"first_measurement_timestamp": "timestamp_1",
"last_measurement_timestamp": "timestamp_2",
"order_number": "order1",
},
{
"device_imei": "imei2",
"device_sim": "sim2",
"device_id": "id2",
"device_type": "type2",
"patient_id": "patient_id2",
"practice_id": "practice_id2",
"billing_status": "preactive",
"first_measurement_timestamp": "timestamp_3",
"last_measurement_timestamp": "timestamp_4",
"order_number": "order1",
},
{
...
},
{
"device_imei": "imei50",
"device_sim": "sim50",
"device_id": "id50",
"device_type": "type50",
"patient_id": "patient_id50",
"practice_id": "practice_id50",
"billing_status": "suspended",
"first_measurement_timestamp": "timestamp_5",
"last_measurement_timestamp": "timestamp_6",
"order_number": "order1",
},
],
"page_info": {
"cursor_token": "Y3VycmVudF9jdXJzb3JfcG9zaXRpb24x=="
}
}
Name | Type | Description |
---|---|---|
count | number | The number of returned devices |
devices | object[] | List of devices possessed by your company. |
devices[x].device_imei | string | The IMEI for this device. |
devices[x].device_sim | string | The SIM corresponding for this device. |
devices[x].device_id | string | The device ID for this device. |
devices[x].device_type | string | The device type for this device. |
devices[x].patient_id | string | The patient ID that this device is currently mapped to. Empty if no patient_id supplied upon ordering. |
devices[x].practice_id | string | The practice ID that this device is currently mapped to. |
devices[x].billing_status | string | The billing status for this device. |
devices[x].first_measurement_timestamp | string | The timestamp of the first measurement received from this device. |
devices[x].last_measurement_timestamp | string | The timestamp of the most recent measurement received from this device. |
devices[x].order_number | string | The order number for this device. Empty if device not ordered through pylo api. |
page_info | object | Information about the response; used for pagination. |
page_info.cursor_token | string | The token signifying where in the response the cursor left off. Supply this token in another request to get the subsequent page. See Pagination for more information. |
Get Specific Device
Supply either device_id or imei to get information about that particular device.
HTTP Request
GET https://api.pylo.com/devices?id=DEVICE_ID
GET https://api.pylo.com/devices?imei=IMEI
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
payload = {
'id': 'deviceid123'
}
response = requests.get('https://api.pylo.com/devices', headers=headers)
curl -X GET 'https://api.pylo.com/devices?id=deviceid123' \
-H 'x-api-key: your-api-key'
Supply exactly one of the following parameters to get information about a specific device.
Query String Parameter | Type | Description |
---|---|---|
id | string | The device_id corresponding to the device about which you seek information. |
imei | string | The imei corresponding to the device about which you seek information. |
Response Body
The above command returns information about the device corresponding to the query string parameter you provided in JSON structured like this:
{
"device_imei": "imei123",
"device_sim": "sim123",
"device_id": "id123",
"device_type": "type123",
"patient_id": "patient_id123",
"practice_id": "practice_id123",
"billing_status": "active",
"first_measurement_timestamp": "timestamp_123",
"last_measurement_timestamp": "timestamp_456",
"order_number": "order1",
}
Name | Type | Description |
---|---|---|
device_imei | string | The IMEI for this device. |
device_sim | string | The SIM corresponding for this device. |
device_id | string | The device ID for this device. |
device_type | string | The device type for this device. |
patient_id | string | The patient ID that this device is currently mapped to. Empty if no patient_id supplied upon ordering. |
practice_id | string | The practice ID that this device is currently mapped to. |
billing_status | string | The billing status for this device. |
first_measurement_timestamp | string | The timestamp of the first measurement received from this device. |
last_measurement_timestamp | string | The timestamp of the most recent measurement received from this device. |
order_number | string | The order number for this device. |
Update Device
Supply either device_id or imei to update the patient id or practice id on the particular device.
HTTP Request
PUT https://api.pylo.com/devices?id=DEVICE_ID
PUT https://api.pylo.com/devices?imei=IMEI
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
body = {
'patient_id': 'patient_id123',
'practice_id': 'practice_id123',
}
requests.put(
'https://api.pylo.com/devices?id=deviceid123'
json=body,
headers=headers
).json()
curl -d '{"patient_id": "patient_id123", "practice_id": "practice_id123"}' \
-X PUT 'https://api.pylo.com/devices?id=deviceid123' \
-H 'x-api-key: your-api-key'
These parameters should be supplied in request body. At least one parameter is required.
Data (JSON) | Type | Description | Default |
---|---|---|---|
patient_id | string | The patient identifier you provide to overwrite the existing patient id. | 0 |
practice_id | string | The practice identifier you provide to overwrite the existing practice id. | 0 |
Response Body
The above command returns a 200 with a patient id if the patient id was updated successfully, or an error code otherwise.
{
"status": "OK",
"patient_id": "patient_id123",
"practice_id": "practice_id123",
}
Name | Type | Description |
---|---|---|
status | string | The status code of the response. "OK" if patient id updated successfully. |
patient_id | string | The up-to-date patient id will be returned. |
practice_id | string | The up-to-date practice id will be returned. |
Readings Service
The Readings resource enables you to query device readings using a combination of filters. Filters are defined in the data of a POST request. Filter options are set forth below.
Note: This endpoint retrieves all measurements taken on your company's member devices which satisfy all of the filter parameters provided in your request (logical AND).
A limit of 1000 measurement readings will be returned per request. If there are more than 1000 readings, a "cursor_token" will be returned. If you would like to get the next 1000 measurements, supply the cursor token as a query parameter. See Pagination for more information.
Unique Identifiers for Queries
- Devices can be uniquely identified by imei or device_id, whichever is available for that device.
- Patients can be uniquely identified by patient_id.
- Readings can be uniquely identified by reading_id.
HTTP Request
POST https://api.pylo.com/readings
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
filters = {
'imei': 'imei1',
'measurement_taken_start_date': '2021-02-21T23:12:00.000Z'
}
requests.post(
'https://api.pylo.com/readings'
json=filters,
headers=headers
).json()
curl -d '{"imei": "imei1"}' \
-X POST 'https://api.pylo.com/readings' \
-H 'x-api-key: your-api-key'
The following optional query string parameter should be supplied if using pagination.
Query String Parameter | Type | Description |
---|---|---|
cursor_token | string | The token returned from the previous page. Supply this token in another request to get the subsequent page. See Pagination for more information. |
These parameters should be supplied in the request body. At least one parameter is required.
Data (JSON) | Type | Description |
---|---|---|
reading_id | string | Only the measurement with this ID will be returned. |
imei | string | Only measurements taken by the device with this IMEI will be returned. |
patient_id | string | Only measurements taken by this patient will be returned. |
device_id | string | Only measurements taken by the device with this device ID will be returned. |
reading_type | string | Only measurements of this reading type will be returned. |
measurement_taken_start_date | string | Results will only include measurements taken between this date end end date. Specify datetime in ISO 8601 format in UTC (e.g., 2021-02-21T23:12:00.000Z). |
measurement_taken_end_date | string | Similar to measurement_taken_start_date, but end of range. Specify datetime in ISO 8601 format in UTC (e.g., 2021-02-21T23:12:00.000Z). |
Response Body
The above command returns all measurements which satisfy all the filter requirements in an array of JSONs structured like this:
{
"count": 2,
"measurements": [
{
"DeviceUser": "1",
"MeasurementType": "Blood Pressure",
"DeviceId": "deviceid1",
"MeasuredAt": "2021-02-23T22:06:00.000Z",
"BatteryPercentage": 58,
"DeviceModel": "PY-802-LTE",
"DeviceType": "PyloBp",
"InsertedAt": "2021-02-23T22:06:00.000Z",
"DeviceSim": "sim1",
"Id": "id3",
"DeviceImei": "imei1",
"SignalStrengthPercentage": 94,
"PatientId": "patient_id1",
"PracticeId": "practice_id1",
"TenantId": "tenant_id1",
"Values": [
{
"Value": 84,
"Type": "diastolic"
},
{
"Value": 129,
"Type": "systolic"
},
{
"Value": 62,
"Type": "pulse"
},
{
"Value": 0,
"Type": "irregular"
}
],
"RadioAccessTechnology": "radio_access_tech_1",
"NetworkName": "network_1",
"TowerLongitude": "longitude_1",
"TowerLatitude": "latitude_1",
},
{
"DeviceUser": "1",
"MeasurementType": "Blood Pressure",
"DeviceId": "deviceid1",
"MeasuredAt": "2021-02-25T22:06:00.000Z",
"BatteryPercentage": 56,
"DeviceModel": "PY-802-LTE",
"DeviceType": "PyloBp",
"InsertedAt": "2021-02-25T22:06:00.000Z",
"DeviceSim": "sim1",
"Id": "id1",
"DeviceImei": "imei1",
"SignalStrengthPercentage": 75,
"PatientId": "patient_id1",
"PracticeId": "practice_id1",
"TenantId": "tenant_id1",
"Values": [
{
"Value": 77,
"Type": "diastolic"
},
{
"Value": 133,
"Type": "systolic"
},
{
"Value": 66,
"Type": "pulse"
},
{
"Value": 0,
"Type": "irregular"
}
],
"RadioAccessTechnology": "radio_access_tech_1",
"NetworkName": "network_1",
"TowerLongitude": "longitude_2",
"TowerLatitude": "latitude_2",
}
],
"page_info": {
"cursor_token": "Y3VycmVudF9jdXJzb3JfcG9zaXRpb24x=="
}
}
Name | Type | Description |
---|---|---|
count | number | The number of returned measurements |
Measurements | object[] | List of measurements found based on the search criteria. |
Measurements[x].DeviceUser | string | The user of the device for this measurement (will always be 1 for devices without switchable user profiles). |
Measurements[x].MeasurementType | string | Either "Weight" or "Blood Pressure". |
Measurements[x].DeviceId | string | The serial number of the device. |
Measurements[x].MeasuredAt | string | The ISO timestamp for when the measurement was recorded. |
Measurements[x].BatteryPercentage | number | The percentage of battery that remains on the device. |
Measurements[x].DeviceModel | string | The model number of the device. |
Measurements[x].DeviceType | string | The type/brand of the device (e.g., PyloBp, PyloWt, etc.) |
Measurements[x].InsertedAt | string | The time at which the measurement was inserted into our database. |
Measurements[x].DeviceSim | string | The ICCID of the SIM profile currently being used by the device. |
Measurements[x].Id | string | The unique ID for the measurement. |
Measurements[x].DeviceImei | string | The IMEI of the device. |
Measurements[x].SignalStrengthPercentage | number | Signal strength of the device (if applicable), which ranges from 0 - 100 |
Measurements[x].PatientId | string | The patient ID provided by partner to Pylo to attach to this device (usually at the time of ordering). Optional. |
Measurements[x].PracticeId | string | The practice ID provided by partner to Pylo to attach to this device. Optional. |
Measurements[x].TenantId | string | The tenant ID provided by partner to Pylo to attach to this device. Optional. |
Measurements[x].Values[y].Value | string | The value of this reading. (Blood pressure in mmHg, weight in lbs.) |
Measurements[x].Values[y].Type | string | The type of this reading |
Measurements[x].RadioAccessTechnology | string | The technology used for radio connectivity for this measurement. Optional. |
Measurements[x].NetworkName | string | Cellular network name used by device for transmission of measurement. Optional. |
Measurements[x].TowerLongitude | string | Longitude of nearest cell tower at time of measurement. Optional. |
Measurements[x].TowerLatitude | string | Latitude of nearest cell tower at time of measurement. Optional. |
page_info['cursor_token'] | string | The token returned from the previous page. Supply this token in another request to get the subsequent page. See Pagination for more information. |
Fulfillment Service
This service enables you to place an order, get order information, and more.
Authentication
Requests use the same authentication method defined in Authentication above.
Place Order
Place an order for a device (or devices) to be shipped to a patient. Supply order details in the body of the request. An order number will be returned to the client upon success.
HTTP Request
POST https://api.pylo.com/orders
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
order = {
'order_requested_shipping_service': 'standard',
'order_notes_from_buyer': 'Please send ASAP'
'recipient_first_name': 'John',
'recipient_last_name': 'Doe',
'recipient_phone': '5551234567',
'recipient_email': 'jdoe@gmail.com',
'recipient_company': '',
'address1': '30 rockefeller center',
'address2': 'apt 5'
'address3': '',
'city': 'New York',
'state': 'NY',
'postal_code': '10041',
'country_code': 'US',
'devices': [
{
'item_sku': 'PY-802-LTE',
'quantity': '2'
},
{
'item_sku': 'PY-300-LTE',
'quantity': '1'
}
],
'require_signature': 'no',
'patient_identifier': 'patientid123',
'practice_identifier': 'practiceid123',
'billing_info': {
'name': 'ABC Company Health',
'country': 'US',
'street1': '10 Rockefeller Plaza',
'state': 'NY',
'postal_code': '10112',
'city': 'New York'
},
'inserts' = [ 'Test-Insert-1', 'Test-Insert-2' ]
}
requests.post(
'https://api.pylo.com/orders',
json=order,
headers=headers
).json()
Create a file "order.json" following the format below.
Change values as needed.
{
'order_requested_shipping_service': 'standard',
'order_notes_from_buyer': 'Please send ASAP'
'recipient_first_name': 'John',
'recipient_last_name': 'Doe',
'recipient_phone': '5551234567',
'recipient_email': 'jdoe@gmail.com',
'recipient_company': '',
'address1': '70 rockefeller center',
'address2': 'apt 5'
'address3': '',
'city': 'New York',
'state': 'NY',
'postal_code': '10041',
'country_code': 'US',
'devices': [
{
'item_sku': 'PY-802-LTE',
'quantity': '2'
},
{
'item_sku': 'PY-300-LTE',
'quantity': '1'
}
]
'require_signature': 'no',
'patient_identifier': 'patientid123',
'practice_identifier': 'practiceid123',
'billing_info': {
'name': 'ABC Company Health',
'country': 'US',
'street1': '10 Rockefeller Plaza',
'state': 'NY',
'postal_code': '10112',
'city': 'New York'
},
'inserts' = [ 'Test-Insert-1', 'Test-Insert-2' ]
}
Then, pass that file as a payload to a curl POST:
curl -d '@../path-to-file/order.json' \
-X POST 'https://api.pylo.com/orders' \
-H 'x-api-key: your-api-key'
These parameters should be in the POST data.
Parameter | Type | Description | Required |
---|---|---|---|
order_requested_shipping_service | string | Either 'standard' or 'two-day'. | No |
order_notes_from_buyer | string | Any notes you wish to be attached to the order. | No |
recipient_first_name | string | The first name of the patient to which the device is being sent. | Yes |
recipient_last_name | string | The last name of the patient to which the device is being sent. | Yes |
recipient_phone | string | The phone number of the patient to which the device is being sent. | Yes |
recipient_email | string | The email of patient to which the device is being sent. | Yes |
recipient_company | string | The company of the patient to which the device is being sent. | No |
address1 | string | The address of the patient to which the device is being sent. | Yes |
address2 | string | Additional space for the address of the patient to which the device is being sent. | No |
address3 | string | Additional space for the address of the patient to which the device is being sent. | No |
city | string | The city of the above address. | Yes |
state | string | The state of the above address. | Yes |
postal_code | string | The postal code of the above address. | Yes |
country_code | string | The 2-digit ISO country code of the above address. | Yes |
devices | obj[] | An array of devices to be ordered. | Yes |
devices[x][item_sku] | string | The item to be ordered. Can be "PY-802-LTE" or "PY-300-LTE". | Yes |
devices[x][quantity] | string | The quantity of devices[x][item_sku] to be ordered. | Yes |
require_signature | string | Whether a signature should be required upon delivery. Can be "yes" or "no". | No |
patient_identifier | string | The unique patient identifier internal to your company. | No |
practice_identifier | string | The unique practice identifier internal to your company. | No |
billing_info | obj | The billing information for your company. | Yes |
billing_info[name] | string | The name of your company or the name of the party to be billed. | Yes |
billing_info[street1] | string | The street number and name of the company or bill-to party address. | Yes |
billing_info[state] | string | The state of the company or bill-to party address. | Yes |
billing_info[city] | string | The city of the company or bill-to party address. | Yes |
billing_info[postal_code] | string | The postal code of the company or bill-to party address. | Yes |
billing_info[country] | string | The 2-digit ISO country code of the company or bill-to party address. | Yes |
inserts | string[] | This field is used to add inserts or otherwise customize the patient kit.^1 | No |
^1: Insert codes (and the customization they represent) must be pre-arranged with Pylo prior to them being usable by an API user.
Response Body
The above command returns a 200 with an order number if the order was placed successfully, or an error code otherwise.
{
"status": "OK",
"order_number": "497993eb-2b94-4a51-ae21-477a9254b4b3"
}
Name | Type | Description |
---|---|---|
status | string | The status code of the response. "OK" if order placed successfully. |
order_number | string | The order reference number for the newly created order. Use this when querying orders via GET. |
Get Specific Order
Pass an order number as a query parameter to get details about that order.
HTTP Request
GET https://api.pylo.com/orders?number={your order number}
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
payload = {
'number': 'abc123'
}
requests.get(
'https://api.pylo.com/orders',
params=payload,
headers=headers
).json()
curl -X GET 'https://api.pylo.com/orders?number=abc123' \
-H 'x-api-key: your-api-key'
The order number parameter should be passed in the URL.
Parameter | Type | Description |
---|---|---|
number | string | The unique order number returned when you placed the order. If you do not know the order number, you can perform a GET without providing an order number to retrieve all orders for your company. |
Response Body
The above command returns the order details if found, or a 404 error code otherwise.
{
"address3": "",
"last_name_recipient": "Doe",
"email_recipient": "jdoe@gmail.com",
"devices": [
{
"sku": "PY-802-LTE",
"quantity": "2",
"imeis": []
},
{
"sku": "PY-300-LTE",
"quantity": "1",
"imeis": []
}
],
"first_name_recipient": "John",
"order_notes_from_buyer": "Please send ASAP",
"phone_recipient": "5551234567",
"state": "NY",
"postal_code": "10041",
"date_placed": "2021-04-20 05:57:22",
"city": "New York",
"require_signature": "no",
"confirmation": "none",
"order_requested_shipping_service": "ups",
"order_number": "02877f36-660f-475e-8778-3c2e4758301c",
"company_recipient": "",
"country_code": "US",
"address1": "30 rockefeller center",
"patient_id": "patientid123",
"practice_id": "practiceid123",
"address2": "",
"date_order_processed": "2021-04-20 05:57:22",
"order_status": "awaiting_shipment",
"ship_date": "",
"tracking_number": ""
}
{
"address3": "",
"last_name_recipient": "Doe",
"email_recipient": "jdoe@gmail.com",
"devices": [
{
"sku": "PY-802-LTE",
"quantity": "2",
"imeis": []
},
{
"sku": "PY-300-LTE",
"quantity": "1",
"imeis": []
}
],
"first_name_recipient": "John",
"order_notes_from_buyer": "Please send ASAP",
"phone_recipient": "5551234567",
"state": "NY",
"postal_code": "10041",
"date_placed": "2021-04-20 05:57:22",
"city": "New York",
"require_signature": "no",
"confirmation": "none",
"order_requested_shipping_service": "ups",
"order_number": "02877f36-660f-475e-8778-3c2e4758301c",
"company_recipient": "",
"country_code": "US",
"address1": "30 rockefeller center",
"patient_id": "patientid123",
"practice_id": "practiceid123",
"address2": "",
"date_order_processed": "2021-04-20 05:57:22",
"order_status": "awaiting_shipment",
"ship_date": "",
"tracking_number": ""
}
Key | Type | Value |
---|---|---|
order_number | string | The order number corresponding to this order. |
date_placed | string | The date at which the order was placed. |
order_status | string | The status of this order. Will be one of these values. |
ship_date | string | The date on which the order was shipped. |
carrier_code | string | The carrier code for this shipment. |
tracking_number | string | The tracking number for this shipment. |
order_requested_shipping_service | string | Either 'standard' or 'two-day'. |
order_notes_from_buyer | string | Any notes you wish to be attached to the order. |
first_name_recipient | string | The first name of the patient to which the device is being sent. |
last_name_recipient | string | The last name of the patient to which the device is being sent. |
phone_recipient | string | The phone number of the patient to which the device is being sent. |
email_recipient | string | The email of patient to which the device is being sent. |
company_recipient | string | The company of the patient to which the device is being sent. |
address1 | string | The address of the patient to which the device is being sent. |
address2 | string | Additional space for the address of the patient to which the device is being sent. |
address3 | string | Additional space for the address of the patient to which the device is being sent. |
city | string | The city of the above address. |
state | string | The state of the above address. |
postal_code | string | The postal code of the above address. |
country_code | string | The 2-digit ISO country code of the above address. |
devices | obj[] | An array of devices to be ordered. |
devices[x]['sku'] | string | The item to be ordered. Will be "PY-802-LTE" or "PY-300-LTE". |
devices][x]['quantity'] | string | The number of devices with this sku in this order. |
devices[x]['imeis'] | string | The IMEIs for these devices. Will be an empty string if awaiting shipment, or a list of strings (one IMEI for each device) once shipped. |
require_signature | string | Whether a signature should be required upon delivery. Can be "yes" or "no". |
confirmation | string | Whether to request proof of delivery from the carrier. Set to "none" unless specifically required. |
patient_id | string | The unique patient identifier internal to your company. |
practice_id | string | The unique practice identifier internal to your company. |
order_status will be one of the following strings:
- awaiting_shipment
- cancelled
- shipped
shipping_type will be one of the following strings:
- ground
- second_day_air
- priority_mail
Get All Orders
Get all orders for your company.
HTTP Request
GET https://api.pylo.com/orders?cursor={cursor_returned_from_previous_page}
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
requests.get(
'https://api.pylo.com/orders',
headers=headers
).json()
curl -X GET 'https://api.pylo.com/orders' \
-H 'x-api-key: your-api-key'
The cursor token parameter should be passed in the URL.
Parameter | Type | Description |
---|---|---|
cursor | string | The token returned from the previous page. Supply this token in another request to get the subsequent page. See Pagination for more information. |
Response Body
The above command returns all orders for your company.
{
"count": 10,
"orders": [
{
"address3": "",
"last_name_recipient": "Seldon",
"email_recipient": "hseldon@galacticempire.net",
"devices": [
{
"sku": "PY-802-LTE",
"quantity": "2",
"imeis": []
},
{
"sku": "PY-300-LTE",
"quantity": "1",
"imeis": []
}
],
"first_name_recipient": "Harry",
"order_notes_from_buyer": "Please send ASAP",
"phone_recipient": "5551234567",
"state": "NY",
"postal_code": "10041",
"date_placed": "2021-04-20 05:57:22",
"city": "New York",
"require_signature": "no",
"confirmation": "none",
"order_requested_shipping_service": "ups",
"order_number": "02877f36-660f-475e-8778-3c2e4758301c",
"company_recipient": "",
"country_code": "US",
"address1": "30 rockefeller center",
"patient_id": "patientid1",
"practice_id": "practiceid1",
"address2": "",
"date_order_processed": "2021-04-20 05:57:22",
"order_status": "awaiting_shipment",
"ship_date": "",
"tracking_number": ""
},
{
"address3": "",
"last_name_recipient": "Doe",
"email_recipient": "jdoe@gmail.com",
"devices": [
{
"sku": "PY-802-LTE",
"quantity": "2",
"imeis": []
},
{
"sku": "PY-300-LTE",
"quantity": "1",
"imeis": []
}
],
"first_name_recipient": "John",
"order_notes_from_buyer": "No rush",
"phone_recipient": "5551234567",
"state": "NY",
"postal_code": "10041",
"date_placed": "2021-04-20 06:30:06",
"city": "New York",
"require_signature": "no",
"confirmation": "none",
"order_requested_shipping_service": "standard",
"order_number": "417e93eb-2b24-4151-ae21-477a925fb4b3",
"company_recipient": "",
"country_code": "US",
"address1": "30 rockefeller center",
"patient_id": "patientid2",
"practice_id": "practiceid2",
"address2": "",
"date_order_processed": "2021-04-20 06:30:06",
"order_status": "shipped",
"ship_date": "2021-04-01",
"carrier_code": "ups_walleted",
"service_code": "ups_ground",
"tracking_number": "1Zabcdefg"
},
{
# ...more orders
}
],
"page_info": {
"cursor_token": "abcdefghijklmnopqrstuvwxyz==="
}
}
{
"count": 10,
"orders": [
{
"address3": "",
"last_name_recipient": "Seldon",
"email_recipient": "hseldon@galacticempire.net",
"devices": [
{
"sku": "PY-802-LTE",
"quantity": "2",
"imeis": []
},
{
"sku": "PY-300-LTE",
"quantity": "1",
"imeis": []
}
],
"first_name_recipient": "Harry",
"order_notes_from_buyer": "Please send ASAP",
"phone_recipient": "5551234567",
"state": "NY",
"postal_code": "10041",
"date_placed": "2021-04-20 05:57:22",
"city": "New York",
"require_signature": "no",
"confirmation": "none",
"order_requested_shipping_service": "ups",
"order_number": "02877f36-660f-475e-8778-3c2e4758301c",
"company_recipient": "",
"country_code": "US",
"address1": "30 rockefeller center",
"patient_id": "patientid1",
"practice_id": "practiceid1",
"address2": "",
"date_order_processed": "2021-04-20 05:57:22",
"order_status": "awaiting_shipment",
"ship_date": "",
"tracking_number": ""
},
{
"address3": "",
"last_name_recipient": "Doe",
"email_recipient": "jdoe@gmail.com",
"devices": [
{
"sku": "PY-802-LTE",
"quantity": "2",
"imeis": []
},
{
"sku": "PY-300-LTE",
"quantity": "1",
"imeis": []
}
],
"first_name_recipient": "John",
"order_notes_from_buyer": "No rush",
"phone_recipient": "5551234567",
"state": "NY",
"postal_code": "10041",
"date_placed": "2021-04-20 06:30:06",
"city": "New York",
"require_signature": "no",
"confirmation": "none",
"order_requested_shipping_service": "standard",
"order_number": "417e93eb-2b24-4151-ae21-477a925fb4b3",
"company_recipient": "",
"country_code": "US",
"address1": "30 rockefeller center",
"patient_id": "patientid2",
"practice_id": "practiceid2",
"address2": "",
"date_order_processed": "2021-04-20 06:30:06",
"order_status": "shipped",
"ship_date": "2021-04-01",
"carrier_code": "ups_walleted",
"service_code": "ups_ground",
"tracking_number": "1Zabcdefg"
},
{
# ...more orders
}
],
"page_info": {
"cursor_token": "abcdefghijklmnopqrstuvwxyz==="
}
}
Key | Type | Value |
---|---|---|
count | number | The number of returned orders |
orders[] | object[] | An array of orders. See the response body in Get Specific Order for the order model definition. |
page_info['cursor_token'] | string | The token returned from the previous page. Supply this token in another request to get the subsequent page. See Pagination for more information. |
order_status will be one of the following strings:
- awaiting_shipment
- cancelled
- shipped
shipping_type will be one of the following strings:
- ground
- second_day_air
- priority_mail
Cancel an order
Supply an order number to cancel an order.
Note: An order can only be cancelled before it is shipped and has no IMEIs attached.
HTTP Request
PUT https://api.pylo.com/orders/{ORDER_NUMBER}/cancel
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
requests.put(
'https://api.pylo.com/orders/abc123/cancel
headers=headers
).json()
curl -X PUT 'https://api.pylo.com/orders/abc123/cancel' \
-H 'x-api-key: your-api-key'
Supply exactly the following path parameter to cancel an order.
Path Parameter | Type | Description |
---|---|---|
order_number | string | The unique order number returned when you placed the order. If you do not know the order number, you can perform a GET without providing an order number to retrieve all orders for your company. |
Response Body
The above command returns a 200 with the cancelled order number if the order was cancelled successfully, or an error code otherwise.
{
"status": "OK",
"cancelled order number": "abc123"
}
Name | Type | Description |
---|---|---|
status | string | The status code of the response. "OK" if the order was cancelled successfully. |
cancelled order number | string | The cancelled order number will be returned. |
Update an order
Supply an order number to update the patient id or practice id on the particular order.
HTTP Request
PATCH https://api.pylo.com/orders
Query Parameters
import requests
headers = {
'x-api-key': 'your-api-key'
}
body = {
'order_number': 'abc123',
'patient_id': 'patientid123',
'practice_id': 'practiceid123',
}
requests.put(
'https://api.pylo.com/orders',
headers=headers,
json=body,
).json()
curl -X PATCH 'https://api.pylo.com/orders' \
-H 'x-api-key: your-api-key' \
-d '{"order_number": "abc123", "patient_id": "patientid123", "practice_id": "practiceid123"}'
The following parameters should be supplied in the request body.
Data (JSON) | Type | Description | Required |
---|---|---|---|
order_number | string | The unique order number returned when you placed the order. | Yes |
patient_id | string | The patient identifier you provide to overwrite the existing patient id. | No |
practice_id | string | The practice identifier you provide to overwrite the existing practice id. | No |
Response Body
The above command returns a 200 with the updated order number if the order was updated successfully, or an error code otherwise.
{
"status": "OK",
"updated order number": "abc123"
}
Name | Type | Description |
---|---|---|
status | string | The status code of the response. "OK" if the order was updated successfully. |
updated order number | string | The updated order number will be returned. |
API Errors
The Pylo API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is invalid or order fulfillment has not been enabled for your account. |
403 | Forbidden -- Your API key may be valid but it is not associated with a usage plan. |
406 | Not Acceptable -- You requested a format that isn't json. |
429 | Too Many Requests or Limit Exceeded -- You're requesting too many measurements! Slow down (or request a rate/quota increase)! |
500 | Internal Server Error -- We had a problem with our server. Try again later. If the problem persists, please contact us. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Webhooks
Overview
Pylo webhooks can be used to notify applications when measurements are taken.
Delivery Information
- Webhooks will be sent as POST requests.
- Hooks will be sent immediately after a measurement is taken.
- Failed deliveries are resent 15 minutes, 1 hour, 3 hours, 8 hours, and 24 hours
after the initial attempt.
- If all delivery attempts fail, an alert is generated for the Pylo team to follow up within 24 hours.
HMAC Validation
- After sharing a secret key with Pylo, every webhook event 'data' field is run through an HMAC using SHA-256 and the output of the function is included in the 'signature' object.
- In order to confirm that the notification came from Prevounce and was not edited en route, SHA-256 HMAC of the 'data' field should be computed and be compared with the signature ('signature') received. If they do not match, the webhook should be discarded.
Webhook Format
Every webhook has the same basic structure:
Example blood pressure webhook POST.
{
"event": "DEVICE_MEASUREMENT",
"eventTime": "2021-02-23T22:07:00.000Z",
"data": "{ \"field\": \"value\" }",
"signature": "abcd1234"
}
Key | Type | Value |
---|---|---|
event | string | The event that triggered this webhook. (For patient measurements, the event will be "DEVICE_MEASUREMENT".) |
eventTime | string | The ISO timestamp for when the webhook was first sent. |
data | string | The data related to the event, this is a string and must be converted into an object by your JSON parser of choice to access properly first. Eg in JavaScript: let obj = JSON.parse(webhook.data); |
signature | string | HMAC SHA-256 of the data field against the secret provided when the webhook was configured. Can be used to verify that the data came from us and was not altered en route. |
Blood Pressure Webhook
Triggers whenever a measurement is received from a blood pressure device or app.
Blood Pressure Webhook Data Format
Blood pressure objects will be packed in the data string.
Reminder: You need to convert the data in the data field to an object via your JSON parser of choice. Eg:
let object = JSON.parse(webhook.data);
Example blood pressure webhook data object.
{
"Id": "id1",
"DeviceId": "deviceid1",
"DeviceImei": "imei1",
"DeviceSim": "sim1",
"DeviceType": "PyloBp",
"DeviceModel": "PY-802-LTE",
"DeviceUser": "1",
"MeasurementType": "Blood Pressure",
"BatteryPercentage": 58,
"SignalStrengthPercentage": 94,
"MeasuredAt": "2021-02-23T22:06:00.000Z",
"Values": [
{
"Value": 84,
"Type": "diastolic"
},
{
"Value": 129,
"Type": "systolic"
},
{
"Value": 62,
"Type": "pulse"
},
{
"Value": 0,
"Type": "irregular"
}
],
"PatientId": "patient_id1",
"PracticeId": "practice_id1",
"RadioAccessTechnology": "radio_access_tech_1",
"NetworkName": "network_1",
"TowerLongitude": "longitude_1",
"TowerLatitude": "latitude_1"
}
Key | Type | Value |
---|---|---|
Id | string | A unique ID for the measurement. |
DeviceId | string | The serial number of the device. |
DeviceImei | string | The IMEI of the device. |
DeviceSim | string | The ICCID of the SIM profile currently being used by the device. |
DeviceType | string | The type/brand of the device. |
DeviceModel | string | The model number of the device. |
DeviceUser | string | The user of the device for this measurement (will always be 1 for devices without switchable user profiles). |
MeasurementType | string | Will be "Blood Pressure". |
BatteryPercentage | number | The percentage of battery that remains on the device. |
SignalStrengthPercentage | number | Signal strength of the device (if applicable), which ranges from 0 - 100 |
MeasuredAt | string | The ISO timestamp for when the measurement was recorded. |
Values | object[] | The array of measurement type and value pairs for this measurement. |
Values[0].Value | number | The value of this diastolic blood pressure reading in units of mmHg. |
Values[0].Type | string | The type of this reading. Will be "diastolic". |
Values[1].Value | number | The value of this systolic blood pressure reading in units of mmHg. |
Values[1].Type | string | The type of this reading. Will be "systolic". |
Values[2].Value | number | The value of this pulse reading in units of BPM. |
Values[2].Type | string | The type of this reading. Will be "pulse". |
Values[3].Value | number | A boolean (1 or 0) number indicating whether the reading is irregular. 1 if irregular, 0 otherwise. |
Values[3].Type | string | The type of this reading. Will be "irregular". |
PatientId | string | The patient ID provided by partner to Pylo to attach to this device (usually at the time of ordering). Optional. |
PracticeId | string | The practice ID provided by partner to Pylo to attach to this device. Optional. |
RadioAccessTechnology | string | The name of the cellular connection type used by the device. Optional. |
NetworkName | string | The name of the cellular network connected to the device. Optional. |
TowerLongitude | string | The longitude coordinate of the nearest cell tower when measurement taken. Optional. |
TowerLatitude | string | The latitude coordinate of the nearest cell tower when measurement taken. Optional. |
Weight Webhook
Triggers whenever a measurement is received from a weight device or app.
Weight Webhook Data Format
Weight objects will be packed in the data string.
Reminder: You need to convert the data in the data field to an object via your JSON parser of choice. Eg:
let object = JSON.parse(webhook.data);
Example weight webhook data object.
{
"Id": "id1",
"DeviceId": "deviceid1",
"DeviceImei": "imei1",
"DeviceSim": "sim1",
"DeviceType": "PyloWt",
"DeviceModel": "PY-802-LTE",
"DeviceUser": "1",
"MeasurementType": "Weight",
"BatteryPercentage": 58,
"SignalStrengthPercentage": 94,
"MeasuredAt": "2021-02-23T22:06:00.000Z",
"Values": [
{
"Value": 184.5,
"Type": "weight"
}
],
"PatientId": "patient_id1",
"PracticeId": "practice_id1",
"RadioAccessTechnology": "radio_access_tech_1",
"NetworkName": "network_1",
"TowerLongitude": "longitude_1",
"TowerLatitude": "latitude_1"
}
Key | Type | Value |
---|---|---|
Id | string | A unique ID for the measurement. |
DeviceId | string | The serial number of the device. |
DeviceImei | string | The IMEI of the device. |
DeviceSim | string | The ICCID of the SIM profile currently being used by the device. |
DeviceType | string | The type/brand of the device. |
DeviceModel | string | The model number of the device. |
DeviceUser | string | The user of the device for this measurement (will always be 1 for devices without switchable user profiles). |
MeasurementType | string | Will be "Weight". |
BatteryPercentage | number | The percentage of battery that remains on the device. |
SignalStrengthPercentage | number | Signal strength of the device (if applicable), which ranges from 0 - 100 |
MeasuredAt | string | The ISO timestamp for when the measurement was recorded. |
Values | object[] | The array of measurement type and value pairs for this measurement. |
Values[0].Value | number | The value of this weight pressure reading in units lbs. |
Values[0].Type | string | The type of this reading. Will be "weight". |
PatientId | string | The patient ID provided by partner to Pylo to attach to this device (usually at the time of ordering). Optional. |
PracticeId | string | The practice ID provided by partner to Pylo to attach to this device. Optional. |
RadioAccessTechnology | string | The name of the cellular connection type used by the device. Optional. |
NetworkName | string | The name of the cellular network connected to the device. Optional. |
TowerLongitude | string | The longitude coordinate of the nearest cell tower when measurement taken. Optional. |
TowerLatitude | string | The latitude coordinate of the nearest cell tower when measurement taken. Optional. |
Glucose Webhook
Triggers whenever a measurement is received from a glucose device.
Glucose Webhook Data Format
Glucose objects will be packed in the data string.
Reminder: You need to convert the data in the data field to an object via your JSON parser of choice. Eg:
let object = JSON.parse(webhook.data);
Example glucose webhook data object.
{
"Id": "id1",
"DeviceId": "deviceid1",
"DeviceImei": "imei1",
"DeviceSim": "sim1",
"DeviceType": "PyloGlucose",
"DeviceModel": "PY-GL1-LTE",
"DeviceUser": "1",
"MeasurementType": "Blood Glucose",
"BatteryPercentage": 58,
"SignalStrengthPercentage": 94,
"MeasuredAt": "2021-02-23T22:06:00.000Z",
"Values": [
{
"Value": 70,
"Type": "glucose"
},
{
"Value": 1,
"Type": "before_meal"
}
],
"PatientId": "patient_id1",
"PracticeId": "practice_id1",
"RadioAccessTechnology": "radio_access_tech_1",
"NetworkName": "network_1",
"TowerLongitude": "longitude_1",
"TowerLatitude": "latitude_1"
}
Key | Type | Value |
---|---|---|
Id | string | A unique ID for the measurement. |
DeviceId | string | The serial number of the device. |
DeviceImei | string | The IMEI of the device. |
DeviceSim | string | The ICCID of the SIM profile currently being used by the device. |
DeviceType | string | The type/brand of the device. |
DeviceModel | string | The model number of the device. |
DeviceUser | string | The user of the device for this measurement (will always be 1 for devices without switchable user profiles). |
MeasurementType | string | Will be "Blood Glucose". |
BatteryPercentage | number | The percentage of battery that remains on the device. |
SignalStrengthPercentage | number | Signal strength of the device (if applicable), which ranges from 0 - 100 |
MeasuredAt | string | The ISO timestamp for when the measurement was recorded. |
Values | object[] | The array of measurement type and value pairs for this measurement. |
Values[0].Value | number | The value of this blood glucose reading in units mg/dL. |
Values[0].Type | string | The type of this reading. Will be "glucose". |
Values[1].Value | number | Whether this blood glucose reading was before meal as "1" or after meal "0". Any other values will not be reflected here yet. |
Values[1].Type | string | The type of this reading. Will be "before_meal". |
PatientId | string | The patient ID provided by partner to Pylo to attach to this device (usually at the time of ordering). Optional. |
PracticeId | string | The practice ID provided by partner to Pylo to attach to this device. Optional. |
RadioAccessTechnology | string | The name of the cellular connection type used by the device. Optional. |
NetworkName | string | The name of the cellular network connected to the device. Optional. |
TowerLongitude | string | The longitude coordinate of the nearest cell tower when measurement taken. Optional. |
TowerLatitude | string | The latitude coordinate of the nearest cell tower when measurement taken. Optional. |
Pulse Ox Webhook
Triggers whenever a measurement is received from a pulse ox device.
Pulse Ox Webhook Data Format
Pulse Ox objects will be packed in the data string.
Reminder: You need to convert the data in the data field to an object via your JSON parser of choice. Eg:
let object = JSON.parse(webhook.data);
Example pulse ox webhook data object.
{
"Id": "id1",
"DeviceId": "deviceid1",
"DeviceImei": "imei1",
"DeviceSim": "sim1",
"DeviceType": "PyloPulseOx",
"DeviceModel": "PY-OX1-LTE",
"DeviceUser": "1",
"MeasurementType": "Pulse Oximetry",
"BatteryPercentage": 58,
"SignalStrengthPercentage": 94,
"MeasuredAt": "2021-02-23T22:06:00.000Z",
"Values": [
{
"Value": 98,
"Type": "spo2"
},
{
"Value": 103,
"Type": "pulse"
}
],
"PatientId": "patient_id1",
"PracticeId": "practice_id1",
"RadioAccessTechnology": "radio_access_tech_1",
"NetworkName": "network_1",
"TowerLongitude": "longitude_1",
"TowerLatitude": "latitude_1"
}
Key | Type | Value |
---|---|---|
Id | string | A unique ID for the measurement. |
DeviceId | string | The serial number of the device. |
DeviceImei | string | The IMEI of the device. |
DeviceSim | string | The ICCID of the SIM profile currently being used by the device. |
DeviceType | string | The type/brand of the device. |
DeviceModel | string | The model number of the device. |
DeviceUser | string | The user of the device for this measurement (will always be 1 for devices without switchable user profiles). |
MeasurementType | string | Will be "Pulse Oximetry". |
BatteryPercentage | number | The percentage of battery that remains on the device. |
SignalStrengthPercentage | number | Signal strength of the device (if applicable), which ranges from 0 - 100 |
MeasuredAt | string | The ISO timestamp for when the measurement was recorded. |
Values | object[] | The array of measurement type and value pairs for this measurement. |
Values[0].Value | number | The value of this spo2 reading in a percentage from 0 - 100%. |
Values[0].Type | string | The type of this reading. Will be "spo2". |
Values[1].Value | number | The value of this pulse reading in units bpm. |
Values[1].Type | string | The type of this reading. Will be "pulse". |
PatientId | string | The patient ID provided by partner to Pylo to attach to this device (usually at the time of ordering). Optional. |
PracticeId | string | The practice ID provided by partner to Pylo to attach to this device. Optional. |
RadioAccessTechnology | string | The name of the cellular connection type used by the device. Optional. |
NetworkName | string | The name of the cellular network connected to the device. Optional. |
TowerLongitude | string | The longitude coordinate of the nearest cell tower when measurement taken. Optional. |
TowerLatitude | string | The latitude coordinate of the nearest cell tower when measurement taken. Optional. |