Skip to content

Send custom events

Name the moments a page view cannot capture, attach the properties you want to break them down by, and identify a person when you have the right to.

3 min read Updated Suggest an edit

A custom event is anything you name — a sign-up, a checkout, a plan change, an export. Tag an element, or call the tracker's API.

Tag an element

Add data-sg-event to a button, link, element, or form.

HTML
<button data-sg-event="signup_clicked" data-sg-prop-plan="growth">  Start trial</button>

Each data-sg-prop-* attribute becomes an event property. The suffix becomes the property name.

The click detector checks the selected element and three ancestors. Property values from attributes use at most 200 characters.

A tagged element always wins over autocapture: the click sends your named event, never both.

Call the API

Use the JavaScript API for events that do not map to an element.

JavaScript
window.sightglass.track("signup_completed", { plan: "growth" });

The call returns immediately; the event is sent with the next batch.

Naming events

Event names match [a-z][a-z0-9_]{0,63} — lowercase letters, digits and underscores, at most 64 characters. A name that fails the shape is refused with bad_event_name.

Names beginning sg_ belong to the platform and are refused with reserved_event_name. The platform's own vocabulary is sg_page_view, sg_screen_view, sg_app_launch, sg_session_start, sg_identify, sg_click, sg_submit, sg_vitals and sg_purchase.

Two habits worth keeping:

  • Name what happened, in the past tense, rather than the button that was clicked.
  • Keep one name per meaning. Two names for one moment split every chart in two.

Properties

Rule Limit Why
Keys per event 32 Beyond it the event is refused with bad_properties.
Nesting depth 2 A deeper object is refused rather than flattened silently.
String value length 1 KB Long values are a document, not a dimension.
Whole event 32 KB Past it the event is refused with event_too_large.
Key names the event-name charset So filters behave the same everywhere.

Property keys are also what the dashboard offers as breakdowns. A project's property allowlist decides which keys appear there — it narrows the screen, not the storage: everything else you send is kept, after the scrub described below.

Custom events are a plan feature. Where the workspace's plan does not include them, the custom event alone is refused with custom_events_not_in_plan — the page view sent in the same batch is still recorded.

What never to send

Do not put personal data in an event name or a property. The ingest defends this, but it is your obligation and not ours:

  • A property key that looks secret-bearing — password, secret, token, auth, cookie, session, credit, card, cvv, ssn, iban, api_key — is dropped whole, wherever the fragment appears in the key.
  • A string value that looks like an email address, or like a long opaque token, is replaced with [redacted], whatever its key.
  • A page path loses its query string, a referrer is reduced to its host, the user agent is classified and then discarded, and no raw IP address ever reaches storage.

Identify a person

Traits are facts about your own user, sent by you, under identified consent only.

JavaScript
window.sightglass.identify("user_000000042", {  email: "[email protected]",  plan: "growth",  seats: 5,});
  • A user id matches ^[A-Za-z0-9_-]{8,64}$.
  • Traits are flat: keys [a-z][a-z0-9_]{0,39}, values string, number, boolean or null, at most 24 per call. A null deletes a trait; the merge is last-write-wins.
  • A secret-shaped key refuses the whole object.
  • Traits travel on one sg_identify event in its own batch. The tracker de-duplicates by value: an unchanged identity re-sends nothing across reloads.
  • Identify from a browser key that is locked to an origin is refused with origin_locked_key; send traits from a server key instead.

Call identify only after identified consent — see Cookieless by default. A person identified this way is also the one you can erase: Data removal.