Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nordicsemi/bluetooth-numbers-database/llms.txt

Use this file to discover all available pages before exploring further.

The bluetooth-numbers-database package exports all data via module.exports in its index.js entry point. Every data export is a plain JavaScript array loaded from the corresponding JSON file in the v1/ directory. The array structures are validated against JSON Schemas that are also exported via the schemas object.

Import Patterns

// Import the entire module
const db = require('bluetooth-numbers-database');

// Or destructure individual exports
const { companies, services, characteristics, descriptors, appearances } = require('bluetooth-numbers-database');

companies

companies
Array<{ code: number, name: string }>
Array of Bluetooth SIG-assigned Company Identifiers. Contains approximately 3,998 entries covering organisations that have registered a company identifier with the Bluetooth Special Interest Group. The code field is a decimal integer; the name field is the official registered company name.
const { companies } = require('bluetooth-numbers-database');

// Find a company by its numeric code
const nordic = companies.find(c => c.code === 89);
console.log(nordic.name); // 'Nordic Semiconductor ASA'

// Find companies whose name includes a partial string (case-insensitive)
const appleEntries = companies.filter(c =>
  c.name.toLowerCase().includes('apple')
);
console.log(appleEntries);
// [{ code: 76, name: 'Apple, Inc.' }]

services

services
Array<{ uuid: string, name: string, identifier: string, source: string }>
Array of GATT Service UUID definitions. Contains 126 entries sourced from the Bluetooth GATT Specification Supplement (GSS) as well as proprietary entries. The uuid field is either a 4-character hexadecimal string (16-bit SIG-assigned) or a full 36-character UUID string (128-bit proprietary). The identifier uses reverse-dot notation (e.g., org.bluetooth.service.heart_rate). The source field is "gss" for SIG-defined services or a vendor identifier for proprietary ones.
const { services } = require('bluetooth-numbers-database');

// Find a service by its UUID
const heartRate = services.find(s => s.uuid === '180D');
console.log(heartRate);
// {
//   name: 'Heart Rate',
//   identifier: 'org.bluetooth.service.heart_rate',
//   uuid: '180D',
//   source: 'gss'
// }

// Find all SIG-defined services
const sigServices = services.filter(s => s.source === 'gss');
console.log(`${sigServices.length} SIG-defined services`);

characteristics

characteristics
Array<{ uuid: string, name: string, identifier: string, source: string }>
Array of GATT Characteristic UUID definitions. Contains 682 entries. The field structure is identical to services: uuid (16-bit hex or full 128-bit UUID), name, identifier (reverse-dot notation such as org.bluetooth.characteristic.battery_level), and source.
const { characteristics } = require('bluetooth-numbers-database');

// Find the Battery Level characteristic
const batteryLevel = characteristics.find(c => c.uuid === '2A19');
console.log(batteryLevel);
// {
//   name: 'Battery Level',
//   identifier: 'org.bluetooth.characteristic.battery_level',
//   uuid: '2A19',
//   source: 'gss'
// }

// Find all characteristics from a proprietary source
const proprietary = characteristics.filter(c => c.source !== 'gss');
console.log(`${proprietary.length} proprietary characteristics`);

descriptors

descriptors
Array<{ uuid: string, name: string, identifier: string, source: string }>
Array of GATT Descriptor UUID definitions. Contains 18 entries covering the standard GATT descriptors defined in the Bluetooth Core Specification, including Client Characteristic Configuration (CCCD), Server Characteristic Configuration, Characteristic Presentation Format, and more. Field structure is the same as services and characteristics.
const { descriptors } = require('bluetooth-numbers-database');

// Find the Client Characteristic Configuration Descriptor (CCCD)
const cccd = descriptors.find(d => d.uuid === '2902');
console.log(cccd);
// {
//   name: 'Client Characteristic Configuration',
//   identifier: 'org.bluetooth.descriptor.gatt.client_characteristic_configuration',
//   uuid: '2902',
//   source: 'gss'
// }

// Log all descriptor names
descriptors.forEach(d => console.log(`${d.uuid}: ${d.name}`));

appearances

appearances
Array<{ category: number, name: string, subcategory?: Array<{ value: number, name: string }> }>
Array of GAP Appearance category definitions from the Bluetooth Core Specification Supplement. Contains 52 top-level categories. The category field is a decimal integer corresponding to bits 15–6 of the 2-byte Appearance value. The optional subcategory array lists sub-categories, each with a value (bits 5–0) and a name.
const { appearances } = require('bluetooth-numbers-database');

// Find a category by its number
const computer = appearances.find(a => a.category === 2);
console.log(computer.name); // 'Computer'
console.log(computer.subcategory);
// [
//   { value: 1, name: 'Desktop Workstation' },
//   { value: 2, name: 'Server-class Computer' },
//   { value: 3, name: 'Laptop' },
//   ...
// ]

// Decode a raw 2-byte appearance value
function decodeAppearance(rawValue) {
  const category = (rawValue >> 6) & 0x3FF; // bits 15-6
  const subCategory = rawValue & 0x3F;       // bits 5-0

  const entry = appearances.find(a => a.category === category);
  if (!entry) return `Unknown (category ${category})`;

  const sub = entry.subcategory?.find(s => s.value === subCategory);
  return sub ? `${entry.name} - ${sub.name}` : entry.name;
}

console.log(decodeAppearance(0x0180)); // 'Computer - Laptop'

schemas

schemas
object
An object containing the JSON Schema definitions used to validate each data array. Keys are companies, services, characteristics, descriptors, and appearances. services, characteristics, and descriptors all share the same attributeSchema object. Useful for runtime validation of custom entries before contributing them to the database or for validating data you’ve fetched independently.
const Ajv = require('ajv');
const { schemas } = require('bluetooth-numbers-database');

const ajv = new Ajv();

// Validate a custom characteristic entry against the attribute schema
const customCharacteristic = {
  uuid: 'EF680201-9B35-4933-9B10-52FFA9740042',
  name: 'My Custom Characteristic',
  identifier: 'com.example.characteristic.custom',
  source: 'custom'
};

const validate = ajv.compile(schemas.characteristics);
const valid = validate([customCharacteristic]);

if (!valid) {
  console.error('Validation errors:', validate.errors);
} else {
  console.log('Entry is valid');
}

version

version
string
The package version string derived from package.json. For example, '1.0.4'. This reflects the npm package version, which also determines the v1/ data directory used internally (the major version number maps to the data directory name).
const db = require('bluetooth-numbers-database');

console.log(db.version); // '1.0.4'

// Or with destructuring
const { version } = require('bluetooth-numbers-database');
console.log(version); // '1.0.4'

Common Patterns

1. Resolve a Company Name from BLE Manufacturer Data

Bluetooth Low Energy advertisements can include Manufacturer Specific Data (AD type 0xFF). The first two bytes of the payload are the little-endian company identifier.
const { companies } = require('bluetooth-numbers-database');

function resolveManufacturer(manufacturerDataBuffer) {
  // First two bytes of manufacturer data are the company code (little-endian)
  const code = manufacturerDataBuffer[0] | (manufacturerDataBuffer[1] << 8);
  const company = companies.find(c => c.code === code);
  return company ? company.name : `Unknown (code ${code})`;
}

// Example: Buffer containing [0x59, 0x00, ...] → code 89 → Nordic Semiconductor ASA
const exampleBuffer = Buffer.from([0x59, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]);
console.log(resolveManufacturer(exampleBuffer)); // 'Nordic Semiconductor ASA'

2. Resolve a Service UUID from a GATT Discovery Result

When a GATT client discovers services on a remote device, it receives UUID strings. Use the services array to turn those into human-readable names.
const { services } = require('bluetooth-numbers-database');

function resolveServiceName(uuid) {
  // Normalise to uppercase for comparison
  const normalised = uuid.toUpperCase().replace(/^0x/, '');
  const service = services.find(s => s.uuid.toUpperCase() === normalised);
  return service ? service.name : `Unknown service (${uuid})`;
}

console.log(resolveServiceName('180D')); // 'Heart Rate'
console.log(resolveServiceName('180F')); // 'Battery Service'
console.log(resolveServiceName('1234')); // 'Unknown service (1234)'

3. Check if a UUID Is in the Database

Before adding a UUID to the database via pull request, check whether it already exists across services, characteristics, and descriptors.
const { services, characteristics, descriptors } = require('bluetooth-numbers-database');

function uuidExists(uuid) {
  const upper = uuid.toUpperCase();
  return (
    services.some(e => e.uuid.toUpperCase() === upper) ||
    characteristics.some(e => e.uuid.toUpperCase() === upper) ||
    descriptors.some(e => e.uuid.toUpperCase() === upper)
  );
}

console.log(uuidExists('180D')); // true  (Heart Rate service)
console.log(uuidExists('2A19')); // true  (Battery Level characteristic)
console.log(uuidExists('ABCD')); // false

Build docs developers (and LLMs) love