These docs are for v2.0. Click to read the latest docs for v3.3.

Device Development

In this document you will learn how to connect your networked devices to thethings.iO.

📘

Before you start learning how to use our platform to connect your devices, we recommend that you read first our Getting Started guide in order to create your Account and set up the platform.

👍

At this guide, we only show the basics of the API REST. You can access to the full REST API Reference to get the full list of endpoints available and play with them from the docs. Also, you'll find examples in different programming languages (Node, Ruby, Python, etc)

Get tokens

To be able to follow the examples you will need an Activation Code or a Thing Token.

An Activation Code is a unique code that will enable your devices to be activated via the Thing Activate API call. The purpose of this code is at the same time identify you as the creator of the thing and when some day you start selling your awesome IoT product, avoid somebody being able to activate things in your name.

As a result of this call, your thing will receive a unique thing token that will identify your thing at thethings.iO platform.

You can also activate your things manually at the Panel.

To get your Thing Tokens go to the Things Manager page and click the get activation codes button.

Postman Test

You can test the next endpoints (except thing subscribe) importing the following postman collection: thethings.iO Postman Collection

Get Postman: Postman REST Client

cURL Test

This is thethings.iO CURL test to check that you are able to make requests.

curl -H "Content-Type: application/json" \
  -X GET "https://api.thethings.io/v2/"
# That is ok. This is the response that you have to get.
{
  "status": "error",
  "code": 401,
  "message": "Invalid session token"
}

REST API Basics

🚧

For the next examples, you have to replace the variables inside brackets {{THING TOKEN}}. Brackets should include your actual value.

Activate

Activates a thing with an activation code. The result is a Thing Token. You will be able to retrieve this Thing Token at any time from the Platform. You can find the product Id at the product details view, but if you have only one product then this product Id is not necessary.

curl -i -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"activationCode" : "{{activation Code}}", "productId":"{{product Id}}"}' \
  -X POST "https://api.thethings.io/v2/things/" -k
# Everything has gone well, 201
{
  "status": "created",
  "message": "thing activated",
  "thingToken": "rFffsL4kcMuaKzJ5UEwqrry5kg5g9hyGWt0T2QP9wLVzw",
  "thingId": "XTNsdG1MGWGZQ-gX7nJzm9cBoEDeDk24NylhazQAwN8"
}

# Error, 400 Bad request
{
  "status": "error",
  "message": "activation code not found"
}

Write

Writes the data from the device corresponding to the specified {{THINGTOKEN}}. Only alphanumeric characters and ".", "-", "" symbols are admitted for the resource name "key".

curl -i -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"values":
    [{
      "key": "fun",
      "value": "9000"
    }]
  }' \
  -X POST "https://api.thethings.io/v2/things/{ {THING_TOKEN} }" -k
# Everything has gone well
{
  "status": "Success",
  "message": "Created"
}

Geolocating your values
If your thing can change its location, you can geolocate your values adding the geo parameter in the body.

{
    "values":
    [{
      "key": "my-geolocated-key",
      "value" : 23,
      "geo" : {
        "lat" : 41.4121132,
        "long" : 2.2199454
      }
    }]
  }

Adding a custom timestamp
When our Platform receives a value, it also stores the current date and time in UTC format. But sometimes your thing isn't able to send the values at the time the sensor reading was done (i.e. your thing doesn't have connectivity or you want to save battery).

To solve this use case, you can send a batch of values and indicate the time on each. The values don't need to be sorted by time. They will be sorted by our storage system automatically.

The format is YYYYMMDDHHmmss. Notice thethings.iO considers all times to be in UTC.

{
    "values":
    [{
      "key": "my-batch-key",
      "value" : 23,
      "datetime" : "20150520130000"
    },
    {
      "key": "my-batch-key",
      "value" : 24,
      "datetime" : "20150520140000"
    },
    {
      "key": "my-batch-key",
      "value" : 25,
      "datetime" : "20150520150000"
    },
    {
      "key": "my-batch-key",
      "value" : 22,
      "datetime" : "20150520120000"
    }]
  }

Query parameters

ParameterDefaultFormatDescription
storetrueBooleanIf false, it will broadcast a value but NOT store the value.
broadcasttrueBooleanIf false, it will store the value WITHOUT broadcasting to the subscribers.

Read

This method returns the values of the specified KEY from the corresponding thing THING_TOKEN.

curl -i -H "Accept: application/json" \
  -X GET "https://api.thethings.io/v2/things/{ {THING_TOKEN} }/resources/{ {KEY} }?limit=10" -k
//  Everything has gone well
[
  {
    "key": "fun",
    "value": "9000",
    "datetime": "2015-01-30T15:35:33.000Z"
  }
]

// If you get this error, remember to change THING_TOKEN for a valid thing token:
{"status": "error", "message": "Thing token doesn't exist"}

// If you try to read a resource with a key which you never have written before,
// you	ll get the next error. Remember to change jEY for a valid key:
{"status": "error","message": "resource not found"}

Query parameters

ParameterDefaultFormatDescription
limit1NumberHow many results (max 1000)
startDateJan 1st 1970YYYYMMDDHHmmssThe min date
endDateEnd of times (for JavaScript)YYYYMMDDHHmmssThe max date

The maximum number of values that would be returned is the last 1000. So if you need to get more than 1000 values, you have to query the previous 1000 values using the endDate of the last value returned by the first query.

In the next example we want to get 2300 values of the resource temperature:

curl -i -H "Accept: application/json" \
  -X GET "https://api.thethings.io/v2/things/{ {THING_TOKEN} }/resources/{ {KEY} }?limit=1000" -k
[
 // 1
    {
        "key": "temperature",
        "value": 24.311,
        "datetime": "2017-01-16T10:25:10.644Z"
    },
  // 2
    {
        "key": "temperature",
        "value": 47.953,
        "datetime": "2017-01-16T10:24:10.641Z"
    },
   // 3
    {
        "key": "temperature",
        "value": 29.241,
        "datetime": "2017-01-16T10:23:10.677Z"
    },
  
  // ..........
  
  // The next value has the datetime that you need to use as a endDate at   
  // the next query
  
  // 1000

    {
        "key": "temperature",
        "value": 22.958,
        "datetime": "2017-01-15T17:46:06.932Z"
    }
]
curl -i -H "Accept: application/json" \
  -X GET "https://api.thethings.io/v2/things/{ {THING_TOKEN} }/resources/{ {KEY} }?limit=1000&endDate=2017-01-15T17:46:06.932Z" -k
[
  // 1
    {
        "key": "temperature",
        "value": 53.708,
        "datetime": "2017-01-15T17:45:06.929Z"
    },
  
  // 2
    {
        "key": "temperature",
        "value": 41.794,
        "datetime": "2017-01-15T17:44:06.966Z"
    },
  
  // 3
    {
        "key": "temperature",
        "value": 47.891,
        "datetime": "2017-01-15T17:43:06.920Z"
    },
  
  // ........
  
  // Again, the next value has the datetime that you need to use as a endDate at   
  // the next query
  
  // 1000
    {
        "key": "temperature",
        "value": 24.805999999999997,
        "datetime": "2017-01-15T01:06:03.212Z"
    }
]

Magic resources

Magic resources are specials resources that start with $, and they have some special behaviors like trigger some common task or update static data. These resources can be used as the others ones using read and write operations.

🚧

Magic resources handlers are processed asynchronously: mixing various magic resources in a single request may have an unexpected behavior because order could not be respected.

$geo resource

This resource allows updates and retrieves the current thing position in GeoJSON format. The coordinates order is longitude and then latitude [longitude, latitude].

curl -H "Content-Type: application/json" \
       -d '{"values":[{"key": "$geo","value" : {"type": "Point","coordinates": [2.154007, 41.390205]}}]}' \
       -X POST "https://api.thethings.io/v2/things/THING_TOKEN"
// Everything is ok
{"status":"created"}
curl -i -H "Accept: application/json" \
  -X GET 'https://api.thethings.io/v2/things/THING_TOKEN/resources/$geo' \
  -k
// On success, the GET command returns JSON structured like this
[{"key":"$geo","value":{"type":"Point","coordinates":[2.154007,41.390205]}}]

$settings resource

This resource allows updates and retrieves things settings meta-data store. It also permits to get and set a single value in the path (in dot notation).

curl -H "Content-Type: application/json" \
       -d '{"values":
      [{
          "key": "$settings",
          "value" : {
                  "name": "My Thing",
                  "foo": "bar"
          }
       }]
  }' \
       -X POST "https://api.thethings.io/v2/things/THING_TOKEN"
curl -H "Content-Type: application/json" \
       -d '{"values":
      [{
          "key": "$settings.name",
          "value" : "My Thing"
        }]
  }' \
       -X POST "https://api.thethings.io/v2/things/THING_TOKEN"
// Everything is ok
{"status":"created"}
curl -i -H "Accept: application/json" \
  -X GET 'https://api.thethings.io/v2/things/THING_TOKEN/resources/$settings' \
  -k
curl -i -H "Accept: application/json" \
  -X GET 'https://api.thethings.io/v2/things/THING_TOKEN/resources/$settings.name' \
  -k
// GET settings
[{"key":"$settings","value":{"name":"My Thing","foo":"bar"}}]

// GET settings value name
[{"key":"$settings.name","value":"My Thing"}]

Subscribe

This method subscribes to the thing channel and gets realtime updates. You will need a compatible client. To subscribe from a browser we recommend to use Websockets. REST API subscription is not reliable on browsers.

With this method you can subscribe to the thing channel and get real-time updates from all the thing's keys (resources). The subscription endpoint creates a streaming channel and we keep the channel open depeding on the keep alive that you send. If no keep alive is set, your router or our server will close the channel at its sole discretion.

To test the real-time updates, you will need to open two consoles. One for the subscription curl command, and another to do the curl write commands.

curl -H "Content-Type: application/json" \
       -X GET "http://api.thethings.io/v2/things/THING_TOKEN"\
       -N
// On success, the above command returns JSON structured like this:
{"status":"success", "message":"subscribed"}

// If you get this error, remember to change THING_TOKEN for a valid thing token.
{"status":"error", "message":"Thing with thing token 'Eyixxxxxxx-xxxxxxxx' not found."}

Get Server Date

You can get the server time by calling:

curl -i -H "Accept: application/json" \
  -X GET "https://api.thethings.io/v2/utils/date?thingToken={{THING_TOKEN}}&format={{format}}" -k
//unix_timestamp
{"date":1494587224,"values":[{"value":1494587224}]}

//UTC
{"date":"2017-05-12T11:07:53.176Z","values":[{"value":"2017-05-12T11:07:53.176Z"}]}

Where format can be UTC (default) or unix_timestamp

Examples

See the examples to connect your device to thethings.iO at our GitHub Repository for different programming languages.