# HTTP Device API Reference

### Getting started <a href="#getting-started" id="getting-started"></a>

**HTTP basics**

[HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) is a general-purpose network protocol that can be used in IoT applications. You can find more information about HTTP [here](https://www.w3.org/Protocols/rfc2616/rfc2616.txt). HTTP protocol is TCP based and uses request-response model.

**JIoT** server nodes act as an HTTP Server that supports both HTTP and HTTPS protocols.

**Client libraries setup**

You can find HTTP client libraries for different programming languages on the web. Examples in this article will be based on [curl](https://en.wikipedia.org/wiki/CURL). In order to setup this tool, you can use instructions in our Hello World guide.

**HTTP Authentication and error codes**

We will use *access token* device credentials in this article and they will be referred to later as **$ACCESS\_TOKEN**. The application needs to include **$ACCESS\_TOKEN** as a path parameter in each HTTP request. Possible error codes and their reasons:

* **400 Bad Request** - Invalid URL, request parameters or body.
* **401 Unauthorized** - Invalid **$ACCESS\_TOKEN**.
* **404 Not Found** - Resource not found.

### Key-value format <a href="#key-value-format" id="key-value-format"></a>

By default, **JIoT** supports key-value content in JSON. Key is always a string, while value can be either string, boolean, double or long. Using custom binary format or some serialization framework is also possible. See protocol customization for more details. For example:

```java
{"stringKey":"value1", "booleanKey":true, "doubleKey":42.0, "longKey":73}
```

### Telemetry upload API <a href="#telemetry-upload-api" id="telemetry-upload-api"></a>

In order to publish telemetry data to **JIoT** server node, send POST request to the following URL:

```
http(s)://host:port/api/v1/$ACCESS_TOKEN/telemetry
```

The simplest supported data formats are:

```
{"key1":"value1", "key2":"value2"}
```

or

```
[{"key1":"value1"}, {"key2":"value2"}]
```

**Please note** that in this case, the server-side timestamp will be assigned to uploaded data! In case your device is able to get the client-side timestamp, you can use following format:

```
{"ts":1451649600512, "values":{"key1":"value1", "key2":"value2"}}
```

In the example above, we assume that “1451649600512” is a [unix timestamp](https://en.wikipedia.org/wiki/Unix_time) with milliseconds precision. For example, the value ‘1451649600512’ corresponds to ‘Fri, 01 Jan 2016 12:00:00.512 GMT’

Example

> ```
> # Publish data as an object without timestamp (server-side timestamp will be used)
> curl -v -X POST -d @telemetry-data-as-object.json http://localhost:8080/api/v1/$ACCESS_TOKEN/telemetry --header "Content-Type:application/json"
> # Publish data as an array of objects without timestamp (server-side timestamp will be used)
> curl -v -X POST -d @telemetry-data-as-array.json http://localhost:8080/api/v1/$ACCESS_TOKEN/telemetry --header "Content-Type:application/json"
> # Publish data as an object with timestamp (server-side timestamp will be used)
> curl -v -X POST -d @telemetry-data-with-ts.json http://localhost:8080/api/v1/$ACCESS_TOKEN/telemetry --header "Content-Type:application/json"
> ```

telemetry-data-as-object.json

```
{"key1":"value1", "key2":true, "key3": 3.0, "key4": 4}
```

telemetry-data-as-array.json

```
[{"key1":"value1"}, {"key2":true}]
```

telemetry-data-with-ts.json

```
{"ts":1451649600512, "values":{"key1":"value1", "key2":"value2"}}
```

### Attributes API <a href="#attributes-api" id="attributes-api"></a>

**JIoT** attributes API allows devices to

* Upload client-side device attributes to the server.
* Request client-side and shared device attributes from the server.
* Subscribe to shared device attributes from the server.

**Publish attribute update to the server**

In order to publish client-side device attributes to **JIoT** server node, send POST request to the following URL:

```
http(s)://host:port/api/v1/$ACCESS_TOKEN/attributes
```

Example

```
# Publish client-side attributes update
curl -v -X POST -d @new-attributes-values.json http://localhost:8080/api/v1/$ACCESS_TOKEN/attributes --header "Content-Type:application/json"
```

new-attributes-values.json

```
{"attribute1":"value1", "attribute2":true, "attribute3":42.0, "attribute4":73}
```

**Request attribute values from the server**

In order to request client-side or shared device attributes to **JIoT** server node, send GET request to the following URL:

```
http(s)://host:port/api/v1/$ACCESS_TOKEN/attributes?clientKeys=attribute1,attribute2&sharedKeys=shared1,shared2
```

Example

```
# Send HTTP attributes request
curl -v -X GET http://localhost:8080/api/v1/$ACCESS_TOKEN/attributes?clientKeys=attribute1,attribute2&sharedKeys=shared1,shared2
```

Result

```
{"key1":"value1"}
```

**Please note**, the intersection of client-side and shared device attribute keys is a bad practice! However, it is still possible to have same keys for client, shared or even server-side attributes.

**Subscribe to attribute updates from the server**

In order to subscribe to shared device attribute changes, send GET request with optional “timeout” request parameter to the following URL:

```
http(s)://host:port/api/v1/$ACCESS_TOKEN/attributes/updates
```

Once shared attribute will be changed by one of the server-side components (REST API or Rule Chain) the client will receive the following update:

Example

```
# Send subscribe attributes request with 20 seconds timeout
curl -v -X GET http://localhost:8080/api/v1/$ACCESS_TOKEN/attributes/updates?timeout=20000
```

Result

```
{"key1":"value1"}
```

### RPC API <a href="#rpc-api" id="rpc-api"></a>

#### Server-side RPC <a href="#server-side-rpc" id="server-side-rpc"></a>

In order to subscribe to RPC commands from the server, send GET request with optional “timeout” request parameter to the following URL:

```
http(s)://host:port/api/v1/$ACCESS_TOKEN/rpc
```

Once subscribed, a client may receive rpc request or a timeout message if there are no requests to a particular device. An example of RPC request body is shown below:

```
{
  "id": "1",
  "method": "setGpio",
  "params": {
    "pin": "23",
    "value": 1
  }
}
```

where

* **id** - request id, integer request identifier
* **method** - RPC method name, string
* **params** - RPC method params, custom json object

and can reply to them using POST request to the following URL:

```
http://host:port/api/v1/$ACCESS_TOKEN/rpc/{$id}
```

where **$id** is an integer request identifier.

Example subcribe

```
# Send rpc request with 20 seconds timeout
curl -v -X GET http://localhost:8080/api/v1/$ACCESS_TOKEN/rpc?timeout=20000
```

Example Reply

```
# Publish response to RPC request
curl -v -X POST -d @rpc-response.json http://localhost:8080/api/v1/$ACCESS_TOKEN/rpc/1 --header "Content-Type:application/json"
```

Reply Body

```
{"result":"ok"}
```

#### Client-side RPC <a href="#client-side-rpc" id="client-side-rpc"></a>

In order to send RPC commands to the server, send POST request to the following URL:

```
http://host:port/api/v1/$ACCESS_TOKEN/rpc
```

Both request and response body should be valid JSON documents. Theh content of the documents is specific to the rule node that will handle your request.

Example Request

```
# Post client-side rpc request
curl -X POST -d @rpc-client-request.json http://localhost:8080/api/v1/$ACCESS_TOKEN/rpc --header "Content-Type:application/json"
```

Request Body

```
{"method": "getTime", "params":{}}
```

Response Body

```
{"time":"2016 11 21 12:54:44.287"}
```

### Protocol customization <a href="#protocol-customization" id="protocol-customization"></a>

HTTP transport can be fully customized for specific use-case by changing the corresponding module.
