Orange textured background

API Reference

createCollector

The background-collection entry point. Start early, await late. Collection runs in parallel with everything else on the page.

Reviewed

Signature
createCollector(options?: FingerprintOptions): CollectorHandle

Returns: A CollectorHandle with two methods, start() to begin collection and getResult() to await the FingerprintResult.

The background-collection pattern

getFingerprint blocks the caller for up to 1 to 1.6 seconds. For interactive pages that pattern adds measurable latency. The solution is to decouple the start of collection from the moment you need the result.

createCollector returns a CollectorHandle immediately. No collection begins yet. Call start() as early as possible in the page lifecycle (top of a script, inside a DOMContentLoaded handler, or in a framework's app initialiser). Collection then runs in the background. By the time the user has filled a form or clicked a button, getResult() typically resolves instantly because collection finished during idle time.

CollectorHandle methods

start() is idempotent. Calling it multiple times is safe; only the first call begins collection. It never throws.

getResult() returns the stored FingerprintResult promise. If start() was never called, getResult() auto-starts collection and waits for it. getResult() also never throws; on any error it resolves to an empty FingerprintResult.

typescript
import { createCollector } from 'doorman-benny'; // Place at the very top of your page-load handler.
// Collection begins immediately and runs in the background.
const collector = createCollector();
collector.start(); //... modules load, network requests fire, user sees the first screen... // By now collection is likely done. getResult() resolves with little or no wait.
async function onFormSubmit() { const result = await collector.getResult(); if (result.automation.automationLikelihood === 'high') { throw new Error('Automated submission blocked'); } await submitToServer({ deviceId: result.hardwareFingerprint, fingerprint: result.fingerprint, });
}

The collector passes the same FingerprintOptions to getFingerprint internally. All options (tiers, timeout, exclude, debug) apply.

Two-stage collection

Some signal collectors split their work into two stages: an early, non-blocking stage that kicks off slow asynchronous work, and a later stage that awaits it and returns the SignalResult.

This is an internal implementation detail; createCollector callers never interact with the two stages directly. The two-stage pattern improves wall-clock collection time by overlapping slow async calls across collectors. The FingerprintResult shape returned by getResult() is identical regardless of which collectors use the two-stage form.

Comparison with getFingerprint

createCollector is a scheduling wrapper around getFingerprint. The FingerprintResult it produces is identical in shape. The only difference is when collection starts: immediately with getFingerprint, or at the explicit start() call with createCollector. Use createCollector whenever the page lifecycle gives you any time before you need the result.

Last reviewed 2026-06-04