NAV
shell python

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:

  1. Devices Service: API service where you can get information about devices currently possessed by your company.

  2. Readings Service: API service where you can get device measurement readings.

  3. Fulfillment Service: API service where you can place orders and get order status.

  4. 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

Pagination

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).

Pagination

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

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

order_status will be one of the following strings:

Shipping Type

shipping_type will be one of the following strings:

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

order_status will be one of the following strings:

Shipping Type

shipping_type will be one of the following strings:

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

HMAC Validation

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.