Tutorial
Understanding mioty blueprints
From raw bytes to structured data, and some best practices
Introduction
Last updated: 2026-01-15
Every mioty® device sends its measurements as a few raw bytes over the air. That keeps transmissions short and battery use low, but it also means the receiving side has no idea, on its own, that byte 0 and 1 are a temperature in tenths of a degree. Traditionally every manufacturer solves this with its own decoder, so an integrator ends up maintaining a separate parser per device, which does not scale.
A mioty® blueprint fixes this. It is a standardized way to describe a device payload, so a capable application center can turn the raw bytes into structured values without you writing custom code for each vendor. This tutorial explains what a blueprint is, how to write one step by step, where its limits are, and how to validate it.
It is written for device manufacturers, system integrators, and end customers.
What you’ll need
1. Why does a mioty payload need a description at all?
If you come from the world of IP traffic, you are used to self-describing data. An HTTP or MQTT message usually carries JSON with field names and types baked right in, so the receiver can read it without any prior agreement.
On an LPWAN this luxury is too expensive. Airtime is limited, duty cycles are regulated, and endpoints run on a battery for years, so every byte on the air counts. A mioty® device therefore sends the bare minimum: raw bytes, no field names, no types, no units.
A temperature reading, for example, fits comfortably in two bytes as an unsigned integer. The same value sent as JSON text costs far more, because every character is a byte:
That is 20 bytes on the air instead of 2, ten times the payload, and even shrinking the key to a single letter still costs five times as much while throwing away the descriptive name. That multiplier is battery and airtime you do not get back.
So the raw bytes have to be mapped to a value, a type and a unit somewhere before an IoT platform can consume them or emit JSON. In mioty® that mapping is the blueprint.

2. What a mioty blueprint is
A blueprint is a JSON file that describes the structure of a device payload. It standardizes the way the payload is described, not the payload itself, so you keep full freedom in your custom payload design while staying interoperable.
One point is worth stressing early: a blueprint only describes the payload, it does not decode it. You still need a decoder, in your application center or on your platform, that reads the description and applies it to the incoming bytes.
Here is the smallest blueprint that is still valid, describing a single temperature value:
2.1 The typeEUI
Every blueprint carries a unique identifier called the typeEui, taken from the vendor’s IEEE EUI-64 range. If you are integrating someone else’s device and do not have a typeEUI at hand, ask the device manufacturer for it, you do not mint your own.
2.2 A blueprint is data, not code
Some technologies decode payloads with small JavaScript snippets pasted into the platform. That is executable code, and a potential security risk for whoever operates the platform if it is not sandboxed carefully. A mioty® blueprint is pure declarative JSON, with no executable code, so any application center can accept and store it quickly without opening that attack surface.
| Approach | Sent over the air | Security to integrate |
|---|---|---|
| mioty® blueprint | Raw bytes only, description held in backend | Declarative JSON, safe to paste |
| Self-describing payload (e.g. OMS) | Data plus descriptor, heavier payload | No external decoder needed |
| JavaScript decoder | Raw bytes only | Executable code, needs sandboxing |
3. Why blueprints matter, and how they differ from other methods
Describe your payload once as a blueprint and it works on every blueprint-capable application center. That means less integration and support work for you as a manufacturer, and structured output for your customer instead of a hand-written parser per device.
It is worth comparing this to a self-describing approach such as OMS. There, the descriptor travels inside the payload, so the data can be interpreted with no external information at all. The price is a heavier payload, which costs airtime and battery on every single transmission. A blueprint keeps the payload lean by moving that descriptor out of the telegram and into the backend, where it only has to exist once.
To be honest about the tradeoff: the blueprint still has to be available to the decoder somewhere. You have not removed the descriptor, you have moved it off the air and stored it once, which for a battery-powered LPWAN device is usually the right call.
4. Watch out: not every application center supports blueprints
Blueprint decoding is optional in the mioty® specification, and support varies from one application center to the next. Some backends decode blueprints for you, others hand you only the raw hexadecimal payload. Before you commit to a backend, verify that it does what you expect. As a rough current picture, the Fraunhofer IIS, Pallax and AVA backends support blueprint decoding, while Loriot does not. Always check the latest capability with the provider, since this changes.
If your application center does not support blueprints, you are not stuck. You can still use the blueprint on your own side, for example by decoding the payload on your IoT platform according to the description. The concept and the file stay the same, only the place where the decoding happens moves downstream.
5. How to write a mioty blueprint
The easiest way to understand a blueprint is to build one up, starting from the smallest thing that works and adding one idea at a time.
5.1 The smallest valid blueprint
Two keys are mandatory at the root: version and typeEui. Everything else describes the data. The uplink array holds the message formats a device sends, each format has an id and a payload array, and each entry in the payload array is one component with a name, a size in bits, and a type.
Fed a payload of 0x04D3, this blueprint produces the number 1235. Correct, but not yet meaningful, which is exactly what the next step fixes.
5.2 Make it human-readable
A component can carry a function, a unit and a label. The function transforms the raw value, where the dollar sign stands for this component’s value. Here the device sends temperature in 0.1 °C steps with a -100 °C offset, a common trick that lets an unsigned integer still express sub-zero readings.
Now the numbers mean something. A raw value of 1235 becomes 23.5 °C, and a raw value of 800 becomes -20.0 °C. The optional meta block is the first nice-to-have, a place for a name, a vendor, and anything else you want to attach to the device type.
If you only needed the concept, you have it now: a blueprint maps raw bytes to named, typed, unit-carrying values. The rest of this section goes one level deeper for developers who want the full toolbox.
5.3 Add a second value
Components are read in the order they appear, and their sizes must add up to the total payload size. Adding a humidity byte after the temperature is as simple as appending a second component.
5.4 Handling an invalid reading (advanced)
Real sensors sometimes report that they have no valid value. A common firmware pattern is a sentinel, here the value 255 meaning sensor error. You do not want to surface a fake 255 percent humidity, so this is where three features come together: hidden keeps the raw byte out of the output, virtual values derive a result instead of reading bytes directly, and a condition decides whether a value is present at all.
When the reading is valid, humidity appears with its percentage. When the sensor reports 255, the humidity field is simply not emitted, and humidity_valid tells the consumer why. That is cleaner than passing a magic number downstream and hoping every platform knows to ignore it.
5.5 Talking back to the device: downlink (advanced)
So far the device only reports. A blueprint can describe both directions, so if you want to control something, add a downlink block. Uplink is device to backend, downlink is backend to device, and the same component grammar applies. Here a single byte switches an LED, read as a boolean where any non-zero value is true.
For downlink the payload array defines how the bytes are assembled to send, rather than how received bytes are interpreted. Downlink only makes sense for bidirectional endpoints, so it is optional and only present when the device can actually receive.
Putting the pieces together, here is the complete blueprint for this temperature and humidity sensor with LED control.
5.6 Datatypes and sizes
A component’s type tells the decoder how to interpret its bits. The available types are uint and int for unsigned and signed integers, float for IEEE 754 floating point, bool for a boolean, string for UTF-8 text, and binary for raw bytes passed through untouched. Size is always given in bits, not bytes, which is the single most common mistake when writing a first blueprint. The declared sizes of all components must add up to the size of the payload you are interpreting.
5.7 Functions
Functions let you convert a raw value into something useful, using the operators and math functions of the ANSI C standard. Inside a function, the dollar sign is this component’s value, dollar-name refers to another component, and dollar-calibration-name refers to a calibration value. A unit conversion from Kelvin to degrees Celsius, for example, is just:
5.8 Calibration
Some devices need per-device calibration data for a correct reading. You define default calibration values in a top-level calibration object, and reference them from a component’s function. If device-specific calibration data is provided later, it replaces the defaults for that device, while any value you do not override stays at the blueprint default.
5.9 Endianness
By default a payload is read big endian, which is why the examples above set littleEndian to false or leave it out. If your device sends its multi-byte values least significant byte first, set littleEndian to true on that format. Mixed endianness within one payload is out of scope, so keep a single byte order per format.
5.10 Specification
Further reference can be found in the mioty Application Layer Specification, which is available on the mioty Alliance website for download.
6. Multiple payloads per device: the MAC Payload Format
A device does not have to send the same payload every time. The MAC Payload Format, or MPF, is an optional one-byte field on the MAC layer that tells the backend which format a given telegram uses. The value range is split in two. The reserved range, 0x00 to 0xBF, is used for standardized formats that are identical across devices. The custom range, 0xC0 to 0xFF, is yours to use freely for device-specific formats without any standardization.
| Format ID | Name | Description |
|---|---|---|
| 0x00 | Default | Device-specific default payload, implicitly assigned if no other format is specified |
| 0x80 | M-Bus | M-Bus format as the next layer, starting with the CI field |
| 0x81 | M-Bus (APL only) | M-Bus application layer data, starting with a data information block (DIB) |
| 0x82 | IO-Link | IO-Link application layer format as the next layer |
| 0x83 | MBAL | M-Bus format using the adaptation layer |
| 0x01–0x7F, 0x84–0xBF | Reserved | Reserved, with 0xA0–0xBF reserved for mioty® technology |
| 0xC0 to 0xFF | Custom | Device-specific payload format |
The reserved IDs are how mioty® hands off to other standards. An ID like 0x82 says the next layer is IO-Link, which is then interpreted by that protocol rather than by a blueprint. The custom range works differently. Think of it as a routing handle, similar to a port number for data types: you tag each telegram with a format ID, and the backend routes it to the matching blueprint. Format ID 0x00 is the implicit default, so your everyday payload travels with no overhead at all, and you only spend a format ID on the less frequent or special transmissions.
7. What a blueprint can and cannot do
A blueprint handles a lot: fixed and conditional fields, unit conversion, calibration, derived virtual values, several formats per device through the MAC Payload Format, and a variable-length tail through a size of -1. It is worth being just as clear about the edges.
7.1 There is no shared vocabulary
A blueprint carries no semantic dictionary. You can name a value temperature, and another vendor can name the same thing Temperature, and nothing enforces a common vocabulary the way Bluetooth GATT characteristics do. There is a useful workaround, though. Take the blueprints you receive from your manufacturers and lightly adapt them, the names, the units, the structure, to your own internal convention. Your application center then emits the same field names no matter which vendor’s device produced the data, because you are running your own custom blueprints for your own solution.
7.2 Repeating and toggleable payloads
There is no repeat construct. A payload whose number of values changes at runtime, for example a device you can configure to send no historical values, or four, or eight, cannot be expressed cleanly in a single blueprint. For a small, bounded set you can enumerate each field and gate it with a condition. Beyond that, a device that toggles whole payload sections on and off through its settings is usually cleaner as several typeEUIs, one per configuration or firmware version, or as separate format IDs. The general rule is to handle toggleable payloads with care rather than forcing one blueprint to cover every combination.
Conclusion
A blueprint lets you describe a payload once and have it decoded anywhere that supports blueprints, while your device keeps sending lean, battery-friendly telegrams over the air. You keep full freedom in your payload design, and your customers get structured data instead of a parser to maintain.
If you build mioty® devices, the single most useful thing you can do for your users is to publish a blueprint alongside the device. If you integrate them, adapt those blueprints to your own naming convention and let your application center do the decoding.
For hardware and backend options to try this on, see the demo kit tutorial. For a full sensor-to-dashboard walkthrough, see the end-to-end demo tutorial. The complete field reference lives in the mioty® Application Layer Specification.
Frequently asked questions
Is a blueprint sent over the air?
No. The blueprint is provisioned out of band and linked to the device, much like its EUI or its keys. Only the raw payload travels over the air.
Do all application centers support blueprints?
No, it is optional in the specification. Verify blueprint support with your backend provider before you rely on it, and if it is missing you can still decode on your own platform.
Can one device use several payload formats?
Yes. Use the MAC Payload Format ID to switch between formats, or assign a separate typeEUI per payload version.
Is it safe to paste a blueprint into my IoT platform?
Yes. A blueprint is declarative JSON, not executable code, so it does not carry the security risk of a pasted decoder script.
My payload length changes at runtime, can a blueprint handle it?
Partly. Use a size of -1 for a variable tail, or condition-gated fields for a small bounded set. For an open-ended, configurable number of values, split it into multiple typeEUIs instead.

