pex

Custom Events

The Apex snippet tracks several event types automatically and exposes an API for sending custom events. All events are sent to the events endpoint as JSON, using navigator.sendBeacon for reliable delivery during page unload.

POST/api/events

Receives all tracking events from the snippet

Accepts a JSON body with project key, event type, visitor ID, URL, timestamp, and a data object containing event-specific fields plus attribution context.

Automatic Events

These events are sent by the snippet without any code on your part:

Event TypeWhen It FiresKey Data
pageviewEvery page loadreferrer, isLanding, experiment assignments
form_submitAny <form> submissionformAction, email, assignments, attribution
engagementVisitor leaves the pageduration (seconds), scrollDepth (0–100%)
heartbeatOnce per page loadsnippetVersion, experiment and form status, screen/viewport size
clickOutbound link clickhref, link text
goal_conversionExperiment goal metgoalType, experimentId, variant, goal-specific fields
rage_click3+ rapid clicks in same areax, y, selector, clicks
dead_clickClick on non-interactive elementx, y, selector, text
js_errorUnhandled JS error or rejectionmessage, source, line, col

Sending Custom Events

Use the global window.apex.track() method to send your own events:

window.apex.track("signup_started", {
  plan: "pro",
  source: "pricing_page"
});

The snippet automatically attaches the visitor ID, project key, current URL, timestamp, and attribution data. You only need to provide the event name and any custom properties.

Common Examples

// Video engagement
window.apex.track("video_played", {
  videoId: "intro-demo",
  duration: 45
});

// Pricing interaction
window.apex.track("pricing_toggle", {
  interval: "annual",
  plan: "growth"
});

// Feature activation
window.apex.track("feature_used", {
  feature: "export_csv",
  firstTime: true
});

Event Payload Format

Every event sent to /api/events follows this structure:

{
  "projectKey": "your-project-key",
  "type": "pageview",
  "visitorId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "url": "https://yoursite.com/pricing",
  "timestamp": "2025-07-15T10:30:00.000Z",
  "data": {
    "referrer": "https://google.com",
    "isLanding": true,
    "assignments": [
      {
        "experimentId": "exp-hero-copy",
        "variant": "variant_b",
        "selectorFound": true,
        "contentMatch": true
      }
    ],
    "attribution": {
      "utm_source": "google",
      "utm_medium": "cpc",
      "utm_campaign": "brand_q3",
      "gclid": "CjwKCAjw..."
    }
  }
}

The data.attribution object is automatically injected from the apex_attr cookie on every event, so your custom events always carry full attribution context.

Goal Conversions

Goal conversions are a special event type tied to experiments. The snippet tracks them automatically when you define a conversion goal on an experiment. The goal_conversion event includes:

{
  "type": "goal_conversion",
  "data": {
    "goalType": "click",
    "selector": ".cta-primary",
    "label": "Primary CTA Click",
    "experimentId": "exp-hero-copy",
    "variant": "variant_b",
    "assignments": [{ "experimentId": "exp-hero-copy", "variant": "variant_b" }]
  }
}

Goal types and their specific fields:

Goal TypeExtra Fields
clickselector, label
pageviewtargetUrl, label
file_downloadfileExtension, fileName, label
engaged_timeengagedSeconds, thresholdSeconds, label

Behavioral Events

The snippet captures UX signals automatically to surface usability issues:

Rage Clicks

Detected when a visitor clicks the same area 3 or more times within 800ms — a strong signal of user frustration (broken buttons, unresponsive UI).

Dead Clicks

Detected when a visitor clicks on a non-interactive element (not a link, button, input, or element with role="button"). Frequent dead clicks often indicate confusing visual affordances.

JS Errors

Both window.onerror and unhandledrejection events are captured and forwarded. Useful for correlating JavaScript errors with conversion drops.

Helper Methods

The snippet exposes a few utility methods on window.apex:

// Get the current visitor's anonymous ID
const visitorId = window.apex.getVisitorId();

// Identify a visitor by email (with optional metadata)
window.apex.identify("user@example.com", { name: "Jane Doe" });

// Send a custom event
window.apex.track("button_clicked", { buttonId: "hero-cta" });

Info

The window.apex object is available as soon as the snippet loads. If you need to call it before the snippet runs, initialize it first: window.apex = window.apex || {};

Next Steps

  • Form Tracking — how form submissions are captured automatically
  • Experiments — how experiment assignments flow into events
  • Installation — verify events are reaching the Apex API