You should now have an access token and know how to make requests to the Igloo API, if you don’t, check out the introduction guide.

Creating a new thing

We will now create your first device with Igloo, you can follow along using the playground or use this tutorial as a guideline to write the code for your device.

In Igloo your IoT devices are called things, you can register a new thing with the following mutation:

mutation {
  createThing(type: "Example") {

If you have Portal open on the “Things” page you will see a new thing appear in the list.

In the mutation we read these very important fields:

  • id: this is a unique identifier for your thing, every time you will update or read data about this thing you will refer to it by id
  • pairCode and qrcode are used by you or the user that bought your devices to get access to the thing in the Remote app. Remote asks to type pairCode or scan the qrCode, we suggest you print the qrCode on your device or put it inside the box
  • token: putting the access token for your account in the code of your device can open you up to security threats: if someone gets access to the code running on a single device they will have access to your account and all your things. This is why we provide you with a thing token that has only access to that specific thing. This way even if they get access to the source code they will only be able to read the data about that one device.
    While you are testing out Igloo there is no need to use this token, but we strongly recommend that you use it in the final product.

You can read data about your thing with a query (you can see all the available fields in the API documentation)

query {
  thing(id: "id-of-your-thing") {
Adding data to your thing

Different things can store different types of data: you can create variables on a thing, this way you can choose which data structure your thing should have, for example:

  • a weather thing could have a float variable for the pressure, another one for the temperature and a last one for wind speed
  • a lamp thing could have a single boolean variable for on/off
  • a seismometer could have a float series storing all the values measured in the last week

It is up to you to choose which variables to have in your thing. To create a new variable on a thing you can use a mutation like this one

mutation {
    name: "On/Off"
    visibleTo: VIEWER
    editableBy: OWNER
    thingId: "id-of-your-thing"
    value: false
  ) {

Let’s go through the mutation parameters one by one

  • name is the user-friendly name of the variable; it is shown in the apps, but to update the variable you only need its id
  • visibleTo specifies which role is necessary to see this variable, VIEWER is the minimum role so any user that has access to the thing can also see this variable
  • editableBy specifies which role is necessary to update this variable, OWNER means that the variable can be changed by the owner of the thing (and by the developer) but not by any user with whom the thing is shared
  • thingId is the ID of the thing on which you want to create the variable

After running the mutation, if you have Portal (or Remote) open and the thing selected you will see the variable appear in the right panel.

You can update the value of the variable using a mutation

mutation {
    id: "id-of-your-variable"
    value: true
  ) {
Which variable types can I use?

The supported variable types are:

  • BooleanVariable: stores a single boolean value
  • FloatVariable: stores a float value, two of the fields that it accepts are min and max, if they are both set the apps will show a slider that allows to pick a value between them
  • StringVariable: stores a text value, it accepts a maxChars field to limit the length of the text that can be set with the Remote app
  • FloatSeriesVariable: stores a list of nodes, each node has a timestamp and a float value, to add a node use the createFloatSeriesNode mutation
  • ImpulseVariable: it doesn’t store any data, but shows a button to the user that he can use to trigger (via GraphQL subscription) and action. For example it can be used to open a door remotely.
  • FileVariable: it can be used to store a file. If the field visualization is set to image, video or audio a preview of the file will be displayed in the apps, otherwise you will simply be able to download it.
  • LayoutVariable: it can be used to store the image of one or several floors of a building. The field primaryMarker on the LayoutFloor allows you to show the position of the device on the map.

The way your variable is displayed will change depending on the optional fields you set, for example the StringVariable is displayed as a textbox by default, but if you specify the allowedValues field then it will become a drop down selection and if you set it as READ_ONLY it simply shows its value as text.

If you want to see the whole spectrum of possibilities checkout the Variables page in our API docs.


We have a notification system too: notifications are always linked to a thing and they are sent to all users that have access to that thing. To create a notification use the following mutation:

mutation {
  createNotification(thingId: "your-thing-id", content:"Hey, look at me!") {

Notifications are delivered as web push notifications by default, so they will pop up as native notifications. If the user enables it he can receive the notifications via SMS or email.
Both on desktop and mobile the notifications can also be seen in the Remote app.