Skip to content
Stand with Ukraine flag

LORIOT Integration

The LORIOT integration connects ThingsBoard to a LORIOT LoRaWAN Network Server over HTTP. LORIOT pushes uplink messages from your LoRaWAN devices to a ThingsBoard HTTP endpoint; the uplink converter decodes each message and stores the result as device telemetry and attributes on the platform. In the reverse direction, ThingsBoard encodes Rule Engine messages via the downlink converter and delivers them to devices through the LORIOT REST API.

Before creating the integration, ensure:

  • You have access to ThingsBoard Cloud with integration functionality enabled for your tenant.
  • You have permissions to create integrations and data converters.
  • You have a LORIOT account with at least one registered application. If you do not have an account yet, follow the Register a LORIOT Account step below.
  1. Go to the LORIOT website. Under Free Community Public Server, click Register Now.
  2. Select your preferred region — for example, Europe → Amsterdam, NL.
  3. On the login page that opens, click Register a new account.
  4. Fill in the registration form: First Name, Last Name, Country, E-Mail, and Password. Accept the Terms of Service and click Create a free account.
  5. Log in — the LORIOT dashboard opens.
  1. In the LORIOT dashboard, click Applications in the left sidebar.
  2. Click + New LoRaWAN® Application.
  3. Enter a Name — e.g. ThingsBoard. Set Device Capacity to the maximum number of devices you plan to connect, then click Create.

You will need the server identifier and Application ID when configuring the ThingsBoard integration connection settings.

  • Server — the cluster code shown in the server selector dropdown in the top-right corner of the LORIOT dashboard (e.g. EU2 for Amsterdam, EU1 for Frankfurt). Enter it in lowercase when filling in the ThingsBoard integration settings — for example, eu2.
  • Application ID — the value in the Application ID column on the Applications page (e.g. BE010A45).

The uplink converter receives each LORIOT uplink message, decodes the LoRaWAN payload, and returns a structured object that ThingsBoard uses to create or update a device and store its telemetry and attributes.

If your device is in the built-in catalog, use the Library tab instead of writing a decoder — see Converters library for over 100 ready-made decoders.

For the full decoder function reference — all input parameters and output fields — see Uplink Data Converter.

  1. Go to Integrations center ⇾ Data converters.
  2. Click + Add data converter ⇾ Create new converter.

In the Add data converter dialog:

  1. Converter type — leave Uplink (selected by default).
  2. Integration type — in the search field, enter Loriot and select Loriot from the list.
  3. Name — enter a converter name, for example Loriot Uplink Converter.
  4. Configure main decoding parameters:
    • Device name — the default value Device $eui names each ThingsBoard device using the EUI from the LORIOT uplink message (e.g. Device BE7A000000000552). On the first uplink ThingsBoard creates the device; on subsequent uplinks it updates the existing one. Change this pattern if you prefer a different naming scheme.
    • The default decoder is pre-filled. Leave it unchanged for this guide.
      By default the editor opens in TBEL; use the TBEL / JS toggle (upper right) to switch languages.
    /**
    * Decodes the incoming payload and returns a structured object containing telemetry data and attributes.
    *
    * @param {byte[]} input - The raw payload received as an array of bytes.
    * @returns {Object} output - The structured output with decoded telemetry and attributes.
    */
    function decodePayload(input) {
    // Initialize the output object with empty attributes and telemetry for clarity.
    var result = { attributes: {}, telemetry: {}};
    // Decode serial number (SN) from the first 4 bytes of the payload.
    // Press '?' icon in the top right corner to learn more about built in helper functions and capabilities.
    result.attributes.sn = parseBytesToInt(input, 0, 4);
    // Extract the timestamp from metadata (represented in milliseconds).
    var timestamp = metadata.ts; // ts from the incoming message.
    // Initialize an object to store decoded key/value telemetry data.
    var values = {};
    // Decode battery level from the 5th byte of the payload.
    values.battery = parseBytesToInt(input, 4, 1);
    // Decode temperature from the 6th and 7th bytes of the payload (divided by 100).
    values.temperature = parseBytesToInt(input, 5, 2) / 100.0;
    // Decode saturation from the 8th byte of the payload.
    values.saturation = parseBytesToInt(input, 7, 1);
    // Combine the timestamp with values and add it to the telemetry.
    result.telemetry = {
    ts: timestamp,
    values: values
    };
    // Return the fully constructed output object.
    return result;
    // Same logic, less code:
    // return {
    // attributes: {
    // sn: parseBytesToInt(input, 0, 4)
    // },
    // telemetry: {
    // ts: metadata.ts,
    // values: {
    // battery: parseBytesToInt(input, 4, 1),
    // temperature: parseBytesToInt(input, 5, 2) / 100.0,
    // saturation: parseBytesToInt(input, 7, 1)
    // }
    // }
    // };
    }
    var result = decodePayload(payload);
    // Uncomment this code block to overwrite values set in the main configuration window. Useful if you extract device/asset/customer/group names from the payload;
    // result.type = 'DEVICE'; // Entity type allows you to choose type of created entity. Can be 'DEVICE' or 'ASSET'.
    // result.name = 'Temperature Sensor'; // Device or asset name (the value must be unique)
    // result.profile = 'IndustrialSensorProfile'; // Device or asset profile name.
    // result.customer = 'MyCustomer'; // If customer is not null - created entity will be assigned to customer with such name.
    // result.group = 'SensorsGroup'; // If group is not null - created entity will be added to the entity group with such name.
    // Return the final result object.
    return result;
  5. Review advanced decoding parameters — pre-populated for LORIOT; leave defaults unless your setup differs.

    The default telemetry keys extracted from LORIOT messages include: data, fCnt, rssi, snr.

    The default attribute keys include: eui, fPort, dr, freq.

  6. Click Add.

What the Converter Receives

ThingsBoard passes two variables to the decoder function:

VariableTypeDescription
payloadbyte arrayThe raw LoRaWAN payload bytes from the LORIOT data field.
metadataobjectKey-value map populated from the LORIOT uplink HTTP message.

Key metadata fields available in the decoder:

FieldDescription
metadata.tsUplink timestamp in milliseconds, parsed from the LORIOT ts field; falls back to server time if the field is absent or unparseable.
metadata.EUIDevice EUI, e.g. BE7A000000000552 — used as the device identifier by the default Device $eui naming template.
metadata.portLoRaWAN frame port (fPort).
metadata.rssiReceived signal strength indicator (dBm).
metadata.snrSignal-to-noise ratio (dB).
metadata.drData rate string, e.g. SF12 BW125 4/5.
metadata.freqTransmission frequency in Hz.
metadata.fcntFrame counter.
metadata.cmdLORIOT message command type — typically rx for uplinks.

Example: Binary Payload Decoded

The decoder assumes a fixed binary payload structure. It reads byte ranges using parseBytesToInt(input, offset, length) and produces:

BytesFieldOutput typeExpressionNotes
0–3snattributeparseBytesToInt(input, 0, 4)Device serial number
4batterytelemetryparseBytesToInt(input, 4, 1)Battery level
5–6temperaturetelemetryparseBytesToInt(input, 5, 2) / 100.0Raw value ÷ 100
7saturationtelemetryparseBytesToInt(input, 7, 1)Saturation level

Example payload (hex):

00BC614E5F092950

Example output:

{
"attributes": { "sn": 12345678 },
"telemetry": {
"ts": 1690000000000,
"values": {
"battery": 95,
"temperature": 23.45,
"saturation": 80
}
}
}

Adapting the Converter

  • Different device name — change the Device name pattern in Main decoding configuration (e.g. replace Device $eui with a fixed string or a field extracted from the payload).
  • Different byte layout — adjust the offset and length in each parseBytesToInt() call to match your payload structure.
  • Different field names — rename battery, temperature, or saturation; add or remove fields as needed.
  • Additional attributes — add more keys to result.attributes (e.g. result.attributes.firmwareVersion = parseBytesToInt(input, 8, 2)).
  1. Go to Integrations center ⇾ Integrations and click + Add integration.
  2. Basic settings:
    • Select Loriot as the integration type.
    • Enter a Name for the integration, or keep the default Loriot integration.
    • Enable integration and Allow create devices or assets are enabled by default — leave them enabled.
    • Click Next.
  3. Uplink data converter:
    • Click Select existing and choose the Loriot Uplink Converter created in the previous step.
    • Alternatively, click Create new to define the decoder inline, or use Library to load a vendor-provided preset.
    • Click Next.
  4. Downlink data converter:
    • Click Skip — the downlink converter is only needed for sending commands to devices and can be added later.
  5. Connection:
    • Copy the HTTP endpoint URL — you will need it when configuring LORIOT.
    See Connection Settings for a full description of each parameter.
  6. Click Add to create the integration.

Base URL

The base address of the ThingsBoard server, used to construct the HTTP endpoint URL below. For ThingsBoard Cloud this is pre-filled automatically.

HTTP Endpoint URL

Auto-generated webhook endpoint for this integration. LORIOT sends uplink messages to this URL as HTTP POST requests. Copy it before closing the wizard — you will need it in the next step.

Create Loriot Application Output / Send Downlink

These two toggles share a common settings group. Enabling either one reveals the following shared fields:

ParameterDescription
ServerLORIOT server subdomain — e.g. eu2. See Locate Server and Application ID.
DomainLORIOT domain — default is loriot.io.
Application IDYour LORIOT application ID.

Create Loriot Application output — when enabled, ThingsBoard automatically registers itself as an HTTP Push output in your LORIOT application via the LORIOT API, so no manual webhook configuration is needed. Enabling this additionally reveals:

ParameterDescription
Credentials typeAuthentication method for the LORIOT API. Basic — enter your LORIOT account Email and Password. Security token — enter a Token generated in your LORIOT account.

Send downlink — when enabled, ThingsBoard can send commands to LORIOT devices via the LORIOT API. Enabling this additionally reveals:

ParameterDescription
Downlink URLAuto-populated as https://{server}.loriot.io/1/rest. Override only if your LORIOT setup uses a non-standard endpoint.
Application Access TokenLORIOT API token used to authenticate downlink requests. Generate this in the Access Tokens section of your LORIOT application.

Enable Security (Headers Filter)

When enabled, ThingsBoard validates an HTTP header on every incoming uplink request and rejects requests that do not carry the expected header/value pair. Click Add to define one or more Header / Value pairs.

Execute Remotely

When enabled, ThingsBoard generates an Integration key and Integration secret. Use these credentials to run the integration as a separate remote process — useful when the integration must reach services not accessible from the ThingsBoard server. See Remote Integrations for setup instructions.

Advanced Settings

ParameterDescription
Replace response status from ‘No Content’ to ‘OK’When enabled, ThingsBoard responds with HTTP 200 instead of 204. Enable if LORIOT treats a 204 response as an error.
DescriptionOptional text description for this integration.
MetadataKey-value pairs injected into every uplink message as integrationMetadata in converter scripts.

To receive uplinks, ThingsBoard must be registered as an HTTP output in your LORIOT application. Choose the method that fits your setup — both result in the same data flow.

Use this method when you prefer not to store LORIOT credentials in ThingsBoard, or when your LORIOT account does not support API access.

  1. Log in to your LORIOT account, go to Applications, and click your application name to open it.
  2. In the left sidebar, click Output.
  3. Click Add New Output.
  4. On the Select your preferred output page, click HTTP Push, then click Continue.
  5. Optionally enter an Output Name. Paste the HTTP endpoint URL copied from the integration connection step into the Target URL for POSTs field. Click Continue.

To reject requests that don’t include specific HTTP headers, enable Enable security (Headers filter) in the integration settings.

  1. Open the Loriot integration in ThingsBoard, click the edit (pencil) icon, and enable Enable security (Headers filter).
  2. Click Add and enter a header name (e.g. authorization) and value (e.g. secret).
  3. Click Apply changes to save the integration settings.
  1. In LORIOT, open your application and go to Output. Click the ThingsBoard HTTP Push output to open its settings.
  2. Click the edit (pencil) icon. In the Custom Headers section, enter the same header name and value in the Key and Value fields, then click Add New Custom headers. Then click Save changes.

After the integration is created and the LORIOT webhook is configured, send a test uplink and confirm that ThingsBoard received the message, decoded it correctly, and provisioned the device.

To verify the integration, use one of the following methods:

Option A — Real device (recommended)

Power on a LoRaWAN device registered in your LORIOT application and let it transmit an uplink. Once a message is received, ThingsBoard automatically creates the device and stores its telemetry.

Option B — curl directly to the ThingsBoard HTTP endpoint

Send a simulated LORIOT uplink payload directly to the ThingsBoard HTTP endpoint. This bypasses LORIOT entirely and lets you confirm that the converter and integration are working before a real device is available.

Replace $HTTP_ENDPOINT_URL with the copied HTTP endpoint URL and run:

Without security:

Terminal window
curl -v -X POST \
-H "Content-Type: application/json" \
-d '{"EUI":"BE7A000000000552","data":"00BC614E5F092950","port":1,"cmd":"rx","dr":"SF12 BW125 4/5","snr":1.2,"ack":"false","freq":868500000,"fcnt":1,"rssi":-130,"ts":1613745998000}' \
"$HTTP_ENDPOINT_URL"

With security header:

Replace $HTTP_ENDPOINT_URL, $HEADER_NAME, and $HEADER_VALUE with the actual values from your integration settings and run:

Terminal window
curl -v -X POST \
-H "Content-Type: application/json" \
-H "$HEADER_NAME: $HEADER_VALUE" \
-d '{"EUI":"BE7A000000000552","data":"00BC614E5F092950","port":1,"cmd":"rx","dr":"SF12 BW125 4/5","snr":1.2,"ack":"false","freq":868500000,"fcnt":1,"rssi":-130,"ts":1613745998000}' \
"$HTTP_ENDPOINT_URL"

The data field 00BC614E5F092950 matches the byte layout from the uplink converter: sn = 12345678, battery = 95, temperature = 23.45, saturation = 80.

Go to Integrations center ⇾ Integrations, open Loriot integration, and click the Events tab. Each successfully processed uplink appears as a row with status OK. Click an event row to inspect the raw HTTP request body received from LORIOT.

Go to Integrations center ⇾ Data converters, open Loriot Uplink Converter, and click its Events tab:

  • In — the raw payload bytes passed to the decoder.
  • Out — the decoded result: attributes and telemetry values written to ThingsBoard.
  • Metadata — HTTP request headers and all LORIOT message fields (EUI, cmd, data, fPort, rssi, snr, ts, etc.).

Go to Entities ⇾ Devices. ThingsBoard automatically provisions a new device named Device <EUI> (e.g. Device BE7A000000000552) on the first uplink from each end device. Open the device and click the Latest Telemetry tab — you should see temperature, battery, and saturation decoded by the converter, plus network metadata fields such as rssi, snr, and dr extracted from the LORIOT message.

To send commands from ThingsBoard to LORIOT devices, configure a downlink converter, enable sending downlinks in the integration, and connect an Integration Downlink node in the Rule Chain.

The downlink converter encodes a ThingsBoard Rule Engine message into a LORIOT-compatible payload. The encoder output must include two fields in metadata required by the LORIOT REST API:

FieldDescription
metadata.EUIThe LORIOT device EUI — read from metadata.cs_eui, injected by the Originator attributes node from the device client attribute eui (ThingsBoard prefixes client-scope attributes with cs_).
metadata.portThe LoRaWAN port — read from metadata.cs_fPort, injected by the Originator attributes node from the device client attribute fPort.

For the full encoder function reference, see Downlink Data Converter.

  1. Open the Loriot integration and click the edit (pencil) icon.
  2. Next to Downlink data converter, click Create new.
  3. In the Add data converter dialog: enter a name (e.g. Loriot Downlink Converter), paste the encoder function below, and click Add.
  4. The converter is now assigned to the integration. Click Apply changes.
// Encode downlink data from incoming Rule Engine message.
// msg - JSON message payload (e.g. { "state": "on" })
// msgType - message type, e.g. 'ATTRIBUTES_UPDATED'
// metadata - enriched by the Originator attributes node with device client attributes.
// ThingsBoard prefixes client-scope attributes with "cs_":
// metadata.cs_eui — LORIOT device EUI stored on first uplink (e.g. "466ECD510CF7B021")
// metadata.cs_fPort — LoRaWAN frame port stored on first uplink (e.g. "1")
var eui = metadata.cs_eui;
// Default port to 1 when the device fPort attribute is missing or empty.
var port = (metadata.cs_fPort != null && metadata.cs_fPort != '') ? parseInt(metadata.cs_fPort) : 1;
var result = {
// Downlink data content type: JSON, TEXT, or BINARY (base64 format).
contentType: "JSON",
// Downlink data — serialise the full message payload as a JSON string.
data: JSON.stringify(msg),
// metadata must include EUI and port for LORIOT delivery.
metadata: {
"EUI": eui,
"port": port
}
};
return result;

To send messages from ThingsBoard to LORIOT devices, enable Send downlink in the integration settings and provide the LORIOT API credentials.

  1. In LORIOT, open your application and click Access Tokens in the left sidebar. Copy an existing token or click Generate another authentication token.
  2. In ThingsBoard, open the Loriot integration and click the edit (pencil) icon.
  3. Enable Send downlink and fill in the required fields:
    • Server — the LORIOT server subdomain (e.g. eu2); see Locate Server and Application ID.
    • Application ID — the Application ID from your LORIOT application.
    • Application Access Token — paste the token copied from LORIOT.
  4. Click Apply changes.

To trigger a downlink when a shared attribute changes, add three nodes to the Root Rule Chain: a Script filter node that passes only shared attribute updates, an Originator attributes node (Enrichment category) that reads the device eui and fPort client attributes into message metadata, and an Integration Downlink node (Action category) that forwards the encoded message to the LORIOT integration.

  1. Open Rule Chains ⇾ Root Rule Chain and click the edit icon.
  2. In the node panel (under Filter), search for script and drag it onto the canvas.
  3. Configure the node:
    • Nameto Loriot Downlink Command.
    • Enter the TBEL filter function: return msgType == "ATTRIBUTES_UPDATED" && metadata.scope == "SHARED_SCOPE" && msg != null;
    • Click Add.
  4. In the node panel (under Enrichment), search for originator attributes and drag it onto the canvas.
  5. Configure the node:
    • NameRetrieve eui and fPort.
    • Under Client attributes, add two keys: eui and fPort.
    • Set Add originator attributes to to Metadata.
    • Click Add.
  6. In the node panel (under Action), search for integration downlink and drag it onto the canvas.
  7. Configure the node:
    • NameDownlink to Loriot.
    • Integration — select Loriot integration.
    • Click Add.
  8. Connect the Message Type Switch node to the to Loriot Downlink Command node via the Post attributes / Attributes Updated relations.
  9. Connect the to Loriot Downlink Command node to the Retrieve eui and fPort node via the True relation.
  10. Connect the Retrieve eui and fPort node to the Downlink to Loriot node via the Success relation.
  11. Click Apply changes.

If you do not have a physical LoRaWAN device available, register a virtual device in LORIOT using the same EUI used in the uplink test (BE7A000000000552). This ensures LORIOT has a device entry to accept the downlink and queue it for delivery.

  1. In your LORIOT application, click Enroll Device in the left sidebar.
  2. Select LoRaWAN® 1.0.x as the LoRaWAN version and keep Over the Air Activation. Click through to Device Details.
  3. Enter a Device name (e.g. my-device), select Class A, and set the Device EUI to BE7A000000000552 (or click Autogenerate to use a new EUI — then use the same value in the curl test uplink).
  4. In the Activation section, the JoinEUI is auto-filled. Leave AppKey empty.
  5. Skip Location and click Create Device.

Adding or updating a shared attribute triggers the Rule Chain, which runs the downlink converter and posts the encoded command to LORIOT.

  1. Go to Entities ⇾ Devices, select your device (e.g. Device BE7A000000000552), and open the Attributes tab.
  2. Switch to Shared attributes and click +.
  3. Enter key (e.g. powerState) and value (e.g. on), then click Add.

Go to Integrations center ⇾ Data converters, open Loriot Downlink Converter, and click the Events tab — a Downlink event should appear in the list.

In the event row, use In, Out, and Metadata to inspect each stage.

To confirm the message reached LORIOT, use either of the following:

  • Device view — Open the device in LORIOT, go to LoRaWAN® Parameters, and scroll to Sequence Numbers. FCntQueue = 1 confirms the downlink is queued waiting for the next device uplink.
  • Application Log — In your LORIOT application, click Log in the left sidebar. A green HTTP entry for your device EUI confirms the downlink was processed.

This section covers the most common problems encountered when setting up and running the LORIOT integration. Each entry describes the symptom, the most likely cause, and the steps to resolve it.

No Uplinks Received

SymptomCauseFix
No uplinks received in ThingsBoardWrong HTTP endpoint URL in LORIOTOpen the Loriot integration, copy the HTTP endpoint URL from the integration details, and paste it into the LORIOT HTTP Push output URL field.
No uplinks receivedContent-Type not set to application/jsonIn the LORIOT HTTP Push output settings, confirm Content type is set to application/json. LORIOT may send text/plain by default, which ThingsBoard cannot parse.
No uplinks receivedSecurity header mismatchIf Enable security (Headers filter) is on, the header name and value in LORIOT’s Custom header fields must exactly match what is configured in ThingsBoard. Open the integration edit mode and compare both values.
No uplinks receivedIntegration is disabledOpen the integration and confirm Enable integration is toggled on.
HTTP Push output shows delivery errors in LORIOTThingsBoard instance is unreachableConfirm your ThingsBoard instance is publicly accessible. The LORIOT Network Server must be able to reach the HTTP endpoint URL over the internet.

Uplink Received but Device Not Created

SymptomCauseFix
Uplink received, no device in ThingsBoardAllow create devices or assets is disabledOpen the integration, click the pencil icon, and enable Allow create devices or assets in the Basic settings step.
Uplink received, no device in ThingsBoardConverter returns an empty device nameGo to Integrations center ⇾ Data converters, open the uplink converter, and click the Events tab. Inspect the Out panel of a recent event — confirm name is present and non-empty. If the Device $eui template is used, confirm metadata.EUI is populated in the In panel.
Uplink received, converter shows errorTBEL or JavaScript exception in the decoderOpen the uplink converter Events tab, filter by Error, and inspect the stack trace. Common causes: incorrect byte offset, division by zero, or undefined variable.

Downlink Not Delivered

SymptomCauseFix
Downlink converter Events tab is emptyRule Chain misconfiguredIn the Root Rule Chain, confirm the Post attributes / Attributes Updated node is connected to the to Loriot Downlink Command script node via Success, and that the chain continues to Retrieve eui and fPortDownlink to Loriot.
Downlink converter fails with Downlink data is not set!Originator attributes node missing from Rule Chain — metadata.cs_eui and metadata.cs_fPort are emptyAdd an Originator attributes node between to Loriot Downlink Command and Integration Downlink in the Root Rule Chain. Add eui and fPort as Client attributes and set Add to Metadata. See Configure the Root Rule Chain.
Downlink converter triggered, but no message in LORIOTEUI or port missing from encoder metadataOpen the downlink converter Events tab, click the Out panel, and confirm both metadata.EUI and metadata.port are present and non-empty.
Downlink sent to LORIOT but device does not receive itWrong Application Access TokenOpen the integration edit mode and verify the Application Access Token matches the token in your LORIOT application Access Tokens section. Regenerate if in doubt.
Downlink payload appears double-encodedHex data sent without isHexEncoded flagIf your data field contains a hex string, add "isHexEncoded": "true" to the encoder metadata. See the note in Add a Downlink Converter.

How to Read Debug Events

  1. Go to Integrations center ⇾ Integrations, open Loriot integration, and click the Events tab.
  2. Click an event row to inspect:
  • In — the raw HTTP request body received from LORIOT before processing.
  • Out — what the converter returned: device name, attributes, and telemetry values passed to ThingsBoard.
  • Error — error text and stack trace, if processing failed. Enable Debug mode on the integration to capture all raw input/output events. Starting from ThingsBoard 3.9, full debug events are stored only during the first hour — afterwards, only error events are retained. Disable debug mode once the issue is identified.