Search documentation

Search titles, headings, and page summaries.

Custom events

Record meaningful actions for Goals, Funnels, and Experiments.

Choose an event name that describes a completed action, such as newsletter_subscribe or activated. Send it when the action succeeds, rather than when a button merely appears. There is no extra setup step in Settings: a stored custom event can be used as a Goal immediately.

Each stored custom event counts toward the Workspace's tracked-event allowance. Stripe payment ingest does not. Custom events never match payments; use Checkout metadata or identify for attribution.

JavaScript

JavaScript
window.graytower("newsletter_subscribe");
window.graytower("plan_selected", { plan: "pro" });

Call window.graytower from your app when a visitor completes an action. Do not put the same event on both JavaScript and HTML for one control.

HTML click tracking

HTML
<button data-gt-event="plan_selected" data-gt-event-plan="pro">
  Choose Pro
</button>

HTML params use data-gt-event-*. Kebab-case becomes snake_case (data-gt-event-plan-name becomes plan_name). Nested attributes fire only the nearest element.

Track a visible section

HTML
<section
  data-gt-scroll="pricing_seen"
  data-gt-scroll-threshold="0.5"
  data-gt-scroll-delay="1000"
>
  <!-- Pricing content -->
</section>

The example sends pricing_seen after at least half the section has remained visible for one second. This is an opt-in custom event, not automatic scroll tracking. Scroll events include scroll_percentage, threshold, and delay, leaving room for up to seven custom data-gt-scroll-* params within the 10-param limit.

Server API

Most reliable for signups and backend workflows. Create a Custom events server API key under Website → Settings → Developer, then forward the browser _gt_id as anonymousId.

JavaScript
await fetch("https://graytower.app/api/collect/server", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GRAYTOWER_SERVER_EVENT_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    type: "newsletter_subscribe",
    eventId: crypto.randomUUID(),
    anonymousId: visitorId, // the browser's _gt_id UUID
    params: { plan: "pro" },
  }),
});

See the Events API and server-side tracking for request fields and retries.

Names and usage

Names use lowercase letters, numbers, _, -, or : and are at most 64 characters. Parameter keys are a-z, 0-9, _, and - only (no colon). Up to 10 parameters are allowed, with values at most 255 characters. Values are stored for Journeys and are not scrubbed.

Do not put secrets, passwords, access tokens, payment details, or sensitive personal data in params or HTML attributes such as data-gt-event-email.

Reserved names such as pageview, identify, signup, reset, and checkout_started are not custom events. identify, signup, and reset update identity. checkout_started is reserved for Level 3 payment matching.