# CoAP Device API Reference

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

**CoAP basics**

[CoAP](https://en.wikipedia.org/wiki/Constrained_Application_Protocol) is a light-weight IoT protocol for constrained devices. You can find more information about CoAP [here](https://tools.ietf.org/html/rfc7252). CoAP protocol is UDP based, but similar to HTTP it uses request-response model. CoAP observes [option](https://tools.ietf.org/html/rfc7641) allows to subscribe to resources and receive notifications on resource change.

JIoT server nodes act as a CoAP Server that supports both regular and observe requests.

**Client libraries setup**

You can find CoAP client libraries for different programming languages on the web. Examples in this article will be based on [CoAP cli](https://www.npmjs.com/package/coap-cli). In order to setup this tool, you can use instructions in our [Hello World](https://thingsboard.io/docs/getting-started-guides/helloworld/) guide.

**CoAP 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 into each CoAP request. Possible error codes and their reasons:

* **4.00 Bad Request** - Invalid URL, request parameters or body.
* **4.01 Unauthorized** - Invalid **$ACCESS\_TOKEN**.
* **4.04 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:

```
{"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:

```
coap://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)
cat telemetry-data-as-object.json | coap post coap://localhost/api/v1/$ACCESS_TOKEN/telemetry
# Publish data as an array of objects without timestamp (server-side timestamp will be used)
cat telemetry-data-as-array.json | coap post coap://localhost/api/v1/$ACCESS_TOKEN/telemetry
# Publish data as an object with timestamp (server-side timestamp will be used)
cat telemetry-data-with-ts.json | coap post coap://localhost/api/v1/$ACCESS_TOKEN/telemetry
```

telemetry-data-as-object.json

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

telemetry-data-as-array.json

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

telemetry-data-with-ts.json

```javascript
{"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:

```
coap://host:port/api/v1/$ACCESS_TOKEN/attributes
```

Example

```
# Publish client-side attributes update
cat new-attributes-values.json | coap post coap://localhost/api/v1/$ACCESS_TOKEN/attributes
```

new-attributes-values.json

```javascript
{"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:

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

Example

```
# Send CoAP attributes request
coap get coap://localhost/api/v1/$ACCESS_TOKEN/attributes?clientKeys=attribute1,attribute2&sharedKeys=shared1,shared2
```

Result

```javascript
{"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 Observe option to the following URL:

```
coap://host:port/api/v1/$ACCESS_TOKEN/attributes
```

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

```
# Subscribe to attribute updates
coap get -o coap://localhost/api/v1/$ACCESS_TOKEN/attributes
```

Result

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

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

**Server-side RPC**

In order to subscribe to RPC commands from the server, send GET request with observe flag to the following URL:

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

Once subscribed, a client may receive rpc requests. 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:

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

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

Example Subcribe

```
# Subscribe to RPC requests
coap get -o coap://localhost/api/v1/$ACCESS_TOKEN/rpc
```

Example Reply

```
# Publish response to RPC request
cat rpc-response.json | coap post coap://localhost/api/v1/$ACCESS_TOKEN/rpc/1
```

Reply Body

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

**Client-side RPC**

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

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

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

Example Request

```
# Post client-side rpc request
cat rpc-client-request.json | coap post coap://localhost/api/v1/$ACCESS_TOKEN/rpc
```

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>

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