Skip to content
Stand with Ukraine flag

Uplink Data Converter

The Uplink data converter is the decoding stage of every ThingsBoard integration, where raw payloads from an external device or network server are mapped to the ThingsBoard data model: device or asset name, profile, customer, group, telemetry values, and attributes.

ThingsBoard provides three ways to define the decoder:

  • Typed: Configure entity type, name patterns, and field mappings in the UI — ThingsBoard pre-fills a decoder script tailored to each integration type. No scripting needed for structured JSON payloads; for binary or custom-encoded payloads, edit the pre-filled decoder to match your device’s payload format. Supported integrations: ChirpStack, Loriot, The Things Stack Community, The Things Stack Industries, ThingPark, and ThingPark Enterprise.
  • Generic: Custom script, works with any integration type.
  • Library: Choose a vendor and model from a catalog of pre-built decoders for 100+ devices.

Each integration uses one converter. A converter can be shared across multiple integrations — changes apply immediately to all.

The uplink converter is configured in Step 2 of the integration wizard:

  • Previously created converter — select an existing converter.
  • Create new — for supported integration types, opens the typed converter wizard: configure field mapping in the UI and optionally write or edit a decoder script. For other integration types, opens a plain script editor.
  • Library — choose a vendor and model from the built-in catalog (supported integration types only).

The converter is saved to Integrations center ⇾ Data converters when the integration is saved. You can also create converters there in advance.

A generic converter works with any integration type and gives you full control over the decoding logic through a custom script.

  1. Go to Integrations center ⇾ Data converters.
  2. Click + Add data converter ⇾ Create new converter.
  3. Set Converter type to Uplink (default).
  4. Select an Integration type, or leave it as All to apply the converter across all integration types.
  5. Enter a Name.
  6. Write or paste the decoder script in Main decoding configuration.
  7. Click Test decoder function to validate.
  8. Optionally add keys to the Update only keys list in Advanced decoding parameters.
  9. Click Add.

The decoder function receives two parameters:

ParameterDescription
payloadRaw message payload. Type depends on content type: JSON object, UTF-8 string (Text), or byte array (Binary (Base64)).
metadataKey-value map with integration-level fields. integrationName is always present. Additional keys can be defined in the integration’s metadata settings.

For binary payloads, TBEL provides built-in helpers: parseBytesToInt, parseBytesToFloat, bytesToHex, decodeToString, and others. See the TBEL reference for the full list.

The function must return an object with these fields:

FieldRequiredDescription
deviceNameYes (device)Name of the device to create or update.
deviceTypeYes (device)Device profile name.
assetNameYes (asset)Name of the asset (alternative to deviceName).
assetTypeYes (asset)Asset profile name.
customerNameNoThe entity is assigned to this customer. ThingsBoard creates the customer if it does not exist.
groupNameNoThe entity is added to this entity group. ThingsBoard creates the group if it does not exist.
attributesNoKey-value map of attribute values. Values must be scalars — nested objects are not supported.
telemetryNoKey-value map of telemetry values, or a { ts, values } object with an explicit timestamp, or an array of { ts, values } objects to report multiple timestamps in one message. Values must be scalars — nested objects are not supported.

Example decoder:

var data = decodeToJson(payload);
return {
deviceName: data.deviceId,
deviceType: 'thermometer',
attributes: { serialNumber: data.sn },
telemetry: {
ts: data.timestamp,
values: { temperature: data.temp, humidity: data.rh }
}
};

Multiple telemetry timestamps example:

telemetry: [
{ ts: data.ts1, values: { temperature: data.temp1 } },
{ ts: data.ts2, values: { temperature: data.temp2 } }
]

Keys added to the Update only keys list in Advanced decoding parameters are written to the database only when their value differs from the previous message.

Available from ThingsBoard 4.0. Configure the entity type, name pattern, and key mappings in the UI — ThingsBoard pre-fills a decoder script for the selected integration type. For structured JSON payloads, no script changes are needed. For binary payloads, modify the pre-filled decoder to match your device’s payload format.

Supported integrations: ChirpStack, Loriot, The Things Stack Community, The Things Stack Industries, ThingPark, and ThingPark Enterprise.

  1. Go to Integrations center ⇾ Data converters.
  2. Click + Add data converter ⇾ Create new converter.
  3. Set Converter type to Uplink (default).
  4. Select a supported Integration type from the dropdown.
  5. Enter a converter name.
  6. Main decoding configuration
    • Set Entity type (Device or Asset) and enter a name pattern using $field references (e.g. Device $eui).
    • Review the auto-generated decoder script.
    • Optionally, use Test payload decoder to validate.
  7. Advanced decoding parameters
    • Review and adjust the pre-populated device profile, label, customer, group, telemetry keys, attribute keys, and update-only keys list.
  8. Click Add.

Entity type: The type of entity the converter creates or updates — Device (default) or Asset.

Device/Asset name: Name pattern for the entity. Use $field references to substitute values auto-extracted from the incoming message — for example, Device $eui. Available fields vary by integration type; common LoRaWAN fields include $eui, $deviceId, $applicationId, $devAddr. The full set for each integration is listed in the integration-specific guide and visible in the test decoder’s Metadata panel.

Decoder script: Auto-generated payloadDecoder(payload, metadata) function (TBEL or JavaScript) that decodes the raw device payload and returns sensor data as attributes and telemetry. You can modify or fully replace it.

The function receives:

  • payload — raw device payload as a byte array (frm_payload). This is the payload sent by the device, not the full integration message — ThingsBoard extracts the device payload automatically.
  • metadata — auto-extracted network fields, including ts (message timestamp in ms) and integration-specific keys such as eui, devAddr, fPort, rssi, snr, and others. The full set of available fields is visible in the test decoder’s Metadata panel and listed in Advanced decoding parameters.

The function must return:

return {
attributes: { key: 'value' },
telemetry: { ts: metadata.ts, values: { temperature: 23.5 } }
};

Do not return deviceName or deviceType — ThingsBoard resolves those from the entity type and name pattern above. To override entity properties from the script (for example, when the device name is encoded in the payload), set the corresponding fields on the result object before returning:

// result.name = 'MySensor'; // overrides the Device name pattern
// result.type = 'ASSET'; // overrides Entity type
// result.profile = 'SensorProfile'; // overrides Device profile name
// result.customer = 'Acme Corp'; // assigns device to a customer
// result.group = 'SensorsGroup'; // adds device to an entity group

All fields are pre-populated for the selected integration type. Adjust as needed.

ThingsBoard automatically extracts standard fields from the raw integration payload — deviceId, devEui, devAddr, fPort, rssi, snr, latitude, longitude, firmwareVersion, and many others — and makes them available as named keys. The decoder script receives payload as the raw binary payload bytes and only needs to handle the device payload itself. The fields below control how the auto-extracted network metadata keys are stored.

The decoder script output (result.attributes, result.telemetry.values) is independent from these fields — it carries device sensor data and is always stored. The Telemetry and Attributes lists here control only the auto-extracted network metadata, not the script output.

Device profile name: Profile assigned to the created or updated device. Supports $field substitution using auto-extracted keys (e.g. $deviceProfileName, $applicationId).

Device label: Optional label attached to the device. Supports $field substitution (e.g. $deviceId, $deviceName).

Customer name: If set, the device is assigned to this customer. ThingsBoard creates the customer if it does not exist.

Device group name: If set, the device is added to this entity group. ThingsBoard creates the group if it does not exist.

Telemetry: Auto-extracted network metadata keys to save as time-series telemetry (e.g. rssi, snr, latitude, longitude, decoded). decoded — if present — is the pre-parsed payload from a network-side payload formatter. Leave empty to save all available keys as telemetry.

Attributes: Auto-extracted network metadata keys to save as device attributes (e.g. eui, devAddr, fPort, bandwidth, spreadingFactor). Attributes hold the latest value only.

Update only keys list: Keys written to the database only when their value has changed since the previous message. Useful for slowly-changing metadata such as eui, devAddr, or fPort.

Built-in catalog of ready-to-use decoder functions for 100+ devices across six LoRaWAN network servers.

Supported integrations: ChirpStack, Loriot, The Things Stack Community, The Things Stack Industries, ThingPark, and ThingPark Enterprise.

  1. Go to Integrations center ⇾ Data converters and click + Add data converter ⇾ Create new converter.
  2. Set Converter type to Uplink and select a supported Integration type.
  3. Switch to the Library tab.
  4. Select the device Vendor.
  5. Select the device Model — the converter name, name pattern, decoder script, and advanced parameters are all auto-populated.
  6. Optionally rename the converter or adjust any values.
  7. Click Add.

The library is open-source and maintained on GitHub.

Launches the built-in testing tool, which lets you run the decoder against a sample message without connecting a real device.
Use it to verify that the script produces the expected attributes and telemetry before deployment.

  • Generic converter: click Test decoder function below the script.
  • Typed converter: click Test payload decoder below the script.

Payload content type: Encoding of the sample payload:

  • JSON: parsed as a JSON object.
  • Text: plain UTF-8 string.
  • Binary (Base64): Base64-encoded bytes, decoded to a byte array automatically.

Payload: Sample input for the decoder. Pre-filled with a representative example for the selected integration type.

Decoder script: The function payloadDecoder(payload, metadata) script loaded from the converter. You can edit it directly in the test dialog to try changes without saving the converter.

Metadata: Key-value pairs available via the metadata object. Pre-populated from the last received message if available; edit entries to simulate different scenarios. metadata.ts holds the message timestamp in milliseconds.

Updated RAW payload — clicking this button in the top-right corner opens a panel with the full raw JSON of the last received message. It contains all fields ThingsBoard receives at the integration endpoint. You can edit the payload directly here and click Apply to use it as the new test input — useful for simulating specific field values or edge cases without sending real device traffic.

Testing

Click Test to execute the script.

Decoder output: The raw object returned by the decoder — attributes and telemetry as they would be stored in ThingsBoard.

Converter output: The fully assembled message — entity type, name, profile, and all data as ThingsBoard will process it.

Converters can be exported as JSON and imported into any ThingsBoard instance, which is useful for sharing custom decoders across environments or team members.

Export: On the Data converters list, click the export icon on a converter row. Alternatively, open the converter details and click Export converter in the panel header. Save the downloaded JSON file.

Import: Click + Add data converter > Import converter, drag and drop the JSON file or click Browse file to select it, then click Import. All settings are restored: name, type, integration type, script, and advanced parameters.

All converters are listed in Integrations center ⇾ Data converters. From the list you can:

  • Edit: click a converter name to open it, make changes, and click Apply changes.
  • Delete: click the delete icon on a row, or select multiple converters and use bulk delete.

A converter is referenced by ID. If the same converter is assigned to multiple integrations, any change to the converter (script, advanced parameters) immediately affects all integrations using it.