---
# System prepended metadata

title: iSeries IoT API

---

# iSeries IoT API
---

## Table of Contents
* [Overview](#overview)
    * [The data model](#the-data-model)
    * [Intended state](#intended-state) 
* [API](#api)
    * [Document Reader API](#document-reader-api)
    * [Structure API](#structure-api)
* [Authorization](#authorization)
    * [Authorization Overview](#authorization-overview)
    * [OAuth 2.0 Authentication and Authorization](#oauth-20-authentication-and-authorization)
* [Permissions](#permissions)
* [REST](#rest)
    * [REST Overview](#rest-overview)
    * [How to Handle Redirects](#how-to-handle-redirects)

---
## Overview 

### The data model
 The API is represented as a JSON document with top-level  attributes of metadata, devices, and structures. Your products use this JSON document to interact with, and react to, devices and related state changes.

Structures represent physical structures in the real world. They serve as an organizing point for devices and store data for the building as a whole. Typically, a structure is a user place of business.

Devices represent physical devices (Document Readers) within a structure.

> **Key Point:** All devices belong to a structure. A structure can have many devices.

Every data element in the JSON document is addressable by URL (also known as "data locations"). Products can read and write to sections of this document and subscribe to changes. This subscription capability allows products to react in real time to changes made to the system, such as turning off a reader when a gate goes out of service.

```JSON
{
    "metadata": {
        "access_token" :"c.FmDPkzyzaQe...",
        "client_version" :1
    },
    
    "devices": {
        "fingerprint_readers": { /* TODO */ },
        "document_readers": {
            "awJo6rH0IldT2YlIVtYaGQ": {
                "device_id" :"awJo6rH...",
                "software_version" :"4.0",
                "structure_id" :"VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw",
                "where_id" :"d6reb_OZTM...",
                "where_name" :"Hallway",
                "name" :"Hallway (upstairs)",                
                "is_online" :true,                
                "last_is_online_change" :"2016-12-29T18:42:00.000Z",
                "last_capture":{
                    "vis_url" :"STRING1/device_id/STRING2?auth=access_token",
                    "uv_url" :"STRING1/device_id/STRING2?auth=access_token",
                    "ir_url" :"STRING1/device_id/STRING2?auth=access_token",
                },
                "last_event": {
                    "has_document" :true,
                    "start_time" :"2016-12-29T00:00:00.000Z",
                    "end_time" :"2016-12-29T18:42:00.000Z",
                }
            }
        }
    }

    "structures": {
        "VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw": {
            "structure_id" :"VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw",
            "document_readers" :["peyiJNo0IldT2YlIVtYaGQ", ...],
            "name" :"Terminal 2",
            "wheres": {
                "Fqp6wJI...": {
                    "where_id" :"Fqp6wJI...",
                    "name" :"Hall 1"
                }
            }
        }
    }
}
```

### Intended state

The service stores the authoritative state of the system, and devices subscribe to changes. Modifying this state causes the service to push a change notification to all subscribers.
B
ecause this propagation has some delay and networks can be unreliable, the state observed by a product may not be the state currently observed by other products or the service. State is eventually synchronized as messages are transmitted between various products.

> **Key Point:** The state stored in the service is the current "intended" state of the system.

This document-oriented publish/subscribe model provides responsive application interactions.


---
## API

### Document Reader API

https://`{url}`/devices/document_readers/`{device_id}`/

#### device_id

|               |                                                     |
| ---           | ---                                                 |
| https://`{url}`/devices/document_readers/`{device_id}`/device_id   ||
| **Returns**   | `string` <br/> *example:* `'V789Typtr...'`          |
| **Access**    | read-only                                           |
| **Available** | **Read:**                                           |

#### software_version

|               |                                                          |
| ---           | ---                                                      |
| https://`{url}`/devices/document_readers/`{device_id}`/software_version ||
| **Returns**   | `string` <br/> *example:* `'1.0.2'`                      |
| **Access**    | read-only                                                |
| **Available** | **Read:**                                                |

#### structure_id

|               |                                                      |
| ---           | ---                                                  |
| https://`{url}`/devices/document_readers/`{device_id}`/structure_id ||
| **Returns**   | `string` <br/> *example:* `'V789Typtr...'`           |
| **Access**    | read-only                                            |
| **Available** | **Read:**                                            |

#### where_id

A unique,generated identifier that represents where_name.

|               |                                                     |
| ---           | ---                                                 |
| https://`{url}`/devices/document_readers/`{device_id}`/where_id    ||
| **Returns**   | `string` <br/> *example:* `'V789Typtr...'`          |
| **Access**    | read-only                                           |
| **Available** | **Read:**                                           |

#### where_name

Display name of the device' "where"

|               |                                                     |
| ---           | ---                                                 |
| https://`{url}`/devices/document_readers/`{device_id}`/where_name  ||
| **Returns**   | `string` <br/> *example:* `'Hall 2'`                |
| **Access**    | read-only                                           |
| **Available** | **Read:**                                           |

#### name

Display name of the device

|               |                                                     |
| ---           | ---                                                 |
| https://`{url}`/devices/document_readers/`{device_id}`/name        ||
| **Returns**   | `string` <br/> *example:* `'Gate 7'`                |
| **Access**    | read-only                                           |
| **Available** | **Read:**                                           |

#### is_online

Device connection status.

|               |                                                      |
| ---           | ---                                                  |
| https://`{url}`/devices/document_readers/`{device_id}`/is_online    ||
| **Returns**   | `boolean` <br/> *example:* `true` or `false`         |
| **Access**    | read-only                                            |
| **Available** | **Read:**                                            |

#### last_is_online_change

Timestamp that identifies the last change to the online status, in ISO 8601 format.

|               |                                                                |
| ---           | ---                                                            |
| https://`{url}`/devices/document_readers/`{device_id}`/last_is_online_change  ||
| **Returns**   | `string` <br/> *example:* `"2016-12-29T18:42:00.000Z"`         |
| **Access**    | read-only                                                      |
| **Available** | **Read:**                                                      |

#### last_event

`https://`{url}`/devices/document_readers/`{device_id}`/last_event`

##### has_document

|               |                                                                 |
| ---           | ---                                                             |
| https://`{url}`/devices/document_readers/`{device_id}`/last_event/has_document ||
| **Returns**   | `string` <br/> *example:* `true` or `false`                     |
| **Access**    | read-only                                                       |
| **Available** | **Read:**                                                       |

#### last_capture

https://`{url}`/devices/document_readers/`{device_id}`/last_capture

##### vis_url

|               |                                                                           |
| ---           | ---                                                                       |
| https://`{url}`/devices/document_readers/`{device_id}`/last_capture/vis_url              ||
| **Returns**   | `string` <br/> *example:* `"STRING1/device_id/STRING2?auth=access_token"` |
| **Access**    | read-only                                                                 |
| **Available** | **Read:**                                                                 |

##### ir_url

|               |                                                                           |
| ---           | ---                                                                       |
| https://`{url}`/devices/document_readers/`{device_id}`/last_capture/ir_url              ||
| **Returns**   | `string` <br/> *example:* `"STRING1/device_id/STRING2?auth=access_token"` |
| **Access**    | read-only                                                                 |
| **Available** | **Read:**                                                                 |

##### uv_url

|               |                                                                           |
| ---           | ---                                                                       |
| https://`{url}`/devices/document_readers/`{device_id}`/last_capture/uv_url              ||
| **Returns**   | `string` <br/> *example:* `"STRING1/device_id/STRING2?auth=access_token"` |
| **Access**    | read-only                                                                 |
| **Available** | **Read:**                                                                 |

### Structure API

https://`{url}`/structures/`{structure_id}`/

#### structure_id

ID number of the structure.

|               |                                             |
| ---           | ---                                         |
| https://`{url}`/structures/`{structure_id}`/structure_id   ||
| **Returns**   | `string` <br/> *example:* `'V789Typtr...'`  |
| **Access**    | read-only                                   |
| **Available** | **Read:**                                   |

#### document_readers

List of document_readers in the structure, byt device identifier.

|               |                                                     |
| ---           | ---                                                 |
| https://`{url}`/structures/`{structure_id}`/document_readers       ||
| **Returns**   | `string[]` <br/> *example:* `['V789Typtr...',... ]` |
| **Access**    | read-only                                           |
| **Available** | **Read:** |

#### name

User defined name of the structure.

|               |                                            |
| ---           | ---                                        |
| https://`{url}`/structures/`{structure_id}`/name          ||
| **Returns**   | `string` <br/> *example:* `'Terminal 1'`   |
| **Access**    | read/write                                 |
| **Available** | **Read:** <br/> **Write:**                 |


#### wheres

User defined name of the structure.

|               |                                            |
| ---           | ---                                        |
| https://`{url}`/structures/`{structure_id}`/wheres        ||
| **Returns**   | `object[]` <br/> *example:* `'Terminal 1'` |
| **Access**    | read-only                                  |
| **Available** | **Read:** <br/> **Write:**                 |

---
## Authorization

### Authorization Overview

The API provides information that you can use to capture customer information for a user. The information is ultimately owned by users, and users can explicitly choose to share this information with your product.

The purpose of authorization is to give your customers a secure means to grant access to their device data.

#### Product site or app before authorization

In your product site or app, you can provide a way for customers to give your product access to their device data. To do this, create a button or other UI element to initiate the OAuth flow.

When you build user authorization into your app, you can either:
- use an external browser to authorize an app
- use a new page to auth a webapp

> **Warning:** Do not use iFrames for user authorization.

#### Login

The user is prompted to login.

#### Permissions

We'll prompt the user to grant access to your product. This page displays the permissions and descriptions you entered when you created your client.

#### Product site or app after authorization

After your customer authorizes your product, we'll send an authorization code that your product can exchange for an access token. Your product can then send the access token with API calls to access Nest data.

Your customers can revoke access at any time, which will prevent your product from making further requests for the customer's device data.

### OAuth 2.0 Authentication and Authorization

```mermaid
sequenceDiagram
    autonumber
    actor U as User
    participant P as Your Product
    participant C as Cloud
    
    P->>C: Request Authorization
    activate C
    activate P
    U->>C: User Login & Consent
    C-->>P: Authorization Code
    deactivate C
    deactivate P

    P->>C: Exchange code for token
    activate P
    activate C
    C-->>P: Token response
    deactivate P
    deactivate C

    P->>C: Use Token to call API
```
---
## Permissions

### Document Reader

| document_reader            |                                      |
| ---                        | ---                                  |
| document_reader read       | Grants read permission to all values |
| document_reader read/write | Grants read permission to all values <br/> Grants write permission to <ul><li>`name`</li><li>`enabled`</li></ul>|

### Structure

| structure            |                                      |
| ---                  | ---                                  |
| structure read       | Grants read permission to all values |
| structure read/write | Grants read permission to all values <br/> Grants write permission to `name` |
---
## REST

### REST Overview 

REST is a lightweight, stateless web service standard that you can use within your products for ad-hoc one-off calls, proof-of-concept labs, troubleshooting, apps that poll approximately every minute, and refresh button implementations.

The REST interface uses the iSeries IoT API Data Model URL as an endpoint.

### How to Handle Redirects

Some programming languages have HTTP implementations that require special handling for redirects.

In response to a REST API request, the Nest API server returns a redirect. The REST client detects the redirect and requests the page that the client was redirected to. Some HTTP implementations do not forward the Authorization header to the redirected URI, and this results in a 401 Unauthorized error.

For example, suppose you ask for foo.com. The foo.com server responds with a redirect to bar.com. Postman or Curl pass the Authorization header to foo and then to bar. Other HTTP implementations, such as Golang's and Python's, do not automatically pass the Authorization header to the redirected URI.

#### How it works

The following sequence diagram shows what happens when a redirect occurs.

```mermaid
sequenceDiagram
    participant API Client
    participant Developer API
    participant Data Store
    Note left of API Client: First HTTP<br/>Request!
    API Client->>Developer API: GET from API url
    Developer API-->>API Client: 307 Redirect to Data Store URL
    Note left of API Client: Second HTTP<br/>Request!
    API Client->>Data Store: GET from Data Store URL
    Data Store-->>API Client: 200 w/ JSON Payload in HTTP Body
```

