NAV
shell python

Introduction

Welcome to the Senscape Hub API! You can use our API to access Senscape Hub API endpoints, which can get information on your devices and data.

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.

Authentication

To authorize, use this code:

import requests

requests.get('url', headers={"Authorization": "API_KEY"})
# With shell, you can just pass the correct header with each request
curl "api_endpoint_here"
-H "Authorization: API_KEY"

Make sure to replace API_KEY with your API key.

Senscape Hub uses API keys to allow access to the API. You can generate an API key in your settings.

Senscape Hub expects for the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: API_KEY

Devices

Get available sensor IDs

import requests

requests.get('https://senscape.eu/api/devices/available-ids', headers={"Authorization": "API_KEY"})
curl "https://senscape.eu/api/devices/available-ids" -H "Authorization: API_KEY"

Make sure to replace API_KEY with your API key with edit devices permissions.

The above command returns JSON structured like this:

[
{
"sensorId": "ID 1",
"devType": "Mosquito"
},
{
"sensorId": "ID 2",
"devType": "Mosquito"
},
]

This endpoint retrieves a list of available sensor IDs for device creation.

HTTP Request

GET https://senscape.eu/api/devices/available-ids

Create device

import requests

"""Create device"""
requests.post(
'https://senscape.eu/api/devices/create',
json={
"name": "Device",
"sensorId": "ID_1",
"devType": "Mosquito",
"lat": 42.2,
"lng": 3.3
},
headers={"Authorization": "API_KEY"}
)
curl -X POST https://senscape.eu/api/devices/create \     
-d '{"name": "Device", "sensorId": "ID_1", "devType": "Mosquito", "lat": 42.2, "lng": 3.3}' \
-H "Authorization: API_KEY" \
-H "Content-Type: application/json"

Make sure to replace API_KEY with your API key with edit devices permissions.

The above command returns JSON structured like this:

{
"success": true,
"msg": "Successfully created new device.",
"device": {
"_id": "6499998daff63db46f82cd6a",
"name": "Device",
"sensorId": "ID_1",
"tags": [],
"loc": {
"type": "Point",
"coordinates": [
3.3,
42.2
]
}
}
}

This endpoint creates a device.

HTTP Request

POST https://senscape.eu/api/devices/create

JSON Body Parameters

Parameter Required Type Description
name true String Device name
sensorId true String Sensor ID
devType true String Device type
lat true Number Latitude of GPS position of device
lng true Number Longitude of GPS position of device

Get devices

import requests

requests.get('https://senscape.eu/api/devices', headers={"Authorization": "API_KEY"})
curl "https://senscape.eu/api/devices" -H "Authorization: API_KEY"

Make sure to replace API_KEY with your API key.

The above command returns JSON structured like this:

{
"devices": [
{
"_id": "5ea84cca9",
"name": "test",
"sensorId": "ID 1",
"tags": [
"Tag C",
],
"typ": "Mosquito",
"description": "this is a test device",
"dev_timestamp": "2021-03-08T14:20:39.000Z", # Timestamp of last activity
"created": "2020-04-28T15:33:30.000Z"
},
{
"_id": "5f102b1",
"name": "test 2",
"sensorId": "ID 2",
"tags": [
"Tag A",
"Tag B"
],
"typ": "Mosquito",
"description": "this is test device 2",
"dev_timestamp": "2022-04-03T09:17:29.000Z",
"created": "2020-07-16T10:25:25.000Z"
},
{
"_id": "5f10312330",
"name": "test 3",
"sensorId": "ID 3",
"tags": [
"Tag C",
"Tag D"
],
"typ": "Mosquito",
"description": "this is test device 3",
"dev_timestamp": "2022-05-29T11:05:38.000Z",
"created": "2020-07-16T10:51:15.000Z"
}
],
"count": 3
}

This endpoint retrieves a paginated list of devices and their total count.

HTTP Request

GET https://senscape.eu/api/devices

Query Parameters

Parameter Default Description
sortField activity By which field the returned list of devices should be sorted. Options: name, type, description, created, activity.
sortOrder desc Sort order of returned list of devices. Options: asc, desc.
pageNumber 0 For pagination, page number, min: 0.
pageSize 10 For pagination, number of entries of page, min: 1, max: 1000.
filterName Filter result by device name.
filterDescription Filter result by device description.
filterTags Filter by tags. Pass multiple tags as comma separated list.

Update device

import requests

"""Update name"""
requests.post(
'https://senscape.eu/api/devices/update',
json={
"id": "DEVICE_ID ("_id" attribute of device)",
"update": {"name": "new name"}
},
headers={"Authorization": "API_KEY"}
)

"""Update description"""
requests.post(
'https://senscape.eu/api/devices/update',
json={
"id": "DEVICE_ID ("_id" attribute of device)",
"update": {"description": "new description"}
},
headers={"Authorization": "API_KEY"}
)

"""Update location"""
requests.post(
'https://senscape.eu/api/devices/update',
json={
"id": "DEVICE_ID ("_id" attribute of device)",
"update": {"location": {"lat": 41, "lng": 3}}
},
headers={"Authorization": "API_KEY"}
)

"""Update name, description and location"""
requests.post(
'https://senscape.eu/api/devices/update',
json={
"id": "DEVICE_ID ("_id" attribute of device)",
"update": {
"name": "new name",
"description": "new description",
"location": {"lat": 41, "lng": 3}
}
},
headers={"Authorization": "API_KEY"}
)
curl -X POST https://senscape.eu/api/devices/update \     
-d '{"id": "DEVICE_ID ("_id" attribute of device)", "update": {"name": "new name"}}' \
-H "Authorization: API_KEY" \
-H "Content-Type: application/json"

Make sure to replace API_KEY with your API key with edit devices permissions.

Make sure to replace DEVICE_ID with the ID of the device you want to update (its “_id” value).

The above command returns JSON structured like this:

{
"success": true,
"msg": "Successfully updated device."
}

This endpoint updates the information of a device.

HTTP Request

POST https://senscape.eu/api/devices/update

JSON Body Parameters

Parameter Required Type Description
id true String Device ID (its “_id” attribute value)
update true Object Update object
update.name false String New name of device
update.description false String New description of device
update.location false Object New location of device
update.location.lat false Number New latitude of device
update.location.lng false Number New longitude of device

Data

Get classifications

import requests

requests.get('https://senscape.eu/api/data/classifications',
headers={"Authorization": "API_KEY"})
curl "https://senscape.eu/api/data/classifications" -H "Authorization: API_KEY"

Make sure to replace API_KEY with your API key.

This request returns a list like this:

[
"Aedes female",
"Aedes male",
"Culex female",
"Culex male",
]

This endpoint retrieves a list of possible classifications of the data records based on the devices in the user account.

HTTP Request

GET https://senscape.eu/api/data/classifications

Get data

"""Basic request"""
import requests

requests.get('https://senscape.eu/api/data', headers={"Authorization": "API_KEY"})

"""Get first five samples, make Pandas DataFrame and store as CSV."""
import requests
import pandas as pd

response = requests.get('https://senscape.eu/api/data?sortOrder=asc&sortField=record_time&pageSize=5', headers={"Authorization": "API_KEY"})
df = pd.DataFrame(response.json()['samples'])
df.to_csv('data.csv')

"""Load dataset from CSV, get record time of last sample and get all new
samples in paginated download, add them to DataFrame and store as CSV

"""
import requests
import pandas as pd

URL = 'https://senscape.eu/api/data'
PAGE_SIZE = 100

"""Read CSV"""
df = pd.read_csv('data.csv', index_col=0)

"""Sort ascending by record time"""
df_sorted = df.sort_values(by='record_time')

"""Get last record time"""
last_record_time = df.iloc[-1]['record_time']

page_number = 0

"""Get first page and add to DataFrame"""
data = requests.get(f'{URL}?filterStart={last_record_time}&sortOrder=asc&sortField=record_time&pageSize={PAGE_SIZE}&pageNumber={page_number}', headers={"Authorization": token})

"""Total count of samples newer than last record time"""
count = data.json()['count']
"""Make DataFrame of downloaded page"""
page_df = pd.DataFrame(data.json()['samples'])
"""Add DataFrame page to DataFrame"""
df = pd.concat([df, page_df], ignore_index=True)

"""Pagination loop to download the rest of the pages"""
for page_number in range(1, int(count/page_size) + 1):
data = requests.get(f'{URL}?filterStart={last_record_time}&sortOrder=asc&sortField=record_time&pageSize={PAGE_SIZE}&pageNumber={page_number}', headers={"Authorization": token})
"""Make DataFrame of downloaded page"""
page_df = pd.DataFrame(data.json()['samples'])
"""Add DataFrame page to DataFrame"""
df = pd.concat([df, page_df], ignore_index=True)

"""Write to CSV"""
df.to_csv('data.csv')

"""Keep an updated dataset using the 'processed' attribute.

A good way to keep an updated dataset without unnecessarily re-downloading
data, is to use the 'processed field'. When a data record first gets processed
by the machine learning model, its 'processed' field get the that
date as value. If at a later point, the machine learning models are updated and
a different classification result is obtained during reprocessing, the
'processed' field is updated with a new date. This can be used to only download
new data records or data records whose classification was changed by updated
machine learning models.

"""
CSV_LOC = 'data.csv'
URL = 'https://senscape.eu/api/data'
API_KEY = "API_KEY"
PAGE_SIZE = 100

"""Just once, get a dataset to get started. Download sorted by 'processed' field"""
url = f'{URL}?sortOrder=asc&sortField=processed&pageSize={PAGE_SIZE}' \
'&pageNumber=0'
data = requests.get(url, headers={"Authorization": API_KEY})

"""Generate DataFrame from downloaded data and save to disk"""
first_df = pd.DataFrame(data.json()['samples'])
first_df.to_csv(CSV_LOC)

"""The following code can be executed on regular intervals to update the
dataset. Only new data is added. Outdated classifications are updated."""
df = pd.read_csv(CSV_LOC, index_col=0)

"""Sort dataset by processed date and get the last one"""
df_sorted = df.sort_values('processed', ascending=True)
last_processed_date = df.iloc[-1]['processed']

"""Download first page of data with (re-)processed date later or equal than last
processed date of current dataset"""
page_url = f'{URL}?processedAfter={last_processed_date}&sortOrder=asc' \
f'&sortField=processed&pageSize={PAGE_SIZE}&pageNumber=0'
data = requests.get(page_url, headers={"Authorization": API_KEY})

"""Total count of samples with (re-)processed date later or equal than last
processed date of current dataset"""
count = data.json()['count']
"""Make DataFrame of downloaded page data"""
df_new_data = pd.DataFrame(data.json()['samples'])

"""Pagination loop"""
for page_number in range(1, int(count/PAGE_SIZE) + 1):
page_url = f'{URL}?processedAfter={last_processed_date}&sortOrder=asc' \
f'&sortField=processed&pageSize={PAGE_SIZE}&pageNumber={page_number}'
data = requests.get(page_url, headers={"Authorization": API_KEY})
"""New data might arrive as we download so we update the count variable"""
count = data.json()['count']
page_df = pd.DataFrame(data.json()['samples'])
"""Concatenate page to new data"""
df_new_data = pd.concat([df_new_data, page_df], ignore_index=True)

"""Concatenate old dataset with new dataset.
Then drop lines with duplicated IDs keeping the newer lines.
This results in a dataset where old and new data is joined, and outdated
classifcations are updated."""
new_df = pd.concat([df, df_new_data], ignore_index=True,
sort =False).drop_duplicates(['_id'], keep='last')
new_df.to_csv(CSV_LOC)



curl "https://senscape.eu/api/data" -H "Authorization: API_KEY"

Make sure to replace API_KEY with your API key.

This request returns a JSON structured like this:

{
"samples": [
{
"_id": "5f1ea1",
"temperature": 25.75036,
"nice_name": "FILE_1587569628",
"classification": "Non-target",
"record_time": "2020-04-22T15:33:49.000Z",
"humidity": 68.05523,
"client_name": "Device 3",
"client_type": "Mosquito",
"processed": "2020-07-16 11:13:58.186886",
"lat": 41.387153,
"lng": 2.190108
},
{
"_id": "5f1ea2",
"temperature": 26.84252,
"nice_name": "FILE_1587569628",
"classification": "Test pulse",
"record_time": "2020-04-22T15:33:49.000Z",
"humidity": 62.77561,
"client_name": "Device 2",
"client_type": "Mosquito",
"processed": "2020-07-27 08:44:07.006276",
"lat": 41.381579,
"lng": 2.182197
},
{
"_id": "5f1ea3",
"temperature": 26.8719,
"nice_name": "FILE_1595545257",
"classification": "Aedes Albopictus female",
"record_time": "2020-07-23T23:13:32.000Z",
"humidity": 63.3112,
"client_name": "Device 1",
"client_type": "Mosquito",
"processed": "2020-07-27 09:37:08.686902",
"lat": 41.381579,
"lng": 2.182197
}
],
"count": 3
}

This endpoint retrieves a paginated list of data records and their total count.

HTTP Request

GET https://senscape.eu/api/data

Query Parameters

Parameter Default Description
sortField record_time By which field the returned list of devices should be sorted. Options: classification, device, name, record_time, processed.
sortOrder desc Sort order of returned list of devices. Options: asc, desc.
pageNumber 0 For pagination, page number, min: 0.
pageSize 10 For pagination, number of entries of page, min: 1, max: 1000.
filterName Filter result by data record name.
deviceId Filter result by device ID. Multiple devices IDs can be included by passing this parameter mutliple times.
classification Filter result by classification. Multiple classifications can be included by passing this parameter mutliple times.
filterStart Filter result by record time, only results with dates later than filterStart are returned.
filterEnd Filter result by record time, only results with dates earlier or equal than filterEnd are returned.
processedAfter Filter result by time of processing, only results with dates later or equal than given datetime are returned.
processedBefore Filter result by time of processing, only results with dates earlier or equal than given datetime are returned.

Errors

The Senscape Hub uses the following error codes:

Error Code Meaning
400 Bad Request – Your request is invalid.
401 Unauthorized – Your API key is wrong.
404 Not Found.
500 Internal Server Error.