NAV Navbar
shell
  • Introduction
  • The Basics
  • Authentication
  • Networks
  • Sensors
  • Sites
  • Packets
  • Alerts
  • Users
  • Errors
  • Introduction

    So you want to use Wintersense data in your own application? Then you've come to the right place!

    Here we describe the various HTTPS requests you can use to pull data from our platform.

    Please begin with The Basics and Authentication. It helps to understand these sections before continuing to the sections that detail specific data requests.

    The Basics

    Here's an example request (gets a list of all your networks)

    curl "https://api.wintersense.com/v1/networks"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    As with most requests the response is JSON formatted:

    [
      {
        "id": "59a68id13fd7ri8e9ea4432c",
        "name": "Gotham City",
        "description": "A network of road temperature sensors for those Dark Knights.",
        "access": "private",
        "level": "admin",
        "createdAt": "2017-08-29T15:48:33.015Z",
        "updatedAt": "2017-09-04T17:38:42.345Z"
      },
      {
        "id": "59a66id13fd6ro8u9ea4562t",
        "name": "Metropolis",
        "description": "A super network of sensors managed by the Daily Planet.",
        "access": "private",
        "level": "basic",
        "createdAt": "2017-07-29T08:48:23.085Z",
        "updatedAt": "2017-09-01T10:29:12.945Z"
      }  
    ]
    

    Base URL

    The base URL for all API requests is:

    https://api.wintersense.com/v1

    The /v1 denotes the version number, i.e. this documentation is for version 1 of our API (currently the only version).

    You then add to this URL depending on the resource you wish to access. e.g. adding /networks to access your networks.

    HTTP Verbs

    As this is a REST API we've tried to use the appropriate HTTP verb (e.g. GET, POST, DELETE, PATCH) where possible. For example, we create a new site with POST, retrieve its details with GET, change its name with PATCH, and remove it with DELETE.

    The appropriate HTTP verb is shown in front of each request. e.g:

    GET https://api.wintersense.com/v1/networks

    Path Segments

    Many of the paths you'll see below include path segments into which a specific value should be inserted. Take, for example, the following path:

    GET https://api.wintersense.com/v1/networks/{networkId}/sites

    Here we expect you to replace {networkId} with the Network ID of your own site. These path segments will always be indicated by the surrounding curly braces. Thus the actual request would look like:

    GET https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites

    Request Body Fields

    Here's an example that includes a JSON body in the request (this particular request would create a new Network):

    curl "https://api.wintersense.com/v1/networks"
      -X POST
      -H "Authorization: apiKey yourApiKeyGoesHere"
      -H "Content-Type: application/json"
      -d '{
            "name": "Gotham City", 
            "description": "A network of road temperature sensors for those Dark Knights."
          }'
    # N.B. in practise you should enter this command as a single line; we're just showing it like this for readability.
    

    When we ask you to perform a POST request we usually expect content in the request body. We expect the body to be JSON formatted.

    Response

    Typically the response will have a JSON formatted body (unless we specifically say otherwise).

    A 2xx status code indiactes a successful request, e.g. most requests respond with 200, but requests that create a resource will respond with 201, and requests that delete a resource will respond with 204 as there's no content to return.

    Please see the section on Errors for an overview of the types of error responses you may expect to see when something goes wrong.

    Authentication

    To authorize a request add your api key to the Authorization header as follows:

    curl "https://api.wintersense.com/v1/networks"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Make sure to replace yourApiKeyGoesHere with your API key.

    The easiest way to authenticate and authorise a request is using an API Key. To generate an API Key you will need to log in to the Wintersense Web Application and go to the Account section. Here you can generate an API Key if you don't already have one, or refresh an existing key.

    N.B. you can only generate/refresh an API Key from within the Wintersense Web Application.

    Whenever you request data from our API you should include the API Key in the Authorization header, preceded by the text apiKey, so we know you're using this form of authentication. e.g:

    Authorization: apiKey abcd1234

    Networks

    The structure of our API revolves around Networks; until you've created a network there's very little you can do. However, once you have a network you can then add Sensors and Sites to begin collecting observations.

    Different users may have a different level of access to a given network. From full admin level rights, down to the basic level. Note how certain requests below can only be performed by users with a certain level. For more information about these levels please consult the Rights Levels Explained section.

    Create Network

    Here's an example of creating a Network:

    curl "https://api.wintersense.com/v1/networks"
      -X POST
      -H "Authorization: apiKey yourApiKeyGoesHere"
      -H "Content-Type: application/json"
      -d '{
            "name": "Gotham City", 
            "description": "A network of road temperature sensors for those Dark Knights."
          }'
    

    POST https://api.wintersense.com/v1/networks

    Properties you can set

    Property Required Description
    name Yes The name of your Network. Limited to a max of 30 characters.
    description No A description of your Network. Useful for storing any extra metadata about the Network. Limited to a max of 1000 characters.

    Get all your Networks

    Get a list of all the Networks you have rights to using:

    curl "https://api.wintersense.com/v1/networks"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    [
      {
        "id": "59a68id13fd7ri8e9ea4432c",
        "name": "Gotham City",
        "description": "A network of road temperature sensors for those Dark Knights.",
        "access": "private",
        "level": "admin",
        "createdAt": "2017-08-29T15:48:33.015Z",
        "updatedAt": "2017-09-04T17:38:42.345Z"
      },
      {
        "id": "59a66id13fd6ro8u9ea4562t",
        "name": "Metropolis",
        "description": "A super network of sensors managed by the Daily Planet.",
        "access": "private",
        "level": "basic",
        "createdAt": "2017-07-29T08:48:23.085Z",
        "updatedAt": "2017-09-01T10:29:12.945Z"
      }  
    ]
    

    GET https://api.wintersense.com/v1/networks

    Network Properties

    Property Description
    id The Network's unique ID. Whenever you see {networkId} written within a URL, you should replace it with a Network ID such as this.
    name The name of your Network.
    description A description of your Network.
    level What rights level you have to this Network, e.g. admin, engineer, basic.
    createdAt When the Network was created. An ISO 8601 formatted string.
    updatedAt When the Network's details were last updated. An ISO 8601 formatted string.

    Get Single Network

    Add the Network's ID to the URL to retrieve its details, e.g:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    {
      "id": "59a68id13fd7ri8e9ea4432c",
      "name": "Gotham City",
      "description": "A network of road temperature sensors for those Dark Knights.",
      "access": "private",
      "level": "admin",
      "createdAt": "2017-08-29T15:48:33.015Z",
      "updatedAt": "2017-09-04T17:38:42.345Z"
    }
    

    GET https://api.wintersense.com/v1/networks/{networkId}

    For when you want information about a given Network.

    Update Network

    Here's how you would change a Network's description:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c"
      -X PATCH
      -H "Authorization: apiKey yourApiKeyGoesHere"
      -H "Content-Type: application/json"
      -d '{
            "description": "A network of road temperature sensors to track Mr Freeze."
          }'
    

    Returns the complete Network object with the updates applied:

    {
      "id": "59a68id13fd7ri8e9ea4432c",
      "name": "Gotham City",
      "description": "A network of road temperature sensors to track Mr Freeze.",
      "access": "private",
      "level": "admin",
      "createdAt": "2017-08-29T15:48:33.015Z",
      "updatedAt": "2017-09-22T13:18:42.365Z"
    }
    

    PATCH https://api.wintersense.com/v1/networks/{networkId}

    As is commonly the case when using the PATCH method you only need to specify the properties you wish to update, i.e. you don't have to include all of the Network's details in the request body. For example you can just update the Network's description without having to include any other properties.

    As shown in the table in the Create a Network section, the only Network properties you can update are its name and description.

    Delete Network

    Example request that deletes a network:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Or to leave only use:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c?leaveOnly=true"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Either way the response will have no content and thus has a status code of 204.

    DELETE https://api.wintersense.com/v1/networks/{networkId}

    If you only want to leave the network, so that other Users of the Network can still access it then add leaveOnly=true as a URL query string parameter.

    Sensors

    A Sensor is the physical device that gets deployed. Typically you would install a single Sensor at each Site.

    Note how you don't "create" or "delete" a Sensor, the Sensor details are already permanently stored in our database, instead you "bind" and "unbind" Sensors to your Network as and when you need to.

    Bind Sensor to Network

    Here's how you use the Sensor's key to add it to a Network:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sensors"
      -X POST
      -H "Authorization: apiKey yourApiKeyGoesHere"
      -H "Content-Type: application/json"
      -d '{
            "key": "maqetaxaku"
          }'
    

    Just be sure to replace the example key used here (i.e. "maqetaxaku") with your own sensor key.

    The response includes more details about the sensor:

    {
      "key": "maqetaxaku",
      "id": "111222",
      "sensorType": "SIGFOX-GEN1-SURFACE",
      "network": "59a68id13fd7ri8e9ea4432c"
    }
    

    POST https://api.wintersense.com/v1/networks/{networkId}/sensors

    Before you can access the data a Sensor collects you first need to bind it to your Network (later you'll Bind the Sensor to a Site too).

    Each sensor has its own unique key, which should be written on the device itself. This is a semi-pronounceable, random string such as maqetaxaku. It's this key that you'll use to add each sensor to your network.

    Why do I have to do this? - The reasoning behind this step is security. Once you bind a sensor to your Network then it can no longer be added to any other Networks. Even if somebody looked at the sensor whilst it was installed and wrote down its key they still wouldn't be able to add it to their own Network as it's already been bound to yours.

    Get Network Sensors

    Example request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sensors"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    [
      {
        "key": "maqetaxaku",
        "id": "111222",
        "sensorType": "SIGFOX-GEN1-SURFACE",
        "network": "59a68id13fd7ri8e9ea4432c"
      },
      {
        "key": "tedapigelo",
        "id": "333444",
        "sensorType": "SIGFOX-GEN1-SURFACE",
        "network": "59a68id13fd7ri8e9ea4432c",
        "site": "59b58e730fd77e0d9ea5232g"
      }  
    ]
    

    Note how the first sensor hasn't been bound to a Site yet but the second one has.

    GET https://api.wintersense.com/v1/networks/{networkId}/sensors

    Retrieve a list of all the sensors already bound to your Network.

    Sensor Properties

    Property Description
    key The unique key used to add the sensor to the Network.
    id The sensor's ID. Sent by the sensor when it uploads its data. It's how the sensor identifies itself on the communications network. This ID is only unique when used in combination with the sensorType property. i.e. no two sensors can have the same id and sensorType combination, however in theory two sensors could have the same id, but belong to different sensorTypes.
    sensorType The type of sensor. Has the format: COMMS-GENERATION-MEASURES, i.e. what comms does it use to upload its data, what generation of sensor is it, and what variable is it trying to measure. Can be used in combination with the sensor id as a unique identifier.
    network The ID of the network it is bound to.
    site The ID of the site it is bound to, if it has been yet.

    Each sensor can only be bound to one Site at a time. If the Sensor doesn't have a site property then it is free to be Bound to a Site.

    Get Single Network Sensor

    Example request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sensors/111222_SIGFOX-GEN1-SURFACE"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    {
      "key": "maqetaxaku",
      "id": "111222",
      "sensorType": "SIGFOX-GEN1-SURFACE",
      "network": "59a68id13fd7ri8e9ea4432c"
    }
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sensors/{id}_{sensorType}

    Retrieve the details of a single sensor bound to your Network.

    Unbind Sensor from Network

    Example request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sensors/111222_SIGFOX-GEN1-SURFACE"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns a 204 response as there's no content to return.

    DELETE https://api.wintersense.com/v1/networks/{networkId}/sensors/{sensorId}_{sensorType}

    Unbinds the Sensor from the Network, after which it is then available to bind to another Network.

    As mentioned previously the Sensor's id is not unique and thus both the id and sensorType are required in the URL.

    Sites

    A Site is the location where you want to make measurements. Sensors are deployed at Sites. We keep Sensors and Sites as separate entities as it makes it simplier to move Sensors between Sites.

    Here's an example scenario to help explain this point better:

    1. First you create a new Network.
    2. Then you bind multiple Sensors to the Network.
    3. Next you create multiple Sites, i.e. for each location you're interested in collecting data at. At this stage none of the Sensors are contributing data to any of the Sites.
    4. An engineer visits a Site and selects a Sensor(s) to deploy at that location. Once installed they should bind the Sensor(s) to the Site. The Sensor(s) are now contributing data to this Site.
    5. Several years later you may wish to swap a Sensor at a Site with a new one. At which point you simply need to unbind the original Sensor and bind the replacement. This maintains a continous record of packets for the Site. Alternatively you may wish to move a Sensor to a new location, in which case you would create a Site for the new location, then unbind the Sensor from the first Site, phycially move the Sensor to the new location, then bind it to the new Site.

    Create Site

    Example:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites"
      -X POST
      -H "Authorization: apiKey yourApiKeyGoesHere"
      -H "Content-Type: application/json"
      -d '{
            "name": "Arkham Asylum Roundabout", 
            "description": "Please get clearance from security guards before visiting to install."
            "location": {
              "lat": 51.449957,
              "lon": -0.177722
            }
          }'
    

    Example response:

    {
        "id": "59a58d744fd79e0d9ba4233f",
        "name": "Arkham Asylum Roundabout",
        "description": "Please get clearance from security guards before visiting to install.",
        "type": "static",
        "network": "59a68id13fd7ri8e9ea4432c",
        "location": {
          "lat": 51.449957,
          "lon": -0.177722
        },
        "createdAt": "2017-10-06T14:38:57.153Z",
        "updatedAt": "2017-10-06T14:38:57.153Z",
        "sensors": []
    }
    

    POST https://api.wintersense.com/v1/networks/{networkId}/sites

    Properties you can set

    Property Required Description
    name Yes The name of the Site. Limited to 30 characters.
    description No Any extra information about the Site you wish to add for future reference. Limited to 1000 characters.
    location Yes An object denoting the latitude and longitude of the Site. Must have lat and lon properties, e.g. as follows: {lat: 52.123456, lon: -1.123456}.

    Get Network Sites

    Example Request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example Response:

    [
      {
          "id": "59a58d744fd79e0d9ba4233f",
          "name": "Arkham Asylum Roundabout",
          "description": "Please get clearance from security guards before visiting to install.",
          "type": "static",
          "network": "59a68id13fd7ri8e9ea4432c",
          "location": {
            "lat": 51.449957,
            "lon": -0.177722
          },
          "createdAt": "2017-10-06T14:38:57.153Z",
          "updatedAt": "2017-10-06T14:38:57.153Z",
          "sensors": [{
            "id": "111222",
            "sensorType": "SIGFOX-GEN1-SURFACE"
          }]
      },
      {"etc": "etc"}
    ]
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sites

    Get a list of all the Sites in this Network.

    Query Parameters

    Name Defaults to Description
    includeSensors true If you're not interested in knowing which sensors are bound to each site then set this as false. The sensors property will then be omitted from Site objects in the response.

    Site Properties

    Property Description
    id The unique ID of this Site. If a URL contains {siteId} then you should replace it with this id.
    name The name of the Site.
    description Extra metadata about the Site.
    location An object containing the Site's latitude (lat) and longitude (lon).
    sensors An array of objects, where each object is a Sensor bound to this Site. The object contains the Sensor's id and sensorType properties.
    createdAt When the Site was created (ISO 8601 format).
    updatedAt when the Site was last updated (ISO 8601 format).

    Get Single Network Site

    Example Request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example Response:

    {
        "id": "59a58d744fd79e0d9ba4233f",
        "name": "Arkham Asylum Roundabout",
        "description": "Please get clearance from security guards before visiting to install.",
        "type": "static",
        "network": "59a68id13fd7ri8e9ea4432c",
        "location": {
          "lat": 51.449957,
          "lon": -0.177722
        },
        "createdAt": "2017-10-06T14:38:57.153Z",
        "updatedAt": "2017-10-06T14:38:57.153Z",
        "sensors": [{
          "id": "111222",
          "sensorType": "SIGFOX-GEN1-SURFACE"
        }]
    }
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}

    Get the details of a single Site.

    Update Site

    In this example the description is updated:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites"
      -X PATCH
      -H "Authorization: apiKey yourApiKeyGoesHere"
      -H "Content-Type: application/json"
      -d '{
            "description": "Please get clearance from villians before visiting to install."
          }'
    

    Response:

    {
        "id": "59a58d744fd79e0d9ba4233f",
        "name": "Arkham Asylum Roundabout",
        "description": "Please get clearance from villians before visiting to install.",
        "type": "static",
        "network": "59a68id13fd7ri8e9ea4432c",
        "location": {
          "lat": 51.449957,
          "lon": -0.177722
        },
        "createdAt": "2017-10-06T14:38:57.153Z",
        "updatedAt": "2017-11-13T10:49:37.121Z",
        "sensors": [{
          "id": "111222",
          "sensorType": "SIGFOX-GEN1-SURFACE"
        }]
    }
    

    PATCH https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}

    Updates a Site's details. See the Create Site section for a list of properties you can set.

    Note that this is not how you add or remove Sensors to the Site, instead use Bind Sensor to Site and Unbind Sensor from Site respectively.

    Bind Sensor to Site

    Example (N.B. you don't need to add any content to the request body for this request):

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f/111222_SIGFOX-GEN1-SURFACE"
      -X POST
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns the Site object with the Sensor added to the sensors array.

    {
        "id": "59a58d744fd79e0d9ba4233f",
        "name": "Arkham Asylum Roundabout",
        "description": "Please get clearance from villians before visiting to install.",
        "type": "static",
        "network": "59a68id13fd7ri8e9ea4432c",
        "location": {
          "lat": 51.449957,
          "lon": -0.177722
        },
        "createdAt": "2017-10-06T14:38:57.153Z",
        "updatedAt": "2017-11-13T10:49:37.121Z",
        "sensors": [{
          "id": "111222",
          "sensorType": "SIGFOX-GEN1-SURFACE"
        }]
    }
    

    POST https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}/sensors/{sensorId}_{sensorType}

    Bind a Sensor to a Site. Note that you can have multiple Sensors bound to a given Site, but it only really makes sense to do this if the Sensors are measuring different variables.

    Get Site Sensors

    Example:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f/sensors"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns an array of Sensors:

    [
      {
        "id": "111222",
        "sensorType": "SIGFOX-GEN1-SURFACE"
      }
    ]
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}/sensors

    Get a list of all the Sensors bound to a given Site.

    Unbind Sensor from Site

    Example:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f/111222_SIGFOX-GEN1-SURFACE"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns the Site object, with the Sensor removed from the Sites array:

    {
      "id": "59a58d744fd79e0d9ba4233f",
      "name": "Arkham Asylum Roundabout",
      "description": "Please get clearance from villians before visiting to install.",
      "type": "static",
      "network": "59a68id13fd7ri8e9ea4432c",
      "location": {
        "lat": 51.449957,
        "lon": -0.177722
      },
      "createdAt": "2017-10-06T14:38:57.153Z",
      "updatedAt": "2017-11-13T10:49:37.121Z",
      "sensors": []
    }
    

    DELETE https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}/sensors/{sensorId}_{sensorType}

    Removes the Sensor from the Site. The Sensor is then free to be added to another Site, e.g. if you decide to move the Sensor to a new location.

    Delete Site

    Example request that deletes a network:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns a 204 as the response body will have no content.

    DELETE https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}/

    Deletes a site from your Network.

    Packets

    Now for the data you're really interested in: the sensor readings! Every time a sensor uploads a set of observations we call this a packet. It includes the readings themselves along with other metadata such as the time the observations were made and which sensor took them.

    Packet Properties

    Example packet including a selection of obs:

    {
      "id": "59d656bed46dc21c28b847ab",
      "sensor": "111222",
      "sensorType": "SIGFOX-GEN1-SURFACE",
      "obsTime": "2017-10-05T15:58:54.000Z",
      "arrivalTime": "2017-10-05T15:58:55.865Z",
      "network": "59a68id13fd7ri8e9ea4432c",
      "site": "59a58d744fd79e0d9ba4233f",
      "obs": {
        "rst": {
          "value": -1.41,
          "corr": -0.1
        },
        "at": {
          "value": 2.36,
          "flags": ["persistence"]
        },
        "rssi": {
          "value": -64
        },
        "battery": {
          "value": 3.129
        }
      },
    }
    

    Here's a breakdown of what the various fields in a packet mean:

    property description
    id The unique ID for this packet
    sensor The ID of the Sensor that submitted the packet
    sensorType The type of Sensor that submitted the packet
    obsTime When the observations were made (in ISO 8601 format)
    arrivalTime When the packet arrived at the Wintersense servers (in ISO 8601 format)
    network The ID of the Network that the Sensor and Site belong to.
    site The ID of the Site to which to the Sensor is bound.
    obs Please see the Obs section.

    Obs

    A typical obs object you might find within a packet:

    {
      ...
      "obs": {
        "rst": {
          "value": -1.41,
          "corr": -0.1
        },
        "at": {
          "value": 2.36,
          "flags": ["persistence"]
        },
        "rssi": {
          "value": -64
        },
        "battery": {
          "value": 3.129
        }
      }
    }
    

    Every packet will contain some observations, or obs for short. For packets requested in JSON format obs is a nested object within the packet object. Each key in this obs object denotes the variable being measured.

    Here's what the various obs keys stand for:

    Key Variable Units
    battery Battery Level V
    rssi Signal Strength dBm
    rst Surface Temperature °C
    at Air Temperature °C
    rh Relative Humidity %
    ms Moisture %
    sp Surface Pressure mb
    ws Wind Speed mph
    wd Wind Direction °
    rr Rain Rate mm/hr

    Most packets will only contain a small subset of these obs, depending on the type of Sensor they've come from.

    For example, Wintersense's road surface temperature sensors commonly upload packets containing Surface Temperature (rst), Air Temperature (at), Battery Level (battery) and Signal Strength (rssi) values.

    Each of these obs variables will have a value along with optional corr and flags properties, as explained below:

    Property Description
    value The actual measurement.
    corr Stands for correction. If it is present then its value has already been added to the value, e.g. to correct for a bias.
    flags An array of strings, with each string denoting a specific flag. A flag indicates suspect data.

    Flags

    The example below shows part of a packet. It highlights that the rst (road surface temperature) value of -111 falls below the expected climatic range as indicated by the "lowerbound" flag, and the "persistence" flag indicates that it has been stuck at this value for some time.

    {
      ...
      "obs": {
        "rst": {
          "value": -111,
          "flags": ["persistence", "lowerbound"]
        }
      }
    }
    

    Whenever a Sensor uploads a packet to the Wintersense servers, the packet passes through several quality control checks. These checks will flag observations that appear suspect, making it easier for you to filter them out if you wish.

    The following table details the various flags that may be added to the flags array.

    Flag Description
    persistence When a Site submits the same value for a particular obs variable multiple times in a row. By default the Wintersense platform will add this flag if a value appears 10 or more times consecutively.
    lowerbound When a value is below the expected lower limit for the given obs variable.
    upperbound When a value is above the expected upper limit for the given obs variable.
    lowspike When a value is dramatically lower than those before it.
    highspike When a value is dramatically higher than those around it.
    ambientdiscrepancy For sensors measuring surface temperature with an infrared sensor this flag is added when the body temperature of the infrared sensor is dramatically different than the ambient (air) temperature. A significant difference will usually mean that the surface temperature readings are no longer accurate. This flag is only ever added to the rst flags array.

    Get Packets (Multiple Sites)

    Retrieves packets from all the Sites in your Network in a single request.

    JSON Format

    Here we ask for JSON formatted packets from all sites, between specific start and end dates, with any flagged data removed:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/packets.json?startDate=2017-12-24T16:00:00Z&endDate=2017-12-25T12:00:00Z&removedFlagged=true"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    The response is an JSON object containing a metadata object and sites array. The metadata object includes basic metadata about the packets, including information about the network. The sites array contains an object for each site, which includes information about the site along with a packets array that contains the packets submitted by this site over the given time frame.

    {
      "metadata" : {
        "startDate": "2017-12-24T16:00:00Z",
        "endDate": "2017-12-25T12:00:00Z",
        "latest": false,
        "removeFlagged": true,
        "network": {
          "id": "59a68id13fd7ri8e9ea4432c",
          "name": "Gotham City",
          "level": "admin",
          "access": "private",
          "createdAt": "2017-08-29T15:48:33.015Z",
          "updatedAt": "2017-09-04T17:38:42.345Z"
        }
      },
      "sites": [
        {
          "id": "59a58d744fd79e0d9ba4233f",
          "type": "static",
          "name": "Arkham Asylum Roundabout",
          "description": "Please get clearance from security guards before visiting to install.",
          "network": "59a68id13fd7ri8e9ea4432c" ,
          "location": {
            "lat": 51.449957,
            "lon": -0.177722
          },
          "createdAt": "2017-10-06T14:38:57.153Z",
          "updatedAt": "2017-10-06T14:38:57.153Z",
          "packets": [
            {
              "id": "59d656bed46dc21c28b847ab",
              "sensor": "111222",
              "sensorType": "SIGFOX-GEN1-SURFACE",
              "obsTime": "2017-12-24T16:03:50.020Z",
              "arrivalTime": "2017-12-24T16:03:50.865Z",
              "network": "59a68id13fd7ri8e9ea4432c",
              "site": "59a58d744fd79e0d9ba4233f",
              "obs": {
                "rst": {
                  "value": -1.41,
                  "corr": -0.1
                },
                "rssi": {
                  "value": -64
                },
                "battery": {
                  "value": 3.129
                }
              },
            },
            {"etc": "etc"}
          ]
        },
        {"etc": "etc"}
      ]
    }
    

    N.B. if you specify that you want the latest packets only using the query parameter latest=true, the packet structure will change slightly. This is because the latest values for the various obs variables may have different observation times and come from different sensors. As such the obsTime, sensor and sensorType fields are now included for each of the obs variables, for example:

    {
      "network": "59a68id13fd7ri8e9ea4432c",
      "site": "59a58d744fd79e0d9ba4233f",
      "obsTime": "2017-12-24T16:03:50.020Z",
      "arrivalTime": "2017-12-24T16:03:50.865Z",
      "obs": {
          "rst": {
              "value": -1.29,
              "sensor": "111222",
              "sensorType": "SIGFOX-GEN1-SURFACE",
              "obsTime": "2017-12-24T15:58:50.060Z"
          },
          "rssi": {
              "value": -64,
              "sensor": "111222",
              "sensorType": "SIGFOX-GEN1-SURFACE",
              "obsTime": "2017-12-24T16:03:50.020Z"
          },
          "battery": {
              "value": 3.129,
              "sensor": "111222",
              "sensorType": "SIGFOX-GEN1-SURFACE",
              "obsTime": "2017-12-24T16:03:50.020Z"
          }
      }
    }
    

    GET https://api.wintersense.com/v1/networks/{networkId}/packets.json

    Query Parameters

    Add a selection of the following query string parameters to help filter the data. All of these parameters are optional.

    Name Defaults to Description
    startDate 1 hour ago, or 1 hour before the endDate if the endDate is provided. Specifies the start of the period for which you want packets. Should be in ISO 8601 format, e.g. 2017-12-24T16:00:00Z
    endDate Now, or 1 hour after the startDate if the startDate is provided. Specifies the end of the period for which you want packets. Should be in ISO 8601 format, e.g. 2017-12-25T12:00:00Z
    sites All Sites Allows you to request packets from a subset of sites. Format as a comma-separated list of Site IDs e.g. 59a58d744fd79e0d9ba4233f,59a58a8e1fd78d0d9ea42631.
    obs All obs Allows you to request only certain observations. Format as a comma-separated list, e.g. rst,battery would only return surface temperature and battery observations.
    latest false If true then only one packet per site is returned, i.e. the latest packet within the specified time period.
    removeFlagged false Set as true to remove any obs that have been flagged, false to leave flagged obs in, or a comma-separated list of obs keys, e.g. rst,at to remove flagged obs for only these variables.

    CSV Format

    Example request for packets in CSV format where we only request surface temperature and battery data over a 15 minute period:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/packets.csv?startDate=2017-10-06T16:45:00Z&endDate=2017-10-06T17:00:00Z&obs=rst,battery"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    Site Name,Site ID,Observation Time (UTC),Arrival Time (UTC),Sensor ID,Sensor Type,Surface Temp Value (degC),Battery Level Value (V)
    Arkham Asylum Roundabout,59a58d730fd78e0d9ea4232f,2017-10-06T16:48:53.000Z,2017-10-06T16:58:52.939Z,101745,WIFI-GEN1-SURFACE,1.37,3.21
    Arkham Asylum Roundabout,59a58d730fd78e0d9ea4232f,2017-10-06T16:53:53.000Z,2017-10-06T16:58:52.939Z,101745,WIFI-GEN1-SURFACE,1.29,3.20
    Arkham Asylum Roundabout,59a58d730fd78e0d9ea4232f,2017-10-06T16:58:53.000Z,2017-10-06T16:58:52.823Z,101745,WIFI-GEN1-SURFACE,1.33,3.20
    Bat Cave,59a58a8e1fd78d0d9ea42631,2017-10-06T16:46:44.000Z,2017-10-06T16:21:44.000Z,196443,SIGFOX-GEN1-SURFACE,2.18,2.99
    Bat Cave,59a58a8e1fd78d0d9ea42631,2017-10-06T16:51:47.000Z,2017-10-06T16:51:47.000Z,196443,SIGFOX-GEN1-SURFACE,2.32,2.98
    

    GET https://api.wintersense.com/v1/networks/{networkId}/packets.csv

    Query Parameters

    Add a selection of the following query string parameters to help filter the data. All of these parameters are optional.

    Name Defaults to Description
    startDate 1 hour ago, or 1 hour before the endDate if the endDate is provided. Specifies the start of the period for which you want packets. Should be in ISO 8601 format, e.g. 2017-12-24T16:00:00Z
    endDate Now, or 1 hour after the startDate if the startDate is provided. Specifies the end of the period for which you want packets. Should be in ISO 8601 format, e.g. 2017-12-25T12:00:00Z
    sites All Sites Allows you to request packets from a subset of sites. Format as a comma-separated list of Site ids e.g. 59a58d744fd79e0d9ba4233f,59a58a8e1fd78d0d9ea42631.
    obs All obs Allows you to request only certain observations. Format as a comma-separated list, e.g. rst,battery would only return surface temperature and battery observations.
    includeSiteNames true Set as true to include a column with the Site names. false will leave them out.
    removeFlagged false Set as true to remove any obs that have been flagged, false to leave flagged obs in, or a comma-separated list of obs keys, e.g. rst,at to remove flagged obs for only these variables.
    includeFlags false Set as true to include the list of flags (returned as a comma-separated list within quotation marks). If you only want them included for a specific set of obs then provide a comma-seperated list of obs keys instead, e.g. rst,at.
    includeCorr false Set as true to include a column for every obs variable showing any corrections. Set as false to leave these out. Or provide a comma-separated list of obs keys to include columns for only certain variables, e.g. rst,at.

    Get Packets (Single Site)

    For when you only want packets from a single Site.

    JSON Format

    Here we ask for JSON packets between specific start and end dates, and ask that only surface temperature and RSSI obs be included:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f/packets.json?startDate=2017-12-24T16:00:00Z&endDate=2017-12-25T12:00:00Z&obs=rst,rssi"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    The response is a JSON object containing a metadata object and a packets array. The metadata object contains information about the packets, the network the site belongs to, and the site itself. The packets array contains all the packets submitted by this sensor over the given time frame.

    {
      "metadata": {
        "startDate": "2017-12-24T16:00:00Z", 
        "endDate": "2017-12-25T12:00:00Z",
        "latest": "false",
        "removeFlagged": "false",
        "network": {
          "id": "59a68id13fd7ri8e9ea4432c",
          "name": "Gotham City",
          "level": "admin",
          "access": "private",
          "createdAt": "2017-08-29T15:48:33.015Z",
          "updatedAt": "2017-09-04T17:38:42.345Z"
        },
        "site": {
          "id": "59a58d744fd79e0d9ba4233f",
          "type": "static",
          "name": "Arkham Asylum Roundabout",
          "description": "Please get clearance from security guards before visiting to install.",
          "network": "59a68id13fd7ri8e9ea4432c" ,
          "location": {
            "lat": 51.449957,
            "lon": -0.177722
          },
          "createdAt": "2017-10-06T14:38:57.153Z",
          "updatedAt": "2017-10-06T14:38:57.153Z",
        }
      },
      "packets": [
        {
          "id": "59d656bed46dc21c28b847ab",
          "sensor": "111222",
          "sensorType": "SIGFOX-GEN1-SURFACE",
          "obsTime": "2017-12-24T16:03:50.020Z",
          "arrivalTime": "2017-12-24T16:03:50.865Z",
          "network": "59a68id13fd7ri8e9ea4432c",
          "site": "59a58d744fd79e0d9ba4233f",
          "obs": {
            "rst": {
              "value": -1.41,
              "corr": -0.1
            },
            "rssi": {
              "value": -64
            }
          },
        },
        {"etc": "etc"}
      ]
    }
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}/packets.json

    The query parameters are exactly the same as for Multiple Sites except you can't set the sites parameter.

    CSV Format

    Example request for packets in CSV format where we only request surface temperature and battery data over a 15 minute period:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sites/59a58d744fd79e0d9ba4233f/packets.csv?startDate=2017-10-06T16:45:00Z&endDate=2017-10-06T17:00:00Z&obs=rst,battery"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    Site Name,Site ID,Observation Time (UTC),Arrival Time (UTC),Sensor ID,Sensor Type,Surface Temp Value (degC),Battery Level Value (V)
    Arkham Asylum Roundabout,59a58d730fd78e0d9ea4232f,2017-10-06T16:48:53.000Z,2017-10-06T16:58:52.939Z,101745,WIFI-GEN1-SURFACE,1.37,3.21
    Arkham Asylum Roundabout,59a58d730fd78e0d9ea4232f,2017-10-06T16:53:53.000Z,2017-10-06T16:58:52.939Z,101745,WIFI-GEN1-SURFACE,1.29,3.20
    Arkham Asylum Roundabout,59a58d730fd78e0d9ea4232f,2017-10-06T16:58:53.000Z,2017-10-06T16:58:52.823Z,101745,WIFI-GEN1-SURFACE,1.33,3.20
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sites/{siteId}/packets.csv

    The query parameters are exactly the same as for Multiple Sites except you can't set the sites parameter and includeSiteNames defaults to false instead.

    Get Sensor's Latest Packet

    Example request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/sensors/111222_SIGFOX-GEN1-SURFACE/latest-packet"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example response:

    {
      "sensor": "111222",
      "sensorType": "SIGFOX-GEN1-SURFACE",
      "obsTime": "2017-10-05T15:58:54.000Z",
      "arrivalTime": "2017-10-05T15:58:55.865Z",
      "network": "59a68id13fd7ri8e9ea4432c",
      "site": "59a58d744fd79e0d9ba4233f",
      "obs": {
        "rst": {
          "value": -1.41,
          "corr": -0.1
        },
        "at": {
          "value": 2.36,
          "flags": ["persistence"]
        },
        "rssi": {
          "value": -64
        },
        "battery": {
          "value": 3.129
        }
      },
    }
    

    GET https://api.wintersense.com/v1/networks/{networkId}/sensors/{id}_{sensorType}/latest-packet

    Retrieve the latest packet from a given Sensor bound to your Network.

    Usually packets are requested from a given Site rather than Sensor. However it can be useful to see the latest packet received from a particular Sensor, e.g. to check its data is being uploaded ok. As long as the Sensor is bound to your Network you can run this request before the Sensor is bound to a Site.

    Alerts

    Alerts are generated when observations are flagged or sites become inactive. Spotting alerts allows us to rectify the issues as soon as possible.

    Get Network Alerts

    Example Request:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/alerts"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Example Response:

    [
      {
        "id": "5ae554fc9288bc62e6c25442",
        "obs": "rst",
        "type": "persistence",
        "details": {
          "tally": 4,
          "firstTime": "2017-10-05T15:58:54.000Z",
          "lastTime": "2017-10-05T22:58:54.000Z"
        },
        "network": "59a68id13fd7ri8e9ea4432c",
        "site": {
          "id": "59a58d744fd79e0d9ba4233f",
          "name": "Arkham Asylum Roundabout",
          "description": "Please get clearance from villians before visiting to install.",
          "type": "static",
          "network": "59a68id13fd7ri8e9ea4432c",
          "location": {
            "lat": 51.449957,
            "lon": -0.177722
          },
          "createdAt": "2017-10-06T14:38:57.153Z",
          "updatedAt": "2017-11-13T10:49:37.121Z",
          "sensors": [{
            "id": "111222",
            "sensorType": "SIGFOX-GEN1-SURFACE"
          }]
        }    
      }
    ]
    

    Returns an empty array if no alerts have been generated.

    GET https://api.wintersense.com/v1/networks/{networkId}/alerts

    Get a list of all the alerts generated for this Network.

    Query Parameters

    Name Defaults to Description
    populateSite true Populates the site property with the site's details (name, description, etc). If false its value will simply be the site's id.

    Site Properties

    Property Description
    id The unique ID of the alert. If a URL contains {alertId} then you should replace it with this id.
    obs The obs variable this alert applies to, e.g. "rst", "at", or "n/a" for more generic alerts.
    type The alert type as detailed below.
    network The network id.
    site An object with the site's details if the query parameter populateSite equals true. If populateSite=false then it is a string with the site id.
    details A object containing futher information specific to the alert types. Properties include tally that tallies the number of times this alert (with its specific network/site/obs/type combination) has been generated, firstTime and lastTime to show the first and last time this particular alert was generated, and hoursInactive for alerts of type inactive.

    Alert Types

    N.B. many of the alert types are named after flags as they are generated when a flag is spotted in a packet.

    Type Description
    persistence Generated when a persisitence flag is spotted within a packet.
    lowerbound Generated when a lowerbound flag is spotted within a packet.
    upperbound Generated when a upperbound flag is spotted within a packet.
    ambientdiscrepancy Generated when a ambientdiscrepancy flag is spotted within a packet.
    inactive Generated when a Site that has previously uploaded packets stops doing so (by default this alert is generated after 24 hours of inactivity).

    Delete Network Alert

    Example request that deletes an alert:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/alerts/5ae554fc9288bc62e6c25442"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns a 204 as the response body will have no content.

    DELETE https://api.wintersense.com/v1/networks/{networkId}/alerts/{alertId}

    Deletes a single alert.

    Delete All Network Alerts

    Example request that deletes all alerts:

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/alerts"
      -X DELETE
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns a 204 as the response body will have no content.

    DELETE https://api.wintersense.com/v1/networks/{networkId}/alerts

    Delete all alerts generated for this Network.

    Users

    Get Network's Users

    Example

    curl "https://api.wintersense.com/v1/networks/59a68id13fd7ri8e9ea4432c/users"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Returns an array of Users:

    [
      {
        "id": "auth0|577e32695beaed6e29ed4742",
        "name": "Batman",
        "email": "Bruce@WayneEnterprises.com",
        "level": "admin"
      },
      {
        "id": "google-oauth2|102245138662351612909",
        "name": "Cat Woman",
        "email": "cat@woman.com",
        "level": "engineer"
      },
      {
        "id": "linkedin|xkYYrDVolQ",
        "name": "The Joker",
        "email": "Joker@ArkhamAsylum.co.uk",
        "level": "basic"
      }
    ]
    

    GET https://api.wintersense.com/v1/networks/{networkId}/users

    Get an list of all the Users who have access to this Network.

    Rights Levels Explained

    A given Network can have many Users and the chances are you won't want every user to have the same level of rights to that Network. For example, you wouldn't want every user to have the power to delete the Network! As such we've created a number of rights levels that you can assign to a given user depending on how much power you want them to have.

    Here's a summary of what actions are available to each level:

    Level What they can do
    admin Has the power to do everything.
    engineer Has all the rights a basic user has, but crucially they can also add, update and delete Sensors and Sites. Assign this level to the engineers who will go out and install the sensors.
    basic Essentially this User has read-only rights, i.e. they can view and download data, but can't delete or modify the Network or any of its Sites or Sensors. They also can't see information about other Users of the Network.

    To check what rights level you have to a given Network simply make a Get Single Network request and check the level property of the response.

    Errors

    Here's an example of a request that would fail as the provided networkId (1234abcd) doesn't exist:

    curl "https://api.wintersense.com/v1/networks/1234abcd"
      -H "Authorization: apiKey yourApiKeyGoesHere"
    

    Because we won't be able to find a Network with this ID we would return a 404 status code and the following error message:

      "statusCode": 404,
      "status": "Not Found",
      "errorCode": "NETWORK_NOT_FOUND",
      "message": "A network with that id does not exist"
    

    When a request fails the response will have an appropriate status code and the body will be a JSON formatted object with further details about the error.

    Status Codes

    Here's a list of error status codes used by the API:

    Error Code Meaning
    400 Bad Request -- The request could not be understood by the server due to malformed syntax. You should not repeat the request without modifications. For example you may have added a URL query string parameter which the API doesn't support.
    401 Unauthorized -- You have not provided sufficient authentication, e.g. you haven't added an Authorization header including your apiKey.
    403 Forbidden -- Although your means of authentication are valid, you do not have the rights to this particular resource, e.g. you're trying to access a Network you don't have rights to.
    404 Not Found -- The given resource could not be found, e.g. you've try to access data for a Site that has since been deleted.
    429 Too Many Requests -- You're making too many requests. Please wait before trying again later at a slower rate.
    500 Internal Server Error -- There was an unexpected issue with our server.
    503 Service Unavailable -- We were unable to reach the services required to fulfill your request, please try again later.'

    Error Object

    The JSON formatted error object returned in the response body will have the following properties:

    Property Description
    statusCode We also include the response status code here for convenience.
    status A short explanation of what the status code means.
    errorCode A short string unique to the specific error. This makes it easier to distinguish between different errors and react accordingly within your own code. For example, the possible errors you may receive when making a Get Single Network Site request include NETWORK_NOT_FOUND and SITE_NOT_FOUND. Although they would have the same statusCode and status the errorCode would indicate one of two very different causes.
    message A client friendly message explaining the errorCode.