Orange textured background

API Reference

getFingerprint

The full-pipeline fingerprint call. Collects all configured signals in parallel, runs three independent risk tracks, and returns two hashes in a single result.

Reviewed

Signature
getFingerprint(options?: FingerprintOptions): Promise<FingerprintResult>

Returns: A FingerprintResult containing a per-browser fingerprint, a cross-browser hardware fingerprint, per-signal detail, and consistency, incognito, and automation scoring.

The pipeline

getFingerprint runs four sequential stages. First, all configured signals are launched in parallel with a global timeout. Every signal that completes before the deadline writes its result; any that do not are recorded as absent.

Second, the hardware hash is derived from the subset of hardware-bound signals. Third, consistency checks, incognito checks, and automation checks run in parallel; none depend on each other. Finally, everything is combined into the composite fingerprint hash and packaged into the FingerprintResult.

On any uncaught error, the function returns an empty FingerprintResult rather than throwing.

Two hashes from one call

The result carries two fingerprints. fingerprint is computed from the full signal set and differs between Chrome and Safari on the same machine because engine-bound signals like audio DSP and canvas rasterisation diverge across browser engines. hardwareFingerprint is computed only from the hardware-bound subset and is stable across browsers and incognito on the same physical device. The exact composition of the hardware-bound subset is part of the internal recipe and not part of the public contract.

Both hashes are 16-char hex strings. You only need to call getFingerprint once to get both.

FingerprintResult fields

FieldTypeDescription
fingerprintstring16-char hex. Full hash fused from all collected signals. Differs per browser engine.
hardwareFingerprintstring16-char hex. Hardware-only hash. Stable across Chrome, Safari, Firefox, Brave on the same device.
versionstringLibrary version string.
collectionTimeMsnumberWall-clock time for the entire collection pass.
signalsRecord<string, SignalResult>Per-signal result map: hash, confidence, binding, optional sentinel, and (in debug mode) raw value.
consistencyConsistencyResultAnti-detect browser detection. spoofLikelihood: 'low' | 'medium' | 'high'.
incognitoIncognitoResultPrivate-mode detection. incognitoLikelihood: 'low' | 'medium' | 'high'.
automationAutomationResultAutomation-framework detection (Puppeteer, Playwright, Selenium). automationLikelihood: 'low' | 'medium' | 'high'.
crossBrowserCrossBrowserScoreCross-browser confidence score with stableSignals and unstableSignals lists.
errorsFingerprintError[] | undefinedOptional. Present only when at least one collector or pipeline failure occurred during this run. A clean run omits the field entirely. Each entry has a 'type' ('collector_threw' | 'collector_timeout' | 'fatal'), optional 'component' name, and a message capped at 200 characters. Errors are diagnostic only and never feed into the hash.
_pipelinePipelineTiming | undefinedOptional. Present only when options.performance === true. Breakdown of pipeline stage durations: collect, crossBrowser, checks, fuse, total. All values in milliseconds, rounded to one decimal place.

Per-signal sentinel codes

Every signal result includes an optional `sentinel` field that provides finer-grained diagnostics without affecting which value gets hashed. Four values are possible: `'unsupported'` means the underlying browser API is absent on this browser; `'threw'` means the collector raised an exception; `'timeout'` means the collector was killed by the global or per-component timeout; `'randomized'` means the collector ran and produced a hash but per-call stability checks (mode-merge noise detection across repeated runs) detected noise.

When sentinel is 'unsupported', 'threw', or 'timeout', the hash is set to a stable absent-sentinel hash and confidence is 'absent'. When sentinel is 'randomized', the hash carries real data and confidence is 'degraded'. Sentinels are purely diagnostic and never change how the composite fingerprint is computed.

The `errors[]` array on the result mirrors collector-level sentinel information at the top level: 'collector_threw' corresponds to sentinel 'threw', 'collector_timeout' to sentinel 'timeout'. The per-signal `errorMessage` field provides the truncated exception or timeout message.

typescript
import { getFingerprint } from 'doorman-benny'; const result = await getFingerprint(); // Two hashes from one call.
console.log(result.fingerprint); // per-browser instance
console.log(result.hardwareFingerprint); // cross-browser device hash // Three independent risk tracks.
if (result.consistency.spoofLikelihood === 'high') { flagForReview('Anti-detect browser detected');
}
if (result.automation.automationLikelihood === 'high') { blockRequest('Automation framework detected');
}
// Incognito is informational; private browsing is not evidence of fraud.
console.log(result.incognito.incognitoLikelihood); // Per-signal detail including sentinel codes.
for (const [name, signal] of Object.entries(result.signals)) { console.log(name, signal.confidence, signal.binding, signal.sentinel);
} // Optional pipeline timing (never use in production).
const timed = await getFingerprint({ performance: true });
console.log(timed._pipeline?.total); // total wall-clock ms
console.log(timed._pipeline?.collect); // signal collection ms

Treat 'medium' as suggestive and 'high' as conclusive for spoofLikelihood and automationLikelihood.

Last reviewed 2026-06-04