💥 Breaking Change

Graduating Airthings REST API from Beta

Over the last few months we have been iterating the Airthings REST API together with our passionate early users. We have received a lot of valuable feedback and implemented updates accordingly.

With this release we are graduating the Airthings REST API from Beta. The motivation for the changes in this update is to improve consistency and usability of the API. We do not foresee any more breaking changes, and potential future breaking changes will result in a version update of the API.

The Swagger documentation has been updated to reflect these changes. Play with the new version, and download it here. (API documentation will be updated as well).

The API will be updated on 2019-11-25.

We hope that the changes do not cause you any inconvenience. Please reach out to Airthings for Business Support for any clarifications or with any questions.

✨ Improvements

Planned changes (swagger-diff):

  • new endpoints for getting location and latest sample of all devices in a location
    • get /locations/{}
    • get /locations/{}/latest-samples
  • new response attributes
    • get /devices
      • new attribute in response: segment/id (in: body, type: string)
      • new attribute in response: segment/name (in: body, type: string)
      • new attribute in response: location/id (in: body, type: string)
      • new attribute in response: location/name (in: body, type: string)
    • get /devices/{}
      • new attribute in response: segment/id (in: body, type: string)
      • new attribute in response: segment/name (in: body, type: string)
      • new attribute in response: location/id (in: body, type: string)
      • new attribute in response: location/name (in: body, type: string)
    • get /locations
      • new attribute from response: locations[]/name (in: body, type: string). This replaces removed attribute locations[]/locationName
    • get /segments
      • new attribute in response: segments[]/deviceId (in: body, type: string). This replaces removed attribute segments[]/serialNumber
      • new attribute in response: location/id (in: body, type: string)
      • new attribute in response: location/name (in: body, type: string)

Example GET /segments endpoint:

  • locationName is replaced by an object.
  • serialNumber is deviceId.

The old vs. new response from the GET /segments endpoint:

{
  "segments": [
    {
        "id": "f3f247b7-829b-427e-8add-b9d58e94ba75",
        "started": "2032-02-05T23:57:12Z",
        "ended": "2019-07-23T10:05:45Z",
        "name": "Bedroom",
        "locationId": "3cc69a8b-5b51-416f-8e01-31ccc7fbda9b",
        "serialNumber": "2930999999"
    }
  ]
}
{
  "segments": [
    {
        "id": "f3f247b7-829b-427e-8add-b9d58e94ba75",
        "started": "2032-02-05T23:57:12Z",
        "ended": "2019-07-23T10:05:45Z",
        "name": "Bedroom",
        "location": {
            "id": "3cc69a8b-5b51-416f-8e01-31ccc7fbda9b",
            "name": "Home"
        },
        "deviceId": "2930999999"
    }
  ]
}

Example GET /locations endpoint:
The old vs. new response from GET /locations:

{
  "locations": [
    {
      "id": "b4e8231b-672f-4e75-b7f0-04ccbd499508",
      "locationName": "Drammensveien 288"
    }
  ]
}
{
  "locations": [
    {
      "id": "b4e8231b-672f-4e75-b7f0-04ccbd499508",
      "name": "Drammensveien 288"
    }
  ]
}

📝 Documentation

The developer documentation has been updated with tutorials on how to use the Airthings API. This includes two guides on how to fetch your Airthings data using either python or node.js and a guide for setting up an automatic SMS messaging service by combining Twillio and Airthings webhooks. The former two guides will help you register your application and provide a starting point for developing an Airthings integrated solution, whereas the latter guide can be utilized to send SMS notifications in the case a threshold value is breached, such as high radon levels or high temperatures.

🚀 Feature Release

The authentication capabilities of the API have been extended to support an OAuth2 Client Credentials grant for machine-to-machine usage.

Select Client Credentials as flow type when creating/updating your API Client in the Dashboard. Then you should be able to use the client_id and secret of the client to obtain an access token.

curl -X POST \
  https://accounts-api.airthings.com/v1/token \
  -H 'Content-Type: application/json' \
  -d '{
	"grant_type":"client_credentials",
	"client_id":"b8a19a7d-64cd-4281-xxxx-xxxxxxxxxxxx",
	"client_secret":"82bfed8b-793a-4423-xxxx-xxxxxxxxxxxx"
}'
{
    "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjMTQ4ODQ1ZC0zNDc4LTRkYjAtOGI2My0yM2QxNGU5Y2EwYWMiLCJhdWQiOiJiOGExOWE3ZC02NGNkLTQyODEtYjUxNS0zZmZhY2M3MjZmZTMiLCJuYmYiOjE1NzMxMjkzNDEsImF6cCI6ImI4YTE5YTdkLTY0Y2QtNDI4MS1iNTE1LTNmZmFjYzcyNmZlMyIsInNjb3BlIjoicmVhZDpkZXZpY2UiLCJpc3MiOiJodHRwczpcL1wvYWNjb3VudHMuYWlydGhpbmdzLmNvbSIsImhicyI6InRydWUiLCJ0eXAiOiJCRUFSRVIiLCJleHAiOjE1NzMxNDAxNDEsImlhdCI6MTU3MzEyOTM0MSwianRpIjoiOTY5NGI4YzctNDEwZi00NjljLTg5YjUtOWY1YjA1NjdiM2ViIn0.s0KvfAs8VtutsusODZMeZHCEkCu5Oecfid1h1LUPhJqB5oe5WCs-TPRQ4oo7cIRDxBK4iTErapwu_QO4AHraQtfkhnRNcWgxhIW7c_3GQik2st6duaud--VIixze1blUKyqdZFRWUFSrgXP4bmxgGO6_x5HtnoCvjPfFwX5H5Xdn8g7FkV1GyGf0caQFUerk-eXjSU8z3CxjD_DD5fG_5FBr5rNpn7PHmc-y7PgBKJmB7CgdOr8ZqpW1PfseRociOGQCgfDNNiHsmd3Q0aGeLx1jnG4yDFT4EZwksH9zQfOb-j_vxo8uCegXGrTJiMDxV4ehniNtXgtgl_SHuJVUtQzo_hbwA6aobQHbrhwIa8UIKy8bxg2D-eMDnFDMeJP7WoV4WrpSiBL_sWv49uva4F_VI-uEl4qS6nopE24z5-wWVuwJsryZH6e8gqSBUTLE4xKN0xol-ESQjekdpkYTbTAnGD3jlZYtJAze63LqXYcom4DYh375nzdV7nd7CRPf6afFlR-h3MQorEEIehiYaBR7VojJlOYgfRD3mHKMmGhVGwMftraE2E1smC8wRQHBtclZ5gdZiMlGiXj2yBuUzFKJLCIb6IZqL23gTJW-nWJZ8WodL8vVg_VY955pvHEbGI6dp8Jiavqb-VjEsGKxhzWczIDjFQ_pV0zy3IsesRo",
    "token_type": "Bearer",
    "expires_in": 10800
}

Improvement

An additional update to webhooks. It is now possible to add headers (up to 3) to the configuration. These headers will be passed on in each request from the webhook. The idea is to support receiving endpoints behind some basic auth and api-keys.

In the same update we enable key-value labels to be added to the payload. These are meant to support custom metadata to be added to each event posted from the webhooks.

An example event with a label for the region, europe:

{
  "id": "91f7fc45-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "type": "airthings-webhook-cloudevent-sample-feed",
  "source": "accounts.airthings.com/webhooks/17995b45-26e9-47e2-8af7-7267f7d89bc0",
  "dataContentType": "application/json",
  "labels": {"region" : "europe"},
  "data": [
    {
      "serialNumber": "2930001150",
      "recorded": "2019-10-17T12:20:49",
      "radonShortTermAvg": 14,
      "humidity": 56.5,
      "temp": 22.3,
      "co2": 644,
      "pressure": 1010,
      "tvoc": 112
    },
    {
      "serialNumber": "2930001151",
      "recorded": "2019-10-17T12:20:48",
      "radonShortTermAvg": 11,
      "humidity": 56.1,
      "temp": 22.1,
      "co2": 641,
      "pressure": 1011,
      "tvoc": 111
    }
  ],
  "time": "2019-10-17T12:22:53.650000",
  "specVersion": "0.2"
}