Skip to main content
An event is one thing a user did: a name, optional properties, and a timestamp taken the moment you call step(). Pageviews are events too, named $pageview and recorded for you when tracking is on; Pageviews and sessions covers those. Events queue in memory and leave in batches, so tracking costs the page a few requests a minute at most.

Tracking an event

Call step() with a name and an optional properties object:
The method signature is:
  • name: a string between 1 and 100 characters that identifies the action.
  • properties: an optional plain object with key-value metadata. Every value must be JSON-serializable.
Event names must be 1–100 characters and properties a plain object (class instances and top-level arrays are rejected). Invalid calls log a [Wendung - Warning] and are ignored; nothing throws. Circular references surface later, at serialization time: the whole batch is dropped with a Failed to serialize batch warning.

Event payload structure

Each step() call snapshots the current session ID, identity, and page context at track time. The queued event takes this shape:

Full request payload

When a batch is flushed, the SDK POSTs an EventRequestPayload to the ingest endpoint. Your API key is sent in the X-API-Key header, not in the body:
sentAt reflects when the batch was dispatched. Per-event timing is preserved in each event’s own timestamp, and each event carries its own identity and context snapshots.

Naming events

Names are the contract between your code and your funnels, so pick a convention and stick to it:
Lowercase words joined by underscores are the most portable format across analytics tools and databases.
Events describe things that already happened, so the name should reflect that.
Avoid generic names that are hard to distinguish in dashboards.

Using properties

Properties are key-value metadata on one event, and they are what you filter and slice by later. Put things there that are specific to that moment. Anything true of the user in general belongs in identify() traits instead.
All property values must be JSON-serializable. Strings, numbers, booleans, arrays, and nested plain objects are all valid. Class instances and functions are not.