Firmware Update Over The Air (FUOTA)

This release provides an implementation of the FUOTA specification. Currently the deployment is limited to one device as we would like to gather feedback on this implementation first. However, in this implementation the deployment to groups of devices is taken into account. Note: this feature is experimental and the API might change.

Updated rxInfo / txInfo (live frame-logs)

The LoRa Server <> LoRa Gateway Bridge messages have been updated to make the downlink scheduling more flexible and generic. This change exposes these fields in the live gateway and device frame-logs.

Payload codec

The payload codec settings have been moved to the Device Profile. Codec settings set in the application configuration still remain functional, but new codec settings must be configured in the Device Profile.


  • Fix organization admin cannot add existing users. (#315)


Please upgrade LoRa Server first to v3 (see Changelog), then upgrade LoRa App Server to v3. This LoRa App Server release is fully backwards compatible.



  • Make it possible in the API to move devices between applications.
  • Add DevAddr to enqueue API call to LoRa Server so that LoRa Server can validate the session-keys are in sync.
  • Add device details overview (UI).


  • Fix panic when JOSN object is set but contains null. (#314)



New integrations

Support has been added to forward events to an Azure service-bus or to AWS SNS. See Configuration.


  • Make JS codec maximum execution-time configurable and increase default value to 100ms.
  • Add configuration option for CORS headers. (#275)
  • Internal code-cleanup with regards to passing configuration and objects.
  • Internal migration from Dep to Go modules.
  • Improve authentication validator SQL query for speed. (#302)
  • Add codec execution time for decoding. (#307)
  • UI: Make delete application confirmation more explicit. (#306)



  • Fix panic in InfluxDB handler on null values in object (#295)



Support for retained messages

It is now possible to configure the retained flag for the MQTT integration. When set, the MQTT broker will retain the last message and send this immediately when a MQTT client connects. (#272)

Environment variable based configuration

Environment variable based configuration has been re-implemented.


  • Calls made by the HTTP integration are now made async.
  • The alignment of the UI tabs has been improved.


  • Fix potential deadlock on MQTT re-connect (#103)
  • Fix logrotate issue (init based systems) (#282



  • Fix createLeafletElement implementation error (introduced by v2.4.0 leaflet upgrade).



TLS for web-interface and API optional

It is no longer required to configure a TLS certificate for securing the LoRa App Server web-interface and API. This configuration is now optional and unset by default.

The following values have been added:

  • RSSI
  • SNR
  • Uplink frame-counter

EUI and key input fields (web-interface)

The device EUI and (session)key input fields have been improved for easier input, supporting both MSB and LSB byte order. Also only the required fields (based on LoRaWAN 1.0.x or 1.1.x) are displayed in the forms.



Google Cloud Platform integration

LoRa App Server is now able to publish application data to Cloud Pub/Sub as an alternative to a MQTT broker. Please refer to the Configuration for more information.

Deactivate device API

An API endpoint has been added to de-activate (not remove) devices.

Device battery status

LoRa App Server now publishes the device battery-level as a percentage instead of a value between 0...255. The battery field will be removed in the next major release.


  • The join-server ca_cert can be left blank to disable client-certificate validation when a TLS certificate is configured.


Upgrade notes

This upgrade is backwards compatible with previous v2 releases, but when using geolocation-support, you must also upgrade LoRa Server to v2.2.0+.



This release adds geolocation support.

  • Configuration of fine-timestamp decryption keys (e.g. for the Kerlink iBTS).
  • .../location MQTT topics on which device locations are published.
  • Location notification endpoint for HTTP integration.
  • Per device reference altitude (for more accurate geolocation).


  • Replace garyburd/redigo/redis with gomodule/redigo/redis.


  • Status notification endpoint was missing for HTTP integration.
  • Fix /api endpoint redirecting to web-interface (this might require a clear cache).


Upgrade notes

This upgrade is backwards compatible with previous v2 releases, but when using multicast-support, you must also upgrade LoRa Server to v2.1.0+.


Multicast support

This adds experimental support for creating multicast-groups to which devices can be assigned (potentially covered by multiple gateways).

LoRaWAN 1.0.3

This update adds LoRaWAN 1.0.3 in MAC version dropdown.


  • Fix organization selector dropdown styling.



  • Use gofrs/uuid UUID library as satori/go.uuid is not truly random. (#253)
  • Fix web-interface login form (sometimes a double login was required).


Upgrade notes

Before upgrading to v2, first make sure you have the latest v1 installed and running (including LoRa App Server). As always, it is recommended to make a backup first :-)


LoRaWAN 1.1 support

This release adds support for LoRaWAN 1.1 devices (meaning that both LoRaWAN 1.0 and LoRaWAN 1.1 devices are supported). Please note that the LoRaWAN 1.0 AppKey is now called NwkKey and LoRaWAN 1.1 adds a new key called AppKey.

(Encrypted) key signaling

The LoRa App Server join-server API supports using Key Encryption Keys (KEK) for encrypting the session-keys on a (re)join-request, requested by LoRa Server. It will also send the (encrypted) AppSKey in this response to LoRa Server.

When LoRa Server receives the first uplink from the device (in case of a rejoin-request, this will be the first uplink using the new security context), it will send this (encrypted) AppSKey together with the application payload to LoRa App Server. This will also be the moment when LoRa App Server will sent the join notification!

New UI

The LoRa App Server web-interface has been re-designed with a focus on better navigation. All main components are now accessible from a sidebar.



The device-status has been removed from the uplink payload and is sent over a separate MQTT topic (or HTTP integration). This to make sure that the the device-status is only published when an update is available. See also Sending and receiving data.

API changes

The API has been cleaned up to improve consistency and usability. This update affects most of the endpoints! Most of these changes can be summarized by the following example (where device is a separate object which now can be re-used for create / get and update methods).


POST /api/devices

  "name": "test-device",
  "devEUI": "0102030405060708",
  "applicationID": "123"

POST /api/devices

  "device": {
    "name": "test-device",
    "devEUI": "0102030405060708",
    "applicationID": "123"

InfluxDB changes

The device_uplink measurement spreading_factor, bandwidth, modulation and bitrate tags are now replaced by a single dr tag.

The uplink message payload (used for MQTT and HTTP integrations) has been modified slightly:

  • It now contains a dr field indicating the used uplink data-rate.
  • Location related fields of each rxInfo element has been moved inside a location object.
  • MAC has been renamed to gatewayID for each rxInfo element.
  • The adr field has been moved out of txInfo and moved into the root object.

The reference field has been removed to simplify the downlink queue handling. When using the REST or gRPC API interface, the response to an enqueue action contains the frame-counter mapped with the downlink queue item. This frame-counter then can be used to map the acknowledgement in case of a confirmed downlink payload.



  • Lock device row on downlink enqueue to avoid duplicated frame-counter values (#245)



  • tls_cert and tls_key are set automatically (again) when installing from .deb file.


This marks the first stable release!

Upgrade notes

  • First make sure you have v0.21.1 installed and running (together with LoRa Server v0.26.3).
  • As some configuration defaults have been changed (in the MQTT topic node has been replaced by device), make sure the old defaults are in you config file. To re-generate a configuration file while keeping your modifications, run:
      lora-app-server -c lora-app-server-old.toml configfile > lora-app-server.toml
  • You are now ready to upgrade to v1.0.0!

See Downloads for pre-compiled binaries or instructions how to setup the Debian / Ubuntu repository for v1.x.


  • In the MQTT topic configuration defaults, node has been replaced by device.
  • Code to remain backwards compatible with environment-variable based configuration has been removed.
  • Code to create device- and service-profiles on upgrade from v0.14.0 has been removed.
  • Code to migrate the device-queue on upgrade from v0.15.0 has been removed.
  • Code to create gateway-profiles on upgrade from v0.20.0 has been removed.
  • Old unused tables (kept for upgrade migration code) have been removed from db.



  • Fix InfluxDB handler error for unexported fields (these are now skipped).
  • Fix data_data in InfluxDB measurement names when using a JS based codec.
  • Add missing int64 and uint64 value handling.




  • In some cases the JavaScript editor (codec functions) would only render on click.



  • JS codec now handles all possible int and float types returned by the encoder function.
  • Fixed Gob decoding issues when decoding to interface{} by using JSON marshaler for logging events.

Improvements: * JS codec downlink errors are now logged to .../error MQTT topic.



  • Skip frame-counter check can now be set per device (so it can be used for OTAA devices).
  • Publish codec decode errors to the application/[applicationID]/node/[devEUI]/error MQTT topic.



  • (Gateway) channel-configuration has been refactored into gateway-profiles.
    • This requires LoRa Server 0.26.0 or up.
    • This removes the channel-configuration related gateway API methods.
    • This adds gateway-profile API methods.


  • Fix leaking Redis connections on pubsub subscriber (#313.
  • Fix discovery interval validation (#226).

Upgrade notes:

In order to automatically migrate the existing channel-configuration into the new gateway-profiles, first upgrade LoRa Server and restart it. After upgrading LoRa App Server and restarting it, all channel-configurations will be migrated and associated to the gateways. As always, it is advised to first make a backup of your (PostgreSQL) database.



  • Global search on organizations, applications, devices and gateways.
  • Display live device events (the same data as publised over MQTT). See also Event logging.


  • When creating an application, show a warning when no service-profile exists.
  • When creating a gateway, show a warning when no network-server has been associated.
  • When creating a device, show a warning when no device-profile exists.


  • Fix organization selector (which would sometimes show an empty value on select).
  • Fix user selector when assigning an user to an organization (which would sometimes show an empty value on select).

Upgrade notes:

Before upgrading, the PostgreSQL pg_trgm extension needs to be enabled. Assuming the LoRa App Server database is configured as loraserver_as this extension could be enabled using the commands below.

Start the PostgreSQL prompt as the postgres user:

sudo -u postgres psql

Within the PostgreSQL prompt, enter the following queries:

-- change to the LoRa App Server database
\c loraserver_as

-- enable the extension
create extension pg_trgm;

-- exit the prompt



  • Gateway discovery configuration has been moved to network-server configuration.
    • Important: when you have the gateway discover feature configured, you need to re-add this configuration under network-servers (web-interface).
  • Expose the following MQTT options for the MQTT gateway backend:
    • Configurable MQTT topics (uplink, downlink, join, ack, error)
    • QoS (quality of service)
    • Client ID
    • Clean session on connect
  • Expose LoRa Server version and configured region through the network-server API endpoint.
  • Websocket client automatically re-connects on connection error (#221)


  • The Class-C enabled checkbox was displayed twice in the web-interface.
  • Organization dropdown was not autocompleting correctly.



  • Expose Class-B fields in device-profile web-interface form.
    • Note: Class-B support is implemented since LoRa Server 0.25.0.


  • Fix factory preset frequency field in device-profile form.



  • LoRa App Server uses a new configuration file format. See configuration for more information.
  • Frame-logs for device are now streaming and can be downloaded as JSON file.
    • Note: the /api/devices/{devEUI}/frames (formerly Device.GetFrameLogs) endpoint has changed (and the gRPC method has been renamed to Device.StreamFrameLogs).
    • You need LoRa Server 0.24+ in order to use this feature.
  • Added streaming frame-logs for gateways (which also can be downloaded as JSON file).
    • You need LoRa Server 0.24+ in order to use this feature.
  • Support MQTT client certificate authentication (#201).

Upgrade notes:

When upgrading using the .deb package / using apt or apt-get, your configuration will be automatically migrated for you. In any other case, please see configuration.



  • Fix missing / prefix in two UI links causing a redirect to the login page.
  • Fix typo in TLS certificate loading causing error failed to find certificate PEM data in certificate input (thanks @Francisco_Rivas)



  • Device last seen timestamp is now stored and displayed in device list
  • In the service-profile, it is now possible to set the
    • Device-status request frequency
    • Report battery level
    • Report margin

When the interval is set to > 0 and reporting of this status is enabled, then this information is displayed in the device list and exposed over MQTT and the configured integrations.

  • Extra logging has been added:
    • gRPC API calls (to the gRPC server and by the gRPC clients) are logged as info
    • Executed SQL queries are logged as debug
  • A warning is displayed in the web-interface when creating a service-profile when no network-server is connected.
  • A warning is displayed in the web-interface when creating a device-profile when the organization is not associated with a network-server.

Internal changes:

  • The project moved to using dep as vendoring tool. In case you run into compiling issues, remove the vendor folder (which is not part of the repository anymore) and run make requirements.

  • The front-end code has been updated to use React 16.2.0 and all dependencies have been updated.


  • --gw-ping-dr 0 is now handled correctly (#204)



  • Implement client certificate validation for incoming application-server API connections.
  • Implement client certificate validation for incoming join-server API connections.
  • Implement client certificate for API connections to LoRa Server.

This removes the following CLI options:

  • --ns-ca-cert
  • --ns-tls-cert
  • --ns-tls-key

See for more information:


  • Optional note field (users) has been changed to textarea.
  • Description field of the gateway has been changed to textarea.


  • Fix device-profile permissions in UI for organization admins.
  • Fix device-profile list per applicationID showing all device-profile names and IDs on the same network-server as the service-profile associated with the given application.



  • LoRa App Server is now able to decode (uplink) and encode (downlink) payloads using the following per application configurable codecs:

    • None (only the raw base64 encoded data will be exposed)
    • Cayenne LPP (data will be encoded / decoded using the Cayenne LPP encoding)
    • Custom JavaScript codec functions (you can provide your own encoding / decoding functions in JavaScript)

See Applications documentation for instructions how to configure this option.



  • Downlink device-queue

    • Downlink device-queue has been moved from the LoRa App Server database to the LoRa Server database.
    • LoRa App Server sends nACK when no confirmation has been received on confirmed downlink transmission. See ACK notifications.
    • LoRa App Server will not re-try transmitting a confirmed downlink anymore.
    • ACK and error notifications now contain the fCnt to which the notification is related.
    • The downlink-queue is now flushed on a (re)activation.
  • Downlink device-queue API (/api/devices/{devEUI}/queue)

    • Removed DELETE /api/devices/{devEUI}/queue/{id} endpoint (as removing individual device-queue items will give fCnt gaps).
    • Added DELETE /api/devices/{devEUI}/queue to flush the whole device-queue.
  • Class-C

    • Class-C timeout (see device-profiles) has been implemented for confirmed downlink transmissions. Make sure to update this value for existing Class-C device-profiles to a sane value.



  • Use RFC1945 Authorization header format (thanks @fifthaxe)


This release depends on LoRa Server 0.23.0. Upgrade LoRa Server first. After upgrading LoRa App Server, it will migrate the remaining device-queue items to the LoRa Server database.



  • Fix unclosed response body (HTTP integrations).



  • Remove RxInfo length validation as this slice is empty when Add gateway meta-data is disabled in the service-profile (thanks @pni-jmattison).
  • Rename /api/node/... prefix of downlink queue into /api/device/... (thanks @iegomez).
  • Rename DownlinkQueue... gRPC methods and structs into DeviceQueue....


Note: this release brings many changes! Make sure (as always) to make a backup of your PostgreSQL and Redis database before upgrading.


  • Data-model refactor to implement service-profile, device-profile and routing-profile storage as defined in the LoRaWAN backend interfaces.

  • Application users have been removed to avoid complexity in the API authorization. Users can still be assigned to organizations.

  • LoRa App Server can now connect to multiple LoRa Server instances.

  • LoRa App Server exposes a Join-Server API (as defined in the LoRaWAN backend interfaces document), which LoRa Server uses as a default join-server.

  • E-mail and note field added for users.

  • Adaptive-datarate configuration has been moved to LoRa Server.

  • OTAA RX configuration has been moved to LoRa Server.

API changes:

  • New API endpoints:

    • /api/device-profiles (management of device-profiles)
    • /api/service-profiles (management of service-profiles)
    • /api/network-servers (management of network-servers)
    • /api/devices (management of devices, used to be /api/nodes, settings have been removed and device-profile field has been added)
  • Updated API endpoints:

    • /api/applications (management of applications, most of the settings are now part of the device-profile)
    • /api/gateways (management of gateways, network-server field has been added)
  • Removed API endpoints:

    • /api/applications/{id}/users (management of application users)
    • /api/nodes (management of nodes, has been refactored into /api/devices)

Note: these changes also apply to the related gRPC API endpoints.

How to upgrade

Note: this release brings many changes! Make sure (as always) to make a backup of your PostgreSQL and Redis database before upgrading.

Note: When LoRa App Server is running on a different server than LoRa Server, make sure to set the --as-public-server / AS_PUBLIC_SERVER (default localhost:8001).

This release depends on the latest LoRa Server release (0.22). Start with updating LoRa Server first. See also the LoRa Server changelog.

LoRa App Server will perform the data-migration when the --db-automigrate / DB_AUTOMIGRATE config flag is set. It will:

  • Create a network-server record + routing-profile on LoRa Server (so that LoRa Server knows how to connect back).
  • For each organization, it will create a service-profile
  • It will create device-profiles (either per device or per application when the “use application settings” is checked)



  • The list of nodes can now be filtered on DevEUI or name prefix (thanks @iegomez).



  • Rename Gateway ping to Gateway discovery.
  • Rename Frame logs to Raw frame logs and add note that these frames are encrypted.



  • Gateway ping for testing the gateway coverage (by other gateways). When configured, LoRa App Server will send periodically pings through each gateway which has the ping functionality enabled. See also [features]/lora-app-server/overview/features/.

Note: this release requires LoRa Server 0.21+ as the gateway ping feature depends on the ‘Proprietary’ LoRaWAN message-type.


  • Content-Type header was missing for HTTP integrations.



  • HTTP data integration. This makes it possible to setup per application http integrations (LoRa App Server posting to configurable HTTP endpoints). Note that LoRa Server will always send the data to the MQTT broker.


  • Better pagination in case there are many pages (thanks @iegomez).
  • Various code has been cleaned up.


  • Fixed duplicated resultset-items when requesting all applications within an organization.



  • Implement support for channel-configuration management. This makes it possible to assign channel-plans to gateways, which then can be used by LoRa Gateway Config.

Note: This feature is dependent on LoRa Server version 0.20.0+.



  • --mqtt-ca-cert / MQTT_CA_CERT configuration flag was added to specify an optional CA certificate (thanks @siscia).


  • MQTT client library update which fixes an issue where during a failed re-connect the protocol version would be downgraded (paho.mqtt.golang#116).


Features & changes:

  • Added frame logs tab to node to display all uplink and downlink frames of a given node. Note: This requires LoRa Server 0.18.0.
  • Updated organization, application and node navigation in UI.



  • Fix ABP sesstings not editable by organization admin (#85)


Features & Changes:

  • Channel-lists have been removed. Extra channels (if supported by the ISM band) are now managed by LoRa Server configuration.


  • On editing a gateway, disable the MAC input field (as this is the unique identifier of the gateway).
  • A pagination regression has been fixed (#82).

Note: when upgrading to this version with --db-automigrate / DB_AUTOMIGRATE set, channel-list data will be removed.


Features & changes:

  • Organization management so that applications and gateways can be managed per organization.
  • Node-session migrate function (to migrate from LoRa Server 0.11.*) has been cleaned up.


  • Openstreetmap tiles can now be fetched using https:// (in some cases Safari was not loading any tiles because of mixed content).
  • When the browser does not allow using the location service, is used as a fallback.
  • Map zoom in/out on scrolling has been disabled (to avoid accidental zoom on scrolling the page).

Many thanks again to @jcampanell-cablelabs for collaborating on this feature.



  • Fix race-condition between fetching the gateway details and getting the current location if the gateway location is not yet set (UI).


Features & changes:

  • Add ‘set to current location’ (create / update gateway in UI)


Features & changes:

  • Gateway management and stats
    • Gateway management UI and API (accessible by global admin users) was added.
    • Gateway locations are now exposed in the uplink MQTT topic
    • Requires LoRa Server 0.16.0+.
  • On MQTT and PostgreSQL connect error, LoRa App Server will retry instead of fail.

Many thanks again to @jcampanell-cablelabs for collaborating on this feature.


This release contains changes that are not backwards compatible!

Features & changes:

  • User management with support to assign users to applications.
  • API authentication / authorization (JWT token) format has been updated (it contains the username instead of all the permissions of the user). See API documentation for more information.
  • --jwt-secret / JWT_SECRET is now mandatory.
  • An initial user with admin / admin credentials will be created (change this password immediately!).
  • Node-session API has been removed, use the /api/nodes/{devEUI}/activation endpoint for getting (and setting) node activations.
  • Updated web-interface to support user management.
  • New API endpoints for creating users and assigning users to applications.

Many thanks to @jcampanell-cablelabs for collaborating on this feature.



  • Per application (network) settings. Settings like Class-C, ADR, receive-window, data-rate etc. can now be managed on an application level. Optionally, they can be overridden per node.
  • Applications and nodes are now paginated per 20 rows.


Features & changes:

  • Class-C support. When adding / changing nodes, tick the Class-C checkbox to enable Class-C support for a given node.
  • Application ID added to application overview (as it is needed to subscribe to MQTT topics).
  • Nodes are now sorted by name.

Note: For Class-C functionality, upgrade LoRa Server to 0.14.0 or above.


This release contains changes that are not backwards compatible!

Features & changes:

  • Nodes can now be grouped per application (e.g. called temperature-sensor). For backwards compatibility, the AppEUI is used as application name when upgrading.
  • Nodes can now be given a name (e.g. garden-sensor), which must be unique within an application. For backwards compatibility the DevEUI is used as name for the nodes when upgrading.
  • Application ID, and the name of the application and node are included in the MQTT payloads.
  • JWT token validation is now based on the ID of the application instead of the AppEUI (which should not be used for grouping nodes by purpose).
  • The gRPC and REST apis have been updated to reflect the above application and node name changes.
  • The MQTT topics (and payloads) are now based on the application ID and node DevEUI (see mqtt topics for more info).
  • An endpoint for activating nodes and for fetching the activation status has been added (before this was done by using the node-session endpoint).
  • The node activation mode can now be set (OTAA or ABP). Incoming join-requests for ABP nodes will be rejected.
  • The node-session API is now accessible at /api/node/{devEUI}/session.

Many thanks to @jcampanell-cablelabs and @VirTERM for their input on the API changes.


  • limit and offset url parameters are now correctly documented in the API console.
  • More descriptive error on missing --http-tls-cert and --http-tls-key configuration.



  • Adaptive data-rate support. See loraserver/features for more information about ADR. Note:

    • LoRa Server 0.13.0 or higher is required
    • ADR is currently only implemented for the EU 863-870 ISM band
    • This is an experimental feature
  • Besides RX information, TX information is exposed for received uplink payloads. See MQTT topics for more information.


  • Update exposed data which is published to the application/[AppEUI]/node/[DevEUI]/rx topic. SNR, RSSI and GPS time (if available) are now included of all receiving gateways.
  • Change GW_MQTT_SERVER environment variable to MQTT_SERVER (thanks @siscia).


  • Make the relax frame-counter option visible in the ui (the static files were not generated and included in 0.1.2).


  • Add relax frame-counter option (this requires LoRa Server >= 0.12.3)


  • Better labels + help text for ui components
  • Redirect to JWT token form on authorization error
  • Add small delay between http server start and gprc-gateway init (to work around internal connection errors)
  • Store all used DevNonce values instead of max. 10.


Initial release. LoRa App Server requires LoRa Server 0.12.0+.

Migrating data from LoRa Server

The database migrations of LoRa App Server are compatible with the database schema of LoRa Server 0.11.0. Running lora-app-server with --db-automigrate will forward migrate the database to the new structure.

Because of the decoupling of the inventory part from LoRa Server, some data needs to be migrated from Redis into PostgreSQL. This process can be automated by starting lora-app-server with the --migrate-node-sessions flag. This must be executed after running the database migrations (--db-automigrate flag, you can use both flags together).

When running lora-app-server with --migrate-node-sessions, it will loop through all nodes in the database (PostgreSQL) and backfill the DevAddr, NwkSKey and AppSKey from the node-session (Redis).

Make sure you have a backup of both databases before starting any migration :-)