APIs Device to Cloud Lorawan Devices Send and receive IoT data
Overview
This page describes how to exchange data between the Device to Cloud platform and your LoRaWAN devices.
- Downlink (platform → device): Send a message to a device by creating a content instance in the device’s
outgoing-msgcontainer. The payload is a hex-encoded byte string. LoRaWAN-specific options (port, priority, confirmed) are set via labels. - Uplink (device → platform): When a device sends a LoRaWAN uplink frame, LORIOT forwards it to D2C. The platform stores the full notification payload in the device’s
received-msgcontainer. - Error handling: If a downlink or provisioning operation fails, the platform records error details in the
error-msgandlogscontainers.
Send message to IoT device
To send a downlink message to a LoRaWAN device, create a content instance (ty=4) in the device’s outgoing-msg container. The con field contains the message payload as a hex-encoded byte string. Use lbl to specify the LoRaWAN port, priority, and whether the delivery should be confirmed.
- Request
- Response
POST {{API_URL}}/device-communication/myLoriot-Device01/outgoing-msg
Accept: application/json
Content-Type: application/json;ty=4
X-M2M-Origin: CmyApplication
X-M2M-RI: 123
Authorization: Bearer {{ACCESS_TOKEN}}
{
"m2m:cin": {
"con": "7123ABC",
"lbl": ["port:100", "priority:0", "confirmed:false"]
}
}
HTTP/2 201 Created
date: Fri, 22 May 2026 08:55:26 GMT
content-type: application/json; charset=utf-8
request-context: appId=cid-v1:
x-service-responder: device-management-orchestrator
x-m2m-ri: 123
x-m2m-rvi: 4
x-m2m-ot: 2026-05-22T08:55:26.304Z
x-m2m-rsc: 2001
x-azure-ref: 20260522T085526Z-157794674c588bv2hC1FRAqubc0000000yng00000000nr1d
x-cache: CONFIG_NOCACHE
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 0
referrer-policy: no-referrer
x-tardis-traceid: e02c1daad6529714d14a233132313436
vary: Origin
x-kong-upstream-latency: 138
x-kong-proxy-latency: 2
x-kong-request-id: c124506370a5fa4ad225a547eea42631
strict-transport-security: max-age=31536000; includeSubDomains
content-length: 994
x-http2-stream-id: 3
{
"m2m:cin": {
"rn": "<resourceName>",
"ri": "<resourceID>",
"ct": "<creationTime>",
"lt": "<lastModifiedTime>",
"con": "7123ABC",
"lbl": ["port:100", "priority:0", "confirmed:false"]
}
}
Downlink message labels
| Label | Description |
|---|---|
port:<number> | LoRaWAN fPort to use for the downlink frame. Valid range: 1–223. |
priority:<number> | Delivery priority. 0 = normal; 1 = immediate. |
confirmed:<true|false> | Whether the LoRaWAN downlink should be a confirmed frame. false = unconfirmed; true = confirmed. |
con must be a hex-encoded byte string (e.g. "7123ABC"). The LORIOT network server delivers the decoded bytes to the device over the air.Receive data from IoT device
When a LoRaWAN device sends an uplink frame, the following happens:
- The device transmits a LoRa radio frame to the nearest gateway.
- The gateway forwards the frame to the LORIOT network server.
- LORIOT decodes the frame and sends the uplink notification to D2C.
- If devices doesn’t exist in D2C system, with the help of device-provisioning request, it will be created automatically.
- D2C stores the notification payload as a content instance in the device’s
received-msgcontainer.
Get last received uplink message
- Request
- Response
GET {{API_URL}}/device-communication/myLoriot-Device01/received-msg/la
Accept: application/json
X-M2M-Origin: CmyApplication
X-M2M-RI: 123
Authorization: Bearer {{ACCESS_TOKEN}}
HTTP/1.1 200 OK
date: Fri, 22 May 2026 08:55:26 GMT
content-type: application/json; charset=utf-8
request-context: appId=cid-v1:
x-service-responder: device-management-orchestrator
x-m2m-ri: 123
x-m2m-rvi: 4
x-m2m-ot: 2026-05-22T08:55:26.304Z
x-m2m-rsc: 2001
x-azure-ref: 20260522T085526Z-157794674c588bv2hC1FRAqubc0000000yng00000000nr1d
x-cache: CONFIG_NOCACHE
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 0
referrer-policy: no-referrer
x-tardis-traceid: e02c1daad6529714d14a233132313436
vary: Origin
x-kong-upstream-latency: 138
x-kong-proxy-latency: 2
x-kong-request-id: c124506370a5fa4ad225a547eea42631
strict-transport-security: max-age=31536000; includeSubDomains
content-length: 994
x-http2-stream-id: 3
{
"m2m:cin": {
"con": {
"cmd": "rx",
"EUI": "647FDA0000004904",
"seqno": 89,
"ts": 1753296610607,
"fcnt": 65,
"port": 10,
"freq": 867300000,
"rssi": -72,
"snr": 9.5,
"toa": 62,
"dr": "SF7 BW125 4/5",
"ack": false,
"bat": 237,
"offline": false,
"confirmed": false,
"devaddr": "30D1B455",
"data": "0367010104687000ff0128",
"decoded": {
"data": {
"raw": "03 67 01 01 04 68 70 00 FF 01 28",
"fPort": 10,
"ambient_temperature": "25.7",
"relative_humidity": "56.0",
"battery_voltage": "2.96"
},
"errors": [],
"warnings": []
}
},
"cnf": "application/json:0",
"ri": "<resourceID>",
"ct": "<creationTime>"
}
}
Uplink message fields
The con field of each received message contains the full LORIOT uplink notification:
| Field | Type | Description |
|---|---|---|
cmd | string | Always "rx" for uplink frames |
EUI | string | 64-bit device EUI (hex) |
seqno | integer | LORIOT-internal sequence number |
ts | integer | Unix timestamp (milliseconds) when LORIOT received the frame |
fcnt | integer | LoRaWAN uplink frame counter |
port | integer | LoRaWAN fPort of the frame |
freq | integer | Frequency in Hz (e.g. 867300000 = 867.3 MHz) |
rssi | integer | Received signal strength in dBm |
snr | number | Signal-to-noise ratio in dB |
toa | integer | Time on air in milliseconds |
dr | string | LoRa data rate (e.g. "SF7 BW125 4/5") |
ack | boolean | Whether the device requested an acknowledgement |
bat | integer | Battery level reported by the device (0–255; 255 = not available) |
offline | boolean | Whether the device was offline when the frame was received |
confirmed | boolean | Whether the frame was a confirmed uplink |
devaddr | string | LoRaWAN device address (hex) assigned after OTAA join |
data | string | Raw uplink payload as a hex-encoded byte string |
decoded | object | Decoded payload if a codec is configured on the LORIOT application (optional) |
Error handling
If an error occurs during downlink delivery or provisioning, D2C records details in two locations:
error-msg— device-level error container; contains the status and reason for the last failed operation.logs— adapter-level log container insided2c-protocol-adapter-loriot; contains structured log entries for troubleshooting.
Get last error for a device:
- Request
- Response
GET {{API_URL}}/device-communication/myLoriot-Device01/error-msg/la
Accept: application/json
X-M2M-Origin: CmyApplication
X-M2M-RI: 123
Authorization: Bearer {{ACCESS_TOKEN}}
HTTP/2 200 OK
date: Wed, 06 May 2026 18:39:45 GMT
content-type: application/json; charset=utf-8
request-context: appId=cid-v1:
x-service-responder: device-management-orchestrator
x-m2m-ri: 123
x-m2m-rvi: 4
x-m2m-ot: 2026-05-06T18:39:45.501Z
x-m2m-rsc: 2000
x-azure-ref: 20260506T183945Z-1698948dff4rhdk2hC1FRA1qrw0000000vx00000000062f8
x-cache: CONFIG_NOCACHE
accept-ranges: bytes
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 0
referrer-policy: no-referrer
x-tardis-traceid: e73dacf181ec59495ca52336373930
vary: Origin
x-kong-upstream-latency: 241
x-kong-proxy-latency: 5
x-kong-request-id: 3325a5457c5e4b2794011e43b3cbfc5b
strict-transport-security: max-age=31536000; includeSubDomains
content-length: 629
x-http2-stream-id: 3
{
"m2m:cin": {
"con": {
"nodeResourceName": "myLoriot-Device01",
"nodeID": "urn:dev:deveui:0080000000017B1B",
"data": "",
"status": {
"code": 500,
"message": "internal server error",
"detail": "Internal server error: subscription creation failed."
}
},
"cnf": "application/json:0",
"ty": 4,
"cs": 604,
"st": 3,
"cr": "CmyApplication",
"rn": "a2efd14b-d5d8-41e0-9c3c-74e907abfc95",
"ri": "69b17f068006f89d59522af0",
"pi": "69b132f78006f89d59521efa",
"ct": "20260311T144110,154000",
"lt": "20260311T144110,154000"
}
}
Get adapter logs:
- Request
- Response
GET {{API_URL}}/d2c-protocol-adapter-loriot/logs/la
Accept: application/json
X-M2M-Origin: CmyApplication
X-M2M-RI: 123
Authorization: Bearer {{ACCESS_TOKEN}}
HTTP/2 200 OK
date: Wed, 06 May 2026 18:39:45 GMT
content-type: application/json; charset=utf-8
request-context: appId=cid-v1:
x-service-responder: device-management-orchestrator
x-m2m-ri: 123
x-m2m-rvi: 4
x-m2m-ot: 2026-05-06T18:39:45.501Z
x-m2m-rsc: 2000
x-azure-ref: 20260506T183945Z-1698948dff4rhdk2hC1FRA1qrw0000000vx00000000062f8
x-cache: CONFIG_NOCACHE
accept-ranges: bytes
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 0
referrer-policy: no-referrer
x-tardis-traceid: e73dacf181ec59495ca52336373930
vary: Origin
x-kong-upstream-latency: 241
x-kong-proxy-latency: 5
x-kong-request-id: 3325a5457c5e4b2794011e43b3cbfc5b
strict-transport-security: max-age=31536000; includeSubDomains
content-length: 629
x-http2-stream-id: 3
{
"m2m:cin": {
"con": {
"identifier": "urn:dev:deveui:0080000000017B1B",
"type": "device processing failed",
"service": "d2c-protocol-adapter-loriot",
"data": "",
"status": {
"code": 500,
"message": "internal server error",
"detail": "Internal server error: d2c-protocol-adapter-loriot unable to delete device from Loriot."
}
},
"cnf": "application/json:0",
"ty": 4,
"cs": 641,
"stg": 2,
"cr": "CmyApplication",
"rn": "31af43c7-f111-4e5a-9694-7c66f5745f72",
"ri": "69b17f068006f89d59522af1",
"pi": "69b158c08006f89d595224b4",
"ct": "20260311T144110,172000",
"lt": "20260311T144110,172000"
}
}
The con field of a log entry has the following structure:
| Field | Description |
|---|---|
identifier | Device or resource identifier |
type | Log entry type (e.g. provisioning, downlink) |
service | Internal adapter service that produced the entry |
status | Outcome — success or an error code |
Next: Forward messages to applications
In the next step, you learn how to integrate your application and use device groups to configure the data routing to your application endpoint.