Event context and variables
Set visitor state once and have it attached to every event — then segment and build funnels on both event properties and context.
Spectry's data model has two halves. An event records something that happened. Context records who it happened to and what state they were in. You set context once; Spectry attaches it to everything that follows.
The problem it solves
Without context, every fact you want to segment on has to be repeated on every event:
// Without context — the plan is repeated forever, and any call that
// forgets it silently drops out of your segments.
Spectry.track('purchase', { order_total: 49, plan: 'pro' });
Spectry.track('ticket_opened', { severity: 'high', plan: 'pro' });
Spectry.track('feature_used', { feature: 'export', plan: 'pro' });
With context, it is stated once:
Spectry.setContext({ plan: 'pro', account_type: 'business' });
Spectry.track('purchase', { order_total: 49 });
Spectry.track('ticket_opened', { severity: 'high' });
Spectry.track('feature_used', { feature: 'export' });
All three events are stored with plan and account_type attached.
Setting context
// Shallow merge — existing keys are kept
Spectry.setContext({ plan: 'pro' });
Spectry.setContext({ seats: 12 }); // context is now { plan, seats }
Spectry.getContext(); // { plan: 'pro', seats: 12 }
Spectry.clearContext(['seats']); // drop one key
Spectry.clearContext(); // drop everything (e.g. on logout)
Spectry.identify() populates context for you: the user ID lands as user_id, and any scalar traits are merged in alongside it.
Point in time, not current state
Context is attached to each event as it is captured, so it records the state at that moment. If a visitor buys on the free plan and upgrades an hour later, the purchase still reads free. This is what makes questions like "how many purchases came from free-plan users?" answerable at all — a profile lookup would only ever tell you what the user's plan is now.
Using it in segments and funnels
Event properties and context attributes are both addressable in rules, using a prefix to say which you mean:
event:order_total— a property from the event's own payload.context:plan— an attribute of the visitor at the time of the event.custom_event_name— the event name itself.
So the segment "purchases over €100 from visitors on the pro plan" is three rules:
custom_event_name equals purchase
event:order_total greater than 100
context:plan equals pro
Nested values are reachable with a dot path up to five levels deep, where numeric segments are array indices counting from zero — event:items.0.sku is the first item's SKU.
"Is it set?" is its own question
A property that is missing, one that is an empty string and one that is 0 are three different things. Comparing to an empty value cannot tell them apart, so use the exists and does not exist operators when that is what you mean. Numeric comparisons only match events that actually carry the property — event:discount less than 10 will not match an event with no discount at all.
Finding out what you already send
Spectry builds the list of your event names, their properties and your context attributes from the traffic itself, over the last seven days. Nothing needs registering, and events sent from code with Spectry.track() appear alongside ones built in the no-code builder. The flip side is that anything you have not sent recently will not be listed — it still works in a rule, it just is not suggested.
What belongs in context
Context is attached to every event, so it is bounded on purpose. Values must be a string, number, boolean or null; nested objects belong in event properties instead. You get up to 32 keys and 2 KB in total, kept for 30 days and shared across the visitor's tabs. Anything over the limit is dropped silently rather than throwing — see the JavaScript API reference for the exact figures.
Context is stored on the visitor's device, so treat it like any other analytics storage: keep personal data out of it beyond the identifiers you already send with identify(). Nothing is written until analytics consent is granted, and revoking that consent erases it.
Already using a GTM data layer?
If your site maintains a window.dataLayer for Google Tag Manager, Spectry can read it instead of you re-instrumenting. Turn on Site settings → Features → Data Layer and pushes are mapped automatically: an entry with an event key becomes a tracked event, and one without becomes context.
dataLayer.push({ event: 'purchase', order_total: 49 }); // -> Spectry.track('purchase', { order_total: 49 })
dataLayer.push({ plan: 'pro' }); // -> Spectry.setContext({ plan: 'pro' })
Entries already on the page when Spectry loads are read once, so identity pushed early still counts. GTM's own gtm.* lifecycle events are ignored, and GTM keeps working exactly as before.
Context answers "who and what state". For "what happened", see Track custom events.