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",
});| Argument | Type | Rules |
|---|---|---|
eventName | string | Required; empty / invalid names are skipped with a warning |
properties | Record<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:
| Knob | Value | Behavior |
|---|---|---|
| Flush timer | 100 ms | Debounced flush after the first queued event |
| Max batch | 50 events | Hard flush when the batch fills |
| Endpoint | POST /api/ingestion/customEvent/batch | Primary path |
| Fallback | Single POST /api/ingestion/customEvent or embed into the replay event stream | Used 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
| Do | Don’t |
|---|---|
Stable enums (plan: "pro") | Free-text blobs that change every session |
| Small primitives (string / number / boolean) | Huge HTML / base64 / screenshots |
Separate identity via identifyUser | Put passwords / tokens in properties |
| Keep names stable for funnels | Rename 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
- Trigger the event in a real browser session.
- Dashboard → Events → Custom (or build a Funnel step).
- Open a Replay and check the activity Custom tab.
- Network tab: look for
/api/ingestion/customEvent/batch(or single) returning 2xx.