Signal Result Wrapper

Every browser collector returns a SignalResult<T>. When a collector cannot run because the API is unavailable, blocked, or restricted by the browser, the SDK returns null for that collector rather than throwing.

typescript
interface SignalResult<T> { value: T; duration: number; // milliseconds}

The /v1/identify request body contains these browser collector results. The compact identify() response does not echo them back; fetch the full event server-side with GET /v1/events/:requestId when you need raw signal data.

Collector Map

The SDK currently collects 41 browser signals:

  • canvas
  • webgl
  • webgpu
  • audio
  • domRect
  • svg
  • fonts
  • webrtc
  • navigator
  • media
  • screen
  • speech
  • intl
  • timezone
  • storage
  • codec
  • platformFeatures
  • uaClientHints
  • sensorCapabilities
  • wasmTiming
  • math
  • cssStyle
  • cssFeatures
  • error
  • windowFeatures
  • htmlElement
  • capabilityVector
  • geometryVector
  • runtimeVector
  • integrity
  • wallets
  • headless
  • workerScope
  • resistance
  • status
  • behavioralRisk
  • incognito
  • devTools
  • virtualization
  • rooted
  • frameDepth

Selected Type Shapes

typescript
interface CanvasSignal { hash: string; isFarbled: boolean;}
typescript
interface WebGLSignal { renderer: string; vendor: string; extensions: string[]; params: Record<string, number>; gpuTimingMs: number | null; isSoftwareRenderer: boolean;}
typescript
interface WalletSignal { detected: string[]; count: number; evmProviders: string[]; solanaProviders: string[]; multipleWallets: boolean; versions: Record<string, string>;}
typescript
interface TimezoneSignal { reported: string; computed: string | null; offsetHistorical: number; isSpoofed: boolean; hash: string;}
typescript
interface CssFeatureSignal { features: Record<string, boolean>; supportedCount: number; hash: string;}
typescript
interface FrameDepthSignal { isFramed: boolean; depth: number; topAccessible: boolean; crossOriginBoundary: boolean; hash: string;}
typescript
interface BehavioralRiskSignal { elapsedMs: number; totalEventCount: number; pointerMoveCount: number; pointerDistancePx: number; pointerDirectionChanges: number; pointerStraightness: number | null; clickCount: number; scrollEventCount: number; scrollBurstCount: number; keyEventCount: number; inputEventCount: number; focusTransitions: number; blurTransitions: number; visibilityTransitions: number; meanPointerIntervalMs: number | null; meanKeyIntervalMs: number | null; classification: "insufficient_data" | "low_interaction" | "human_like" | "synthetic_like"; riskScore: number; reasons: string[]; hash: string;}
typescript
interface HeadlessSignal { isHeadless: boolean; markers: string[];}

Canonical Schema

The canonical source of truth for browser signal types is:

That file defines:

  • every browser collector interface
  • the ClientSignals map used in the identify request payload
  • the compact IdentifyResponse returned by identify()

If you are building custom server-side scoring, use this page to orient yourself and sdk/src/types.ts for the exact current schema.