fastmon Docs

Custom events

Send your own events, such as an add-to-cart, a login, or a signup, from the tracker, a click, the GA4 dataLayer, or a single POST.

An event records a step without a URL of its own: an add-to-cart from a drawer, a login, a search, a newsletter signup. It is a name and, optionally, up to 30 properties.

From the tracker

Call fastmon.event with a name and the properties:

fastmon.event('add_to_cart', { value: 129.9, currency: 'EUR', sku: 'SW-100' });

The event rides on the next beacon of the pageview. Without one within about a second, the tracker sends an event_update beacon by fetch, at most 20 per pageview. At page hide, pending events also go by keepalive fetch, and the collector keeps one copy.

A call before the tracker has loaded needs this queue stub first. The tracker sends what it queued with its first beacon.

<script>
  window.fastmon = window.fastmon || {};
  fastmon.event = fastmon.event || function () { (fastmon._q = fastmon._q || []).push(arguments); };
</script>

From a click

A click on an element with data-fm-event, or on anything inside it, sends an event with that name. Every other data-fm-event-* attribute becomes a property, its value always a string.

<button data-fm-event="add_to_cart" data-fm-event-sku="SW-100" data-fm-event-value="129.9">
  Add to cart
</button>

The closest element with the attribute decides. An empty data-fm-event="" keeps clicks inside a marked container from counting.

From the dataLayer

Two independent application settings, both off by default, read pushes on window.dataLayer. Pushes before the tracker loaded count too, Google Tag Manager's gtm.* pushes never do.

  • collection.ga4_ecommerce reads view_item, add_to_cart, remove_from_cart, view_cart, begin_checkout, add_payment_info, and purchase with their ecommerce props.
  • collection.data_layer reads every push that carries an event name. The event has no props unless you list top-level keys in collection.data_layer_prop_keys, up to 30.
  • Repeats: one name counts at most 10 times per pageview.

A GA4 event keeps value, currency, the number of items as item_count, and per item items.<n>.item_id, item_name, price, and quantity. A large order keeps at least its first six items. The order id and every other field stay in the page.

view_cart, begin_checkout, and purchase also reach their checkout funnel stage.

Keep or drop names

collection.data_layer_mode and collection.data_layer_names filter dataLayer events at the collector. A change applies within five minutes.

  • block (default) drops the listed names. With an empty list nothing is dropped.
  • allow keeps only the listed names, the GA4 names included. An empty list keeps no dataLayer event.
  • List: up to 50 names, and eec.* covers every name starting with eec..

fastmon.event() calls and data-fm-event clicks are never filtered.

Without the tracker

Any script on your pages, a tag manager included, can post a single event. Send it as text/plain to avoid a preflight.

POST https://fastmon.site/c/e/{collector_hash}
Content-Type: text/plain

{"u": "https://shop.example/cart", "n": "add_to_cart", "p": {"value": 129.9, "currency": "EUR"}}
KeyRequiredMeaning
uyesThe page URL. Its host picks the site. Stored like a pageview URL.
nyesThe event name.
pnoThe properties, an object. Nested objects flatten to parent.child.
tsnoWhen it happened, epoch milliseconds. Defaults to the receive time.
pvidnoThe pageview it belongs to. Without it the event joins no pageview and only counts.
sqnoCounts your events of one pageview from 1. Without it each event gets a random one.

The route answers 204 whatever the body holds. A body that breaks a rule is dropped silently. Two posts with the same pvid, ts, and sq are one event, so a retry should carry its sq.

When the POST is blocked, GET /c/e/{collector_hash}.gif takes the same keys in the query string, with p as the JSON text of the object.

Browsers only

Country, device, and bot verdict come from the request, so a post from your server counts as a bot.

Limits and rules

RuleValue
Namea-z, 0-9, _, ., -, 1 to 48 characters after lowercasing, at least one letter or digit
Events per beacon20, the rest is lost
Events per pageview100, the tracker sends no more
Property keys30 after flattening
Key length128 characters
Value length500 characters
  • Name cleanup: the tracker turns every other character into _, so Add To Cart is stored as add_to_cart and Größe as gr_e. It skips a name with no letter or digit left. /c/e/ rewrites nothing and drops an invalid name.
  • Over a limit: the whole event is dropped, and the beacon carrying it is kept.
  • Types: a number or a boolean is stored as text, an array as its JSON text.
  • Revenue: name the properties value and currency. Nothing converts or checks a currency.
  • Sampling: events are never sampled, not billed, and not capped per site.
  • Off switch: the application setting event_tracking turns your own events off.

Privacy

Names and properties must not hold personal data. The tracker masks keys and email addresses as described under Privacy → Event properties.

Correct or delete an event

Owners and members fix a wrong name, a wrong value, or a test purchase on one event. Open its row on the Events tab, or call PATCH /sites/{site_id}/events/{event_id} with the new name or properties. DELETE on the same path removes it.

The event_id comes from the event list. Every count and list follows, and the audit log records event.updated or event.deleted. Stage events derived from checkout pages cannot be changed and answer 409.

Where events show up

The page sits under Explorer → Events in the sidebar.

  • Overview tab: events over time by name, the names ranked, and the most frequent values of each property.
  • Revenue: one order per pageview with order_placed or purchase, at its largest value, per currency. A reloaded thank-you page counts again.
  • Value per event: the sum of value per name and currency.
  • Events tab: one row per event with its properties as chips. A row opens to every stored field and has a share link.
  • Name filter: suggests the names of the period by count and accepts any valid name.
  • Page filters: URL, page type, login state, connection, and viewport class narrow the events. Events stored before 2026-10-16 carry no page and match none.
  • Visitor journey: shows a visitor's events with their properties. A purchase closes a visit like order_placed.

API

  • POST /organizations/{org_id}/analytics/events lists events newest first, each with event_id, name, source, and props. names takes any name, and source is tracker, collector, or shopify_pixel. See the reference.
  • POST /organizations/{org_id}/analytics/events/overview counts the events of a window per name, over time, and per property value, with order_revenue and value_sums. revenue is deprecated.
  • MCP and Ask: the get_events tool answers the same counts. See MCP server.

On this page