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-msg container. 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-msg container.
  • Error handling: If a downlink or provisioning operation fails, the platform records error details in the error-msg and logs containers.

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"]
  }
}
LabelDescription
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.
Note:
The payload in 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:

  1. The device transmits a LoRa radio frame to the nearest gateway.
  2. The gateway forwards the frame to the LORIOT network server.
  3. LORIOT decodes the frame and sends the uplink notification to D2C.
  4. If devices doesn’t exist in D2C system, with the help of device-provisioning request, it will be created automatically.
  5. D2C stores the notification payload as a content instance in the device’s received-msg container.
  • 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>"
  }
}

The con field of each received message contains the full LORIOT uplink notification:

FieldTypeDescription
cmdstringAlways "rx" for uplink frames
EUIstring64-bit device EUI (hex)
seqnointegerLORIOT-internal sequence number
tsintegerUnix timestamp (milliseconds) when LORIOT received the frame
fcntintegerLoRaWAN uplink frame counter
portintegerLoRaWAN fPort of the frame
freqintegerFrequency in Hz (e.g. 867300000 = 867.3 MHz)
rssiintegerReceived signal strength in dBm
snrnumberSignal-to-noise ratio in dB
toaintegerTime on air in milliseconds
drstringLoRa data rate (e.g. "SF7 BW125 4/5")
ackbooleanWhether the device requested an acknowledgement
batintegerBattery level reported by the device (0–255; 255 = not available)
offlinebooleanWhether the device was offline when the frame was received
confirmedbooleanWhether the frame was a confirmed uplink
devaddrstringLoRaWAN device address (hex) assigned after OTAA join
datastringRaw uplink payload as a hex-encoded byte string
decodedobjectDecoded 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 inside d2c-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:

FieldDescription
identifierDevice or resource identifier
typeLog entry type (e.g. provisioning, downlink)
serviceInternal adapter service that produced the entry
statusOutcome — 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.