API Documentation
👩🏻‍💻

API Documentation

Introduction

The QuantAQ Cloud API allows you to manage your air quality sensors and data in a simple, programmatic way using conventional HTTP requests. Each endpoint is intuitive (hopefully...) and allows you to easily obtain data and execute various actions. If you notice something that can be made more clear or more intuitive, please let us know!

This documentation will begin with a general overview of the API and how it works, followed by details on each endpoint that is available in v1 of the API. Throughout this documentation, there will be code examples using httpie - an easy-to-use command line client for making HTTP requests. The names of specific resources will be represented by variables which will be wrapped in "<>".

Getting Started

Obtaining an API key

Authentication is handled using HTTP Basic Auth which consists of sending an API key that is unique to your account with each request. This key should be kept secret and not shared with anyone. This API key is tied to your user account and will only allow you to take actions within your assigned scope of permissions.

You can generate an API key for your account by visiting the developer dashboard and clicking Generate New Key in the upper right hand corner of your screen. It is recommended that you set this key as an environment variable on your computer with the name QUANTAQ_APIKEY.

To include your API key in your request, add an HTTP Authorization header, consisting of a username and a password. When using httpie, you can use the -a flag to indicate authorization. The API key serves as the username and the password should be left blank.

Sending your first API call

To make an API call, you need four pieces of information:

  1. api_key A random string of alphanumeric characters that gives you access to the API.
  2. endpoint The URI listed in the API reference section below.
  3. method One of GET, POST, PUT, DELETE.
  4. arguments JSON-encoded values sent to the method (these are not always required)

More often than not, you will be sending either GET (retrieve data) or POST (submit data) requests to api.quant-aq.com. All API endpoints begin with the same URL which for the QuantAQ Cloud API is api.quant-aq.com/device-api/. The full URL will be of form:

https://api.quant-aq.com/device-api/{version}/{endpoint}

The version of the API may change (this will be documented) which signals changes in the underlying structure of the API. For now, there is only one version available: v1. Throughout these docs, we will just assume the version is v1.

A good first API call would be to get your account information. As mentioned above, we will use httpie for examples. To get your account information, the API call would look like:

$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/account

You should see a response that looks something like the following:

{
    "confirmed": true,
    "email": "users_email@quant-aq.com",
    "first_name": "First Name",
    "id": 1,
    "is_administrator": false,
    "last_name": "Last Name",
    "last_seen": "2020-09-28T13:12:33.745041",
    "member_since": "2020-06-05T22:05:24.612347",
    "role": 5,
    "username": "username"
}

Understanding API calls and responses

Any tool that is fluent in HTTP requests and has support for HTTP basic authentication protocols can be used to communicate with the QuantAQ Cloud API. Requests must be made using HTTPS. The interface response depending on the action required. Below is a list of libraries by language that can be used to make conventional HTTP requests:

R

Igor Pro

Not compatible. Igor does not currently support SSL 😢.

HTTP statuses and errors

Each request that is made to the API will have an attached status code that tells you whether the request was successful or not. If there is an issue with the request, an error will be returned as indicated both by the HTTP status code and the response body. In general, if the status code is in the 200's, the request was successful. If the status code is in the 400's, there was an error with the request; this could range from improper authentication to an illegal operation (e.g., you were trying to request data for which you do not have the necessary permissions). If a 500 error is returned, there was a server-side error which means we were not able to process the request for some reason.

An example error response:

HTTP/1.1 403 Forbidden
{
	"id": "forbidden",
	"message": "You do not have permissions for this action."
}

API Reference

account

/account [GET]

Return your account information.

Arguments

None.

Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/account
Example Response
{
    "confirmed": true,
    "email": "your-email@email.com",
    "first_name": "First Name",
    "id": 1,
    "is_administrator": false,
    "last_name": "Last Name",
    "last_seen": "2020-09-28T13:12:33.745041",
    "member_since": "2020-06-05T22:05:24.612347",
    "role": 5,
    "username": "username"
}

devices/

The devices/ endpoints allow you to add and retrieve information about devices.

/devices/ [GET]

Return a paginated list of all of your devices.

Arguments

Untitled

ArgumentTypeDescription
per_page
integer
The number of items to return per page.
page
integer
The page number to return.
sort
string
Please see the advanced queries section at the bottom of this page.
filter
string
Please see the advanced queries section at the bottom of this page.
limit
string
Please see the advanced queries section at the bottom of this page.
team
string
The team name to limit the query by.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/devices/
Example Response
{
    "data": [
        {
            "city": "New City",
            "country": "US",
            "created": "2019-03-03T17:50:16.829776",
            "description": "",
            "geo": {
                "lat": 42.5,
                "lon": -71.1
            },
            "id": 1,
            "last_seen": "2019-12-06T22:57:05.917175",
            "model": "arisense_v200",
            "n_datapoints": 4048,
            "outdoors": true,
            "owner_id": 1,
            "private": true,
            "sn": "SN000-001",
            "status": "CALIBRATION",
            "timezone": "US/Eastern",
            "url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001"
        },
        ...
    ],
    "meta": {
        "first_url": "https://api.quant-aq.com/device-api/v1/devices/?page=1&per_page=50",
        "last_url": "https://api.quant-aq.com/device-api/v1/devices/?page=1&per_page=50",
        "next_url": null,
        "page": 1,
        "pages": 1,
        "per_page": 50,
        "prev_url": null,
        "total": 3

/devices/<serial number> [GET]

Retrieve information about a single device.

Arguments

None.

Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/devices/<serial-number>
Example Response
{
    "city": "Boston",
    "country": null,
    "created": "2019-12-08T23:23:28.107099",
    "description": null,
    "geo": {
        "lat": null,
        "lon": null
    },
    "id": 6,
    "last_seen": "2019-12-08T23:23:28.107106",
    "model": "arisense_v200",
    "n_datapoints": 0,
    "outdoors": true,
    "owner_id": 1,
    "private": true,
    "sn": "a123456",
    "status": "INACTIVE",
    "timezone": null,
    "url": "https://api.quant-aq.com/device-api/v1/devices/a123456"
}

/devices/<serial number> [PUT]

Update the information for a specific device.

Arguments

Untitled

ArgumentTypeDescription
firmware_version
string
The device firmware version.
lat
float
Location/latitude
lon
float
Location/longitude
city
string
Location/city
country
string
2-digit ISO country code.
description
text
Short description and/or label for the sensor.
is_outdoors
boolean
True if the device is outdoors.
is_private
boolean
True if you wish for the device to remain private.
device_state
string
One of [ ACTIVE, INACTIVE, CALIBRATION, RETIRED, PRE_REGISTERED ]
timezone
string
The device timezone.
Example Request
$ http -a <your-api-key-here>: PUT https://api.quant-aq.com/device-api/v1/devices/<serial-number> lat=71.3 lon=17.5 country=US 
Example Response
{
    "city": "Boston",
    "country": "US",
    "created": "2019-12-08T23:23:28.107099",
    "description": null,
    "geo": {
        "lat": 71.3,
        "lon": 17.5
    },
    "id": 6,
    "last_seen": "2019-12-08T23:32:20.744588",
    "model": "arisense_v200",
    "n_datapoints": 0,
    "outdoors": true,
    "owner_id": 1,
    "private": true,
    "sn": "a123456",
    "status": "INACTIVE",
    "timezone": null,
    "url": "https://api.quant-aq.com/device-api/v1/devices/<serial number>"
}

/devices/<serial number> [DELETE]

Mark a device as ready for deletion.

🚫

This cannot be undone! Be careful before deleting devices.

Arguments

None.

Example Request
$ http -a <your-api-key-here>: DELETE https://api.quant-aq.com/device-api/v1/devices/<serial-number> 
Example Response
{
    "device dropped": "success"
}

teams/

/teams/ [GET]

Get a paginated list of teams that you belong to.

Arguments

Untitled

ArgumentTypeDescription
per_page
integer
The number of items to return per page.
page
integer
The page number to return.
sort
string
Please see the advanced queries section at the bottom of this page.
filter
string
Please see the advanced queries section at the bottom of this page.
limit
string
Please see the advanced queries section at the bottom of this page.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/teams/
Example Response
{
    "data": [
        {
            "admins": [
                "admin1"
            ],
            "description": "Team 1",
            "devices": [],
            "id": 1,
            "members": [
                "user-1",
								"user-2"
            ],
            "name": "Team 1"
        }
    ],
    "meta": {
        "first_url": "https://api.quant-aq.com/device-api/v1/teams/?page=1&per_page=50",
        "last_url": "https://api.quant-aq.com/device-api/v1/teams/?page=1&per_page=50",
        "next_url": null,
        "page": 1,
        "pages": 1,
        "per_page": 50,
        "prev_url": null,
        "total": 1
    }
}

/teams/<id> [GET]

Get information about an individual team.

Arguments

Untitled

ArgumentTypeDescription
id
integer
The id of the team you are trying to retrieve. The id can be looked up by first querying all teams.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/teams/1
Example Response
{
  "admins": [
      "admin1"
  ],
  "description": "Team 1",
  "devices": [],
  "id": 1,
  "members": [
      "user-1",
			"user-2"
  ],
  "name": "Team 1"
}

data/

Retrieve data for a given sensor. Data can only be retrieved by sensor and all data results are paginated.

/devices/<serial-number>/data/ [GET]

Return a paginated list of data for device by serial number.

Arguments

Untitled

ArgumentTypeDescription
per_page
integer
The number of items to return per page.
page
integer
The page number to return.
sort
string
Please see the advanced queries section at the bottom of this page.
filter
string
Please see the advanced queries section at the bottom of this page.
limit
string
Please see the advanced queries section at the bottom of this page.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/devices/<serial-number>/data/?limit=100&per_page=50
Example Response
{
    "data": [
						{
	            "co": 51.106268512085,
	            "co2": 421.793483200912,
	            "geo": {
	                "lat": 40.9844188816344,
	                "lon": 105.561207967016
	            },
	            "no": 10.2810514330163,
	            "no2": 56.8233499407749,
	            "noise": 6.29058420281369,
	            "o3": 37.946070157595,
	            "pm1": 8.91967278706223,
	            "pm10": 14.2017895600789,
	            "pm25": 9.07509558015509,
	            "pressure": 101454.562990336,
	            "rh_manifold": 73.2982119788483,
	            "sn": "SN000-001",
	            "solar": 8.49282458496783,
	            "temp_box": 35.226457866451,
	            "temp_manifold": 7.28921112549997,
	            "timestamp": "2020-06-08T15:31:16.895459",
	            "timestamp_local": "2020-06-08T09:31:16.895459",
	            "tvoc": null,
	            "url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/19",
	            "wind_dir": 323.38596795112,
	            "wind_speed": 99.8816892936835
	        }
    ],
    "meta": {
        "first_url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/?page=1&per_page=50&limit=100",
        "last_url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/?page=2&per_page=50&limit=100",
        "next_url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/?page=2&per_page=50&limit=100",
        "page": 1,
        "pages": 2,
        "per_page": 50,
        "prev_url": null,
        "total": 100
    }
}

/devices/<serial-number>/data/raw/ [GET]

Return a paginated list of the raw data for a device by serial number. NOTE: This data is only available to researchers.

Arguments

Untitled

ArgumentTypeDescription
per_page
integer
The number of items to return per page.
page
integer
The page number to return.
sort
string
Please see the advanced queries section at the bottom of this page.
filter
string
Please see the advanced queries section at the bottom of this page.
limit
string
Please see the advanced queries section at the bottom of this page.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/devices/<serial-number>/data/raw/?limit=100&per_page=50
Example Response
{
    "data": [
				{
            "bin0": 286.647741870419,
            "bin1": 551.701930611041,
            "bin10": 46.7706898657725,
            "bin11": 29.584787450594,
            "bin12": 50.7844931631582,
            "bin13": 21.5517228689086,
            "bin14": 44.4108140986913,
            "bin2": 221.637921828236,
            "bin3": 275.16465539171,
            "bin4": 312.552750081673,
            "bin5": 224.606340244391,
            "bin6": 230.723866268078,
            "bin7": 40.6604798027605,
            "bin8": 86.764139275662,
            "bin9": 76.3482566483437,
            "co2_raw": 959.118224004688,
            "co_ae": 911.5526546364,
            "co_diff": null,
            "co_we": 467.476827385698,
            "dew_point": 2.1147447373898,
            "flag": 64,
            "geo": {
                "lat": 40.9844188816344,
                "lon": 105.561207967016
            },
            "no2_ae": 579.782539043588,
            "no2_diff": null,
            "no2_we": 614.951076396963,
            "no_ae": 789.090772676965,
            "no_diff": null,
            "no_we": 439.438007376347,
            "noise": 6.29058420281369,
            "o3_ae": 455.557344482557,
            "o3_diff": null,
            "o3_we": 669.05302084695,
            "opc_flow": 0.569001807871506,
            "opc_sample_time": null,
            "pressure": 101454.562990336,
            "rh_manifold": 73.2982119788483,
            "sn": "SN000-001",
            "solar": 8.49282458496783,
            "temp_box": 35.226457866451,
            "temp_manifold": 7.28921112549997,
            "timestamp": "2020-06-08T15:31:16.895459",
            "timestamp_local": "2020-06-08T09:31:16.895459",
            "url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/raw/19",
            "voc_raw": 139.457791015991,
            "wind_dir": 323.38596795112,
            "wind_speed": 99.8816892936835
        }
    ],
    "meta": {
        "first_url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/raw/?page=1&per_page=50&limit=100",
        "last_url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/raw/?page=2&per_page=50&limit=100",
        "next_url": "https://api.quant-aq.com/device-api/v1/devices/SN000-001/data/raw/?page=2&per_page=50&limit=100",
        "page": 1,
        "pages": 2,
        "per_page": 50,
        "prev_url": null,
        "total": 100
    }
}

meta-data/

Meta data contains information about the location and firmware the device is using.

/meta-data/<serial-number>/ [GET]

Return a paginated list of meta data for a device.

Arguments

Untitled

ArgumentTypeDescription
per_page
integer
The number of items to return per page.
page
integer
The page number to return.
sort
string
Please see the advanced queries section at the bottom of this page.
filter
string
Please see the advanced queries section at the bottom of this page.
limit
string
Please see the advanced queries section at the bottom of this page.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/meta-data/<serial-number>/?limit=100&per_page=2
Example Response
{
    "data": [
				{
            "altitude": 48.0,
            "fw": null,
            "geo": {
                "lat": 35.894024,
                "lon": -78.886574
            },
            "sn": "SN000-041",
            "timestamp": "2020-02-02T19:59:37.743000",
            "uncertainty": 770.0,
            "url": "https://api.quant-aq.com/device-api/v1/meta-data/SN000-041/82605"
        },
        {
            "altitude": 48.0,
            "fw": null,
            "geo": {
                "lat": 35.894024,
                "lon": -78.886574
            },
            "sn": "SN000-041",
            "timestamp": "2020-02-02T18:59:38.768000",
            "uncertainty": 770.0,
            "url": "https://api.quant-aq.com/device-api/v1/meta-data/SN000-041/82572"
        }
    ],
    "meta": {
        "first_url": "https://api.quant-aq.com/device-api/v1/meta-data/SN000-041/?page=1&per_page=50&limit=100",
        "last_url": "https://api.quant-aq.com/device-api/v1/meta-data/SN000-041/?page=2&per_page=50&limit=100",
        "next_url": "https://api.quant-aq.com/device-api/v1/meta-data/SN000-041/?page=2&per_page=50&limit=100",
        "page": 1,
        "pages": 1002,
        "per_page": 2,
        "prev_url": null,
        "total": 2003
    }
}

logs/

Logs contain information about the state of the device.

/log/<serial-number>/ [GET]

Return a paginated list of logs which contain information about the operational status of the device.

Arguments

Untitled

ArgumentTypeDescription
per_page
integer
The number of items to return per page.
page
integer
The page number to return.
sort
string
Please see the advanced queries section at the bottom of this page.
filter
string
Please see the advanced queries section at the bottom of this page.
limit
string
Please see the advanced queries section at the bottom of this page.
Example Request
$ http -a <your-api-key-here>: GET https://api.quant-aq.com/device-api/v1/log/<serial-number>/?limit=4&per_page=2
Example Response
{
    "data": [
				{
            "level": "INFO",
            "message": "SETUP_STARTED",
            "millis": 5232,
            "sn": "SN000-041",
            "timestamp": "2020-04-17T01:12:53",
            "url": "https://api.quant-aq.com/device-api/v1/log/668462?sn=SN000-041"
        },
        {
            "level": "INFO",
            "message": "MODEM_RESET",
            "millis": 195947878,
            "sn": "SN000-041",
            "timestamp": "2020-04-17T01:11:56",
            "url": "https://api.quant-aq.com/device-api/v1/log/668461?sn=SN000-041"
        }
    ],
    "meta": {
        "first_url": "https://api.quant-aq.com/device-api/v1/log/SN000-041/?page=1&per_page=2&limit=4",
        "last_url": "https://api.quant-aq.com/device-api/v1/log/SN000-041/?page=2&per_page=2&limit=4",
        "next_url": "https://api.quant-aq.com/device-api/v1/log/SN000-041/?page=2&per_page=2&limit=4",
        "page": 1,
        "pages": 1002,
        "per_page": 2,
        "prev_url": null,
        "total": 4
    }
}

Advanced Queries

Most QuantAQ Cloud API endpoints support advanced queries that allow you to filter, limit, and sort your results. All endpoints that return paginated data - such as retrieving data points - support these features.

Filtering requests

To filter a query, use the filter keyword argument with the format filter=<parameter>,<filter spec>,<value>. Multiple filters can be combined together via ; to build complex queries. For example, if we want to return the data where PM2.5 is between 25 and 50 µg/m3, we would write filter=pm25,ge,25;pm25,le,50;.

A full request might look like:

$ http -a <your-api-key-here>: GET "https://api.quant-aq.com/device-api/v1/devices/<serial number>/data/?filter=pm25,ge,25;pm25,le,50;"

The following filter specs are available to use:

  • eq: = (equals)
  • ne: ≠ (not equals)
  • lt: < (less than)
  • gt: > (greater than)
  • ge: ≥ (greater than or equal to)
  • le: ≤ (less than or equal to)
  • in: in
  • like: like

Limiting requests

To limit the number of data points returned for any given request, use the limit keyword argument with the number of data you would like returned. For example, to only return the first 5 items, use limit=5. If you are calling an endpoint that returns paginated data and would like to return a specific number of data per page, you can alternatively (or additionally) use the per_page keyword argument.

Sorting requests

To return data in a specific order, you can use the sort keyword argument with format sort=<parameter>,<order> where <order> is one of asc or desc. For example, if you want to return the data descended by timestamp:

$ http -a <your-api-key-here>: GET "https://api.quant-aq.com/device-api/v1/devices/<serial number>/data/?sort=timestamp,desc"

Other Resources

SDKs

py-quantaq

py-quantaq is the official python API wrapper for the QuantAQ Cloud API and is maintained and supported by QuantAQ. Full documentation can be found here. For questions specific to py-quantaq, please use the GitHub repository issues page.

Changelog

January 11th, 2021

  • The devices/ endpoint was updated to allow for a new parameter (team) which permits users to query available devices by a team name. Simply add ?team=team-1 and you will only be returned the available devices for the requested team. If the team name does not exist or have any devices, nothing will be returned. If you would like to return all available devices across all of your teams, simply omit the team parameter as before.