View source
How is built.

About the project

We consider this a reference implementation for a consumer cellular IoT product, where Nordic development kits are treated like a consumer cellular IoT device, for example a Robot Lawnmower, which is purchased by a consumer at a retail store, and when turned on should work just like that.

The backend

For this to work we use nRF Cloud's ProvisionDevices endpoint to pre-provision the devices to a nRF Cloud tenant and ship a pre-activated SIM card.

We have set up a Message Bridge that forwards messages from these devices to our backend, which is in charge of transforming these messages into the format that is understood by the web application.

This includes regularly fetching the shadow of the devices using the nRF Cloud REST API.

It also maintains the database of devices that can be access on this website using their fingerprint.

Check out the source code of the project on GitHub, and especially the feature files that document the functionality that has been implemented.

The firmware

Devices connect directly to the nRF Cloud MQTT endpoint and are running the asset_tracker_v2 application. Firmware builds are published in an out-of-tree repository on GitHub so we can provide pre-compiled builds with the configuration that is optimal for the out-of-box experience. .

Cloud connection

Devices need to connect nRF Cloud using a certificate that is pre-provisioned (in case of our development kits) or has been created using the custom device onboarding (this feature not yet available) of

Why the attestation token cannot be used

nRF 9x devices with modem firmware >=2.0.0 ship with an attestation token which can be used directly to authenticate against nRF Cloud's CoAP API, but only after it has been on-boarded.

This means that a device would need to be associated with the nRF Cloud Account for the out-of-box experience to work.

But if users want to use their device with their own nRF Cloud it would have to be disassociated from the nRF Cloud account first.

This would also not allow a fallback in case the users hands over this device to a colleague. They would then need to disassociate the device from their account first.

Provisioning the device with a second certificate solves this:

  • If a user wants to use the device with their own nRF Cloud account they can flash any firmware as long as it is not using the secTag 42.
  • If they want the original out-of-box behaviour, they only have to flash the out-of-box firmware back.

The frontend

The web site is a static web app, and the source code is published on GitHub.

It is build using Vike which allows to build both a dynamic web app with Preact and TypeScript as well as render static pages (for example for the development kit pages) using Markdown files.

The base UI framework is Bootstrap 5 which has been modified to match Nordic Semiconductor's style guide.

The Lucide icons are used to annotate interactive elements.

The map

Device owners (those who know the fingerprint of a device) can opt-in to make the device data publicly available on

Data published by the device to nRF Cloud will be visible to everyone if it follows the LwM2M object definitions for this project. This allows anyone to describe the data their device is sending and for the map application interpret arbitrary device information. Certain objects (for example location, environment) will have additional UI features, which can be re-used for all devices that fulfill the object definition.

This only works if the device connects to nRF Cloud using the credentials.

nRF Cloud Location services

This project integrates directly with the nRF Cloud Location services for showing device location on the map.

Ground fix API

The coarse location of a device is acquired by using the Ground fix API, which turns neighboring cell scans of the device (which contain LTE and Wi-Fi cell information), into an approximate location.

The device sends these cell scans using the GROUND_FIX message via MQTT.

nRF Cloud resolves these scans to a geo location and sends the location via MQTT to the device.

These messages are received by the backend using the a message bridge.

QR codes

The easiest way to access the page for an individual device is to scan a QR code, which encodes a fingerprint (more about that later) and the URL of this page.


Here is an example:

The QR code encodes a link with a fingerprint (e.g. 92b.d3c4fb) that contains the production run number (e.g. 2347) and a unique token (e.g. d3c4fb) that will prove a user's ownership of the kit and will be used to look up the device information in our database.

The production run number is an integer created by combining the last two digits of the year and the week number. This way the generated fingerprint can be short and does not have to be globally unique. During production runs, uniqueness check only needs to be done locally.

In the fingerprint, the production run number is HEX encoded to reduce the number of characters in the fingerprint.

Manually entering the fingerprint

If users cannot scan the QR code because they do not have a camera, they have to enter the fingerprint manually.

The fingerprint is designed so that there are no ambiguous letters, e.g. o (lowercase "o") and 0 (Zero), which enables the user to enter it manually without making too many mistakes.