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_KEYwith 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_KEYwith 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_KEYwith 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_KEYwith 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_KEYwith your API key with edit devices permissions.
Make sure to replace
DEVICE_IDwith 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_KEYwith 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_KEYwith 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. |