All developer tools

BLE UUID Generator & Converter

Generate a 128-bit base UUID with its service and characteristic UUIDs, convert 16-, 32-, and 128-bit forms and firmware byte arrays, and copy the format each stack expects.

Generate a service and its characteristics

One random base, with sequential values in the 16-bit field at characters 5 to 8.

Random RFC 9562 version 4 UUID from crypto.getRandomValues, created in your browser. Paste your own 128-bit base to use it instead.

Convert a UUID

Byte order of pasted bytes

Applies to byte lists and to 32 hex digits without dashes. UUID strings with dashes and 16- or 32-bit values are read as written.

Address your characteristics from SimpleBLE

Read, write, and subscribe to characteristics by service and characteristic UUID with SimpleBLE.

Open the read, write, and notify recipe
Fundamentals

Why custom services use 128-bit UUIDs

Every service, characteristic, and descriptor in a GATT database has a UUID that identifies its type. The short 16-bit form is reserved for values the Bluetooth SIG assigns: adopted services such as Heart Rate 0x180D, characteristics, descriptors, and member UUIDs allocated to companies. A product team does not pick a 16-bit value for its own attributes.

Custom services and characteristics without a SIG allocation use full 128-bit UUIDs, and no registry is involved. The Core Specification describes UUIDs as values that can be created independently, with a negligible probability that two of them match. A version 4 UUID from a cryptographic random source carries 122 random bits, and that is the form this tool generates.

The cost is size. A 128-bit UUID takes 16 bytes in ATT PDUs and advertising data, where a 16-bit UUID takes 2. A legacy advertising PDU holds 31 bytes of advertising data, and a list with one 128-bit service UUID uses 18 of them, including its length and type bytes.

Reserved range

Why custom UUIDs avoid the Bluetooth Base UUID

The Core Specification (Vol 3, Part B, Section 2.5.1) pre-allocates a range of UUIDs for often-used, registered purposes. The first value in the range is the Bluetooth Base UUID, 00000000-0000-1000-8000-00805F9B34FB, and every 16- or 32-bit UUID is an alias for a 128-bit value in it:

128_bit_value = 16_bit_value × 2^96 + Bluetooth_Base_UUID

Heart Rate 0x180D is therefore 0000180D-0000-1000-8000-00805F9B34FB, and any value of the form xxxxxxxx-0000-1000-8000-00805F9B34FB is the alias of a 32-bit value. A custom attribute placed in this range can collide with an existing or future SIG assignment, and tools that resolve assigned numbers treat it as a SIG value. The converter flags every UUID in the range.

A random version 4 UUID cannot land in the range. The Base UUID carries version 1 in the version field, the 1 in -1000-, and a version 4 UUID always carries 4 in that position.

Byte order

Canonical strings and on-air byte order

The canonical string writes the 16 bytes of a UUID most significant first, in groups of 8, 4, 4, 4, and 12 hex digits. ATT and GATT send multi-octet fields least significant octet first (Core Specification Vol 3, Part F, Section 3.3.1 and Part G, Section 2.4), so a UUID travels with its 16 bytes reversed. Advertising data uses the same order. For the Nordic UART Service:

Canonical string   6E400001-B5A3-F393-E0A9-E50E24DCCA9E
Canonical bytes    6E 40 00 01 B5 A3 F3 93 E0 A9 E5 0E 24 DC CA 9E
On-air bytes       9E CA DC 24 0E E5 A9 E0 93 F3 A3 B5 01 00 40 6E

The whole 16-byte value is reversed, not each group. A 16-bit UUID follows the same rule: Heart Rate 0x180D appears on air as 0D 18.

Firmware SDKs store 128-bit UUIDs as little-endian byte arrays, so an array copied from firmware or a packet capture reads backwards against the canonical string. Reading it in the wrong order still produces a well-formed UUID, and discovery then fails to find the attribute. In the converter, select on-air order for arrays from firmware and captures, and canonical order for bytes written in string order.

UUID families

Deriving a UUID family from one base

Vendor profiles commonly share one base across a service and its characteristics, and vary a 16-bit field in canonical bytes 2 and 3, characters 5 to 8 of the string. The Nordic UART Service uses this layout, and Nordic documents the service UUID with a 16-bit offset of 0x0001:

Service  6E400001-B5A3-F393-E0A9-E50E24DCCA9E
RX       6E400002-B5A3-F393-E0A9-E50E24DCCA9E
TX       6E400003-B5A3-F393-E0A9-E50E24DCCA9E

The nRF5 SoftDevice API is built on the same layout. sd_ble_uuid_vs_add registers a base, and ble_uuid_t supplies the 16-bit value for bytes 12 and 13 of the little-endian array, which are bytes 2 and 3 of the canonical string. One registered base addresses 65,536 UUIDs.

A family keeps related attributes recognizable in logs and code. Each derived UUID is still a complete 128-bit identifier, and clients compare all 128 bits. Derived values keep the version and variant bits of the base, which sit in bytes 6 and 8, and distinct 16-bit values always produce distinct UUIDs. Record the assigned values in source control and do not reuse a retired value for a different attribute.

Stack formats

The format each stack expects

  • Zephyr and nRF Connect SDK. BT_UUID_128_ENCODE takes the five groups of the canonical string as numbers and emits the bytes little-endian. Wrap it in BT_UUID_DECLARE_128 or BT_UUID_INIT_128. SIG values use BT_UUID_DECLARE_16.
  • nRF5 SDK. ble_uuid128_t holds the base as little-endian bytes. sd_ble_uuid_vs_add registers it, ignoring bytes 12 and 13, and returns a type index. Each attribute is then a ble_uuid_t with its 16-bit value and that type. SIG values use BLE_UUID_TYPE_BLE.
  • ESP-IDF with Bluedroid. esp_bt_uuid_t with len set to ESP_UUID_LEN_128 and uuid.uuid128 holding little-endian bytes. SIG values use ESP_UUID_LEN_16 and uuid.uuid16.
  • ESP-IDF with NimBLE. BLE_UUID128_INIT takes the 16 bytes in little-endian order. SIG values use BLE_UUID16_INIT.
  • SimpleBLE. Services and characteristics are addressed by full 128-bit UUID strings, written in lowercase as in the SimpleBLE documentation: 0000180f-0000-1000-8000-00805f9b34fb for the Battery service. A 16-bit value such as 180f is passed in its 128-bit form.
  • Captures and HCI logs. Raw bytes appear in on-air order. Compare them against the on-air output, not the canonical string.

The converter emits each of these forms. To identify an assigned or known vendor UUID, open it in the GATT UUID lookup.