Developer pages

Custom events & properties

tracker.customEvent — API, batching, reserved names, properties, and verification.

When to use

Track product moments that URLs and autocapture cannot express: signups, plan changes, checkout steps, feature flags, and other business semantics.

API

import { HumanBehaviorTracker } from "humanbehavior-js";

const tracker = HumanBehaviorTracker.init(apiKey);

await tracker.customEvent("signed_up", {
  plan: "pro",
  source: "pricing_page",
});
ArgumentTypeRules
eventNamestringRequired; empty / invalid names are skipped with a warning
propertiesRecord<string, any>Optional; JSON-serializable values preferred

Returns a Promise<void>. Safe to await or fire-and-forget.

Batching (browser SDK)

Outbound custom events are batched before leaving the browser:

KnobValueBehavior
Flush timer100 msDebounced flush after the first queued event
Max batch50 eventsHard flush when the batch fills
EndpointPOST /api/ingestion/customEvent/batchPrimary path
FallbackSingle POST /api/ingestion/customEvent or embed into the replay event streamUsed on certain failures

Order of insertion is preserved. Do not depend on a separate “force flush” API for normal product events — navigation/unload paths flush pending work.

Minimum duration gate

With the default minimumDurationMilliseconds: 5000, custom events fired in the first five seconds of a session are held in a pending queue and flushed once the gate opens. Set minimumDurationMilliseconds: 0 in init if you need immediate delivery (for example, very short landing-page sessions).

Reserved / automatic names

Prefer your own snake_case names for product events. The SDK already emits namespaced analytics events such as:

$pageview, $click, $form_submitted, $rageclick, $deadclick, $web_vitals

Avoid colliding with those $… names unless you intentionally extend the same pipeline.

Property design

DoDon’t
Stable enums (plan: "pro")Free-text blobs that change every session
Small primitives (string / number / boolean)Huge HTML / base64 / screenshots
Separate identity via identifyUserPut passwords / tokens in properties
Keep names stable for funnelsRename casually after funnels ship

Automatic device/URL properties are attached by the SDK separately when enableAutomaticProperties is on — you do not need to re-send browser UA on every event.

Non-browser / custom clients

For high-volume non-browser producers, call the HTTP batch endpoint directly — see Ingestion API. Prefer the JS SDK in browsers so session id, retry, and privacy behavior stay consistent.

Verify

  1. Trigger the event in a real browser session.
  2. Dashboard → Events → Custom (or build a Funnel step).
  3. Open a Replay and check the activity Custom tab.
  4. Network tab: look for /api/ingestion/customEvent/batch (or single) returning 2xx.