---
title: "Device matching and hardware fingerprint"
description: "Bind signed access to an installation and its product-scoped hardware hashes."
slug: "/docs/v1/licensing/hardware-fingerprint"
section: "Licensing models"
order: 901
audience: "all"
level: "intermediate"
last_updated: "2026-10-25"
version: "v1"
related: ["/docs/v1/licensing/platform-plans", "/docs/v1/sdks/compatibility"]
draft: false
---
Bind signed access to an installation and its product-scoped hardware hashes.

## Plan requirement
Basic installation and hardware binding remains required and available on all platform plans. **Pro and Business** unlock configurable strict/flexible matching under Products → Validation & offline policy. A lower-plan settings write returns `PLAN_UPGRADE_REQUIRED` (403). This uses the developer’s effective KDPika subscription, not the buyer’s software plan.

## What the app sends
Fingerprint-capable Python, Node.js, Rust, PHP and C# sources collect hardware identifiers locally, normalize and salt hashes for the product, and send hashes only. No raw serial numbers should enter a request, database, URL or log. A stable random installation ID is separate from the fingerprint.

Activation uses `X-App-ID`, `X-Environment`, `X-Installation-ID` and JSON containing `license_key`, `device_id`, device metadata and `fingerprint`. Validation uses the activation bearer token, the same `X-Installation-ID` and a fresh `fingerprint`. A body example is a contract template, not a usable hardware value:

```json
{
  "fingerprint": {
    "version": 1,
    "hardware_id": "<64 lowercase hex characters>",
    "components": {
      "baseboard": "<product-salted SHA-256 hex>",
      "cpu": "<product-salted SHA-256 hex>"
    },
    "is_virtual": false
  }
}
```

`hardware_id` is SHA-256 of the sorted component pairs joined with a newline: `baseboard=<hash>` then `cpu=<hash>`, without a trailing newline. Follow the SDK’s collection/normalization logic; do not hash an arbitrary display name. The `is_virtual` value is a hint and never a sole rejection reason.

## Matching policy
- **Strict:** every saved/available component must match. Missing previously saved components do not weaken the binding.
- **Flexible:** the configured number of components must match (1–5, bounded by the saved component count). Previously saved motherboard and CPU anchors must still be present and match. Default minimum: 2.
- New matching components can extend the baseline; removing a saved critical component cannot bypass it.

The server signs `device.fingerprint` and `device.installation_hash`. Verify Ed25519 first, then compare the signed installation hash and fingerprint to this installation before using a cached or online result. Never strip fields from the signed payload or trust an unsigned fingerprint object.

## Recovery and limits
`INVALID_FINGERPRINT` means the required input is absent/malformed. `FINGERPRINT_MISMATCH` means this machine does not match the saved binding. A local SDK can return `HARDWARE_UNAVAILABLE` if usable identifiers cannot be collected. Keep protected features locked and offer publisher-assisted deactivation/reactivation; do not fabricate identifiers.

This is software-based device matching, not hardware attestation or unbreakable anti-piracy. An administrator controlling a client can patch code or spoof inputs. Native browser JavaScript fingerprinting has no fallback and is unsupported. Use Node.js/Electron main or a trusted server process, with actual target-machine tests on Windows, macOS and Linux.

[Check SDK release compatibility](/docs/v1/sdks/compatibility) before installing: earlier registry/ZIP releases predate the required contract.
