> For the complete documentation index, see [llms.txt](https://docs.akenza.io/akenza.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.akenza.io/akenza.io/get-started/your-data-flow/device-connector/coap.md).

# CoAP

The **Constrained Application Protocol (CoAP)** ([RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252)) is a specialized web transfer protocol designed for resource-constrained devices and networks. Operating over UDP, CoAP provides a low-overhead alternative to TCP/HTTP, making it ideal for IP-based IoT devices that require minimal power and bandwidth consumption.

To connect a CoAP-enabled device to **akenza**, you must first create a CoAP Device Connector and assign it to a Data Flow (Create Data Flow > Start with empty Data Flow > + Device Connector > CoAP > New CoAP Device Connector).

* For **Pre-shared Key Authentication**: a unique secret is generated upon creating the connector. Your device must pass this secret and the Device ID as query parameters in every CoAP request.
* For **Secure X.509 Authentication**: devices authenticate cryptographically via DTLS. You must submit your Custom Certificate Authority (CA) to akenza and provision devices matching the certificates, as detailed in the setup guide below.

{% hint style="warning" %}
By default CoAP communication without DTLS is insecure. Even if data transmission over a NB-IoT network is inherently encrypted within the cellular network, once the data leaves the carrier network for the public internet, additional measures are required to maintain security.

Therefore, we recommend using DTLS to secure the connection (see below). If your device does not support DTLS, the following alternative architecture can be implemented.

**Fallback Architecture: Secure Tunnel**

1. **Private APN:** Use a private APN configured by your network operator.
2. **VPN Tunnel:** Establish a secure VPN tunnel between the operator's APN and akenza.
3. **Result:** Data remains in its lightweight UDP format for the device, while the "hop" over the public internet is protected from eavesdropping by the tunnel.

[Contact](mailto:support@akenza.io) akenza for more information regarding transport security.
{% endhint %}

### Secure Transport (DTLS)

To secure communication over unencrypted UDP networks, akenza supports Datagram Transport Layer Security (DTLS). This ensures confidentiality, data integrity, and secure device authentication.

#### X.509 Certificate Authentication

Devices can authenticate securely with akenza using *X.509* Certificates. During the DTLS handshake, the device presents its cryptographic certificate to verify its identity, establishing an encrypted channel before any CoAP requests are transmitted. akenza will automatically extract the deviceId from the common name (CN) in the certificate.

To utilize X.509 certificate authentication, you must generate a **Device Certificate Authority (CA)** and individual **Device Client Certificates** for your devices. For more information, refer to [DTLS Device Client Certificates](/akenza.io/get-started/your-data-flow/device-connector/coap/dtls-device-client-certificates.md).

#### Verifying the server identity

akenza uses server certificates issued by ZeroSSL. Make sure your devices trust the [Sectigo Root Certificates](https://www.sectigo.com/knowledge-base/detail/Access-New-Sectigo-Certificate-Chain) specifically [ZeroSSLECCDVSSLCA2.crt](http://crt.sectigo.com/ZeroSSLECCDVSSLCA2.crt).

#### DTLS with Connection ID (CID)

To avoid costly DTLS handshakes after periods of inactivity, the protocol uses DTLS Connection IDs (as defined in [RFC 9146](https://www.rfc-editor.org/rfc/rfc9146)). The CID allows the DTLS session to be resumed without a full handshake even when the device's IP address or UDP port changes (e.g., after a network sleep cycle).

The device aims to perform as few handshakes as possible. The DTLS session is kept alive across transmission intervals by using the CID, so a new handshake is only required when the session cannot be resumed.

### Content Formats

The akenza CoAP connector supports multiple payload formats. Ensure your device includes the correct `Content-Format` option header in its requests to match the transmitted data type:

<table data-header-hidden><thead><tr><th width="206.4375">CoAP Content-Format ID</th><th>Format</th><th>Behaviour</th><th data-hidden></th></tr></thead><tbody><tr><td><code>50</code></td><td><code>application/json</code></td><td><p>Standard JSON payload, parsed directly into a structured JSON object.<br><br>If JSON parsing fails:</p><ul><li><em>Valid UTF-8 payload:</em> Converted to plain text (<code>value</code>) plus Hex (<code>payloadHex</code>) and Base64 representations (<code>payloadBase64</code>).</li><li><em>Invalid UTF-8 payload:</em> Converted to Hex (<code>payloadHex</code>) and Base64 representations (<code>payloadBase64</code>).</li></ul></td><td><code>application/json</code></td></tr><tr><td><code>60</code></td><td><code>application/cbor</code></td><td>Concise Binary Object Representation (CBOR). Parsed and converted into standard JSON.</td><td><code>application/cbor</code></td></tr><tr><td><code>41</code></td><td><code>application/xml</code></td><td>XML payload, automatically converted into a JSON structure.</td><td><code>application/xml</code></td></tr><tr><td><code>42</code></td><td><code>application/octet-stream</code></td><td>Raw binary data. Automatically converted into both Hex (<code>payloadHex</code>) and Base64 (<code>payloadBase64</code>) string representations for the decoder.</td><td><code>application/octet-stream</code></td></tr><tr><td><code>0</code></td><td><code>text/plain</code></td><td>Plain text. The raw string is placed into a JSON object under the key <code>value</code>. Note that the string is expected to have utf-8 format.</td><td><code>text/plain</code></td></tr></tbody></table>

### Additional devices

akenza provides dedicated support for [Efento](https://docs.akenza.io/akenza.io/get-started/your-data-flow/device-connector/coap/efento) devices.

## Sending a CoAP Uplink

<mark style="color:green;">`POST`</mark> `coap://coap.akenza.io:5683/v3/capture?secret={uplinkSecret}&deviceId={deviceId}`

The body can be any **JSON** object.

#### Query Parameters

| Name         | Type   | Description                                                                                     |
| ------------ | ------ | ----------------------------------------------------------------------------------------------- |
| timestamp    | string | The timestamp of the event (ISO-8601 formatted - the current time will be used if not provided) |
| topic        | string | The data topic ("default" will be used if not provided)                                         |
| uplinkSecret | string | The uplink secret used to authenticate the request                                              |
| deviceId     | string | The device ID                                                                                   |

#### Headers

| Name            | Type   | Description      |
| --------------- | ------ | ---------------- |
| content\_format | number | application/json |

{% tabs %}
{% tab title="201 Note that the actual response code is 2.01 for CoAP" %}

```
{
    "id": "UUID",
    "timestamp": "ISO-8601 date string",
    "message": "uplink received"
}
```

{% endtab %}
{% endtabs %}

### Sample NodeJS Script

The below sample nodeJS script allows sending a CoAP uplink. It requires the node module [coap](https://www.npmjs.com/package/coap) to be installed.

```typescript
const coap = require('coap');

// define connection options
const options = {
    hostname: "coap.akenza.io",
    port: 5683,
    method: "POST",
    pathname: "/v3/capture",
    query: "secret={secret}&deviceId={deviceId}",
    options: {
        "Content-Format": "application/json",
    },
};
// create the request object
const req = coap.request(options);
// set the payload
const payload = {
    temperature: Math.random() * 100,
};
req.write(JSON.stringify(payload));
// handle success response
req.on('response', function (res) {
    res.pipe(process.stdout);
});
// handle error response
req.on('error', function (err) {
    console.log("error while sending coap request", err);
});
// send the request
req.end();
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.akenza.io/akenza.io/get-started/your-data-flow/device-connector/coap.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
