Send Custom Events
Beyond the built-in events the assistant records automatically (session starts, queries, reactions, forms), you can send your own custom events — each carrying whatever properties you attach — from the page where the assistant is embedded. Custom events appear in the User Activity Feed and the session timeline alongside the standard ones, so you can correlate visitor behavior on your site with the assistant conversation and follow the exact context you care about.
The sendTrace Method
The assistant instance exposes sendTrace:
await window.skdwn.instance.sendTrace(eventName, eventProperties);
| Parameter | Type | Required | What it does |
|---|---|---|---|
eventName | string | Yes | The name of the event — pick something descriptive, like CTA.Clicked or Product.Viewed. |
eventProperties | Record<string, string> | No | Key–value pairs attached to the event. Use them to add context — a button ID, a page path, a product SKU. |
Send an Event with Properties
The properties are where custom tracking becomes useful: attach whatever context you want to follow, as string key–value pairs. Call sendTrace from any script on the page where the assistant is embedded — a button handler, a route change, a checkout step:
// Fire from your own page code — no API key, no extra endpoint needed.
window.skdwn.instance.sendTrace("Pricing.Viewed", {
plan: "pro",
billing: "annual",
source: "hero-cta"
});
A few things worth knowing:
- Values are strings. Pass strings; stringify anything else —
String(count),
price.toFixed(2). The keys are yours to choose.
- It's fire-and-forget. The call returns a Promise, but you don't need to
await it — if the connection isn't ready it fails quietly instead of throwing.
- Guard very early calls. If a trace might fire before the widget has
connected, check isConnected first:
if (window.skdwn?.instance?.isConnected) {
window.skdwn.instance.sendTrace("Pricing.Viewed", { plan: "pro" });
}
What Happens to Your Properties
Once sent, an event carries its properties everywhere analytics can read them:
- User Activity Feed — your properties render inline in the Details column
of the event's row (see Track User Activity).
- Session timeline — they appear in the event's expandable detail card (see
- CSV export — the
ActivityFeedexport includes them, so you can pivot on
them in a spreadsheet or a BI tool.
Your eventName is stored and shown exactly as you wrote it (Pricing.Viewed), and every property you set is preserved verbatim.
Reserved Property Names
Seekdown attaches a few identity and routing properties to every event automatically. You don't set these, and they don't appear among your custom Details — they power the User, Source, and Time columns and the session grouping instead:
| Property | Comes from | Used for |
|---|---|---|
userId | your userId embed option | the identity every event is grouped and filtered by |
sessionId | the assistant | groups a visitor's events into one session |
assistantId | the assistant | the Source column |
tenantId | the server | keeps your analytics scoped to your workspace |
isPreview | the assistant | marks dashboard/preview traffic |
user.* | your userInformation embed option | the friendly User label (e.g. user.email) |
Avoid reusing these names for your own properties. Anything else you send is stored as-is and shown in Details.
Example: Track Reference Clicks with a Custom Helper
The natural way to send custom events is through a custom helper — a small JavaScript function you add in the Advanced editor and call from your templates. This keeps tracking logic alongside the rest of your assistant customization.
1. Create the helper. In the Advanced editor, add a new helper named trackReferenceClick:
(referenceId, referenceTitle) => {
window.skdwn.instance.sendTrace("Reference.Clicked", {
referenceId: referenceId,
referenceTitle: referenceTitle
});
}
2. Call it from a template. Override the highlighted template (or your own content-type template) and wire the helper to the link's onclick:
<a href="{{ reference.url }}"
target="_blank"
onclick="skdwn.instance.helpers.trackReferenceClick(
'{{ reference.id }}',
'{{ reference.title \| sanitize }}'
)">
{{ reference.title }}
</a>
Every time a visitor clicks a reference card, a Reference.Clicked event is recorded in the session timeline with the reference ID and title.
3. Another example — track a product view. If your assistant uses a custom PRODUCT content-type template, add a helper named trackProductView:
(productId, category) => {
window.skdwn.instance.sendTrace("Product.Viewed", {
productId: productId,
category: category
});
}
Then fire it when the product card renders or when the visitor clicks it:
<div class="product-card"
onclick="skdwn.instance.helpers.trackProductView(
'{{ reference.id }}',
'{{ reference.dataset \| sanitize }}'
)">
<h4>{{ reference.title }}</h4>
<a href="{{ reference.url }}">View product</a>
</div>
How It Works
- The call sends the event over the assistant's SignalR connection to the
backend — no extra endpoint or API key is needed.
- If you set
userInformationin the embed options,
those properties are automatically included in the event (prefixed with user.), so you don't need to pass them again.
- The event is recorded under your own
eventName, with its properties, and
shows up in both the session timeline and the User Activity Feed.
Best Practices
- Name events
Domain.Action. A consistent scheme (Pricing.Viewed,
Signup.Started, Reference.Clicked) keeps the feed readable and groups related events together.
- Keep names stable. The feed and CSV group by the exact event name — renaming
an event splits its history. Pick a name and keep it.
- Send strings, keep them small. A handful of short, meaningful properties
beats a large blob; stringify numbers and booleans.
- Don't send secrets. Traces are stored in your analytics and shown in the
dashboard — never put passwords, tokens, or data you wouldn't want a teammate to read into a property.
When to Use It
- Measure what visitors do with answers — track which reference cards they
click, which products they view, which links they follow.
- Measure funnel steps — send events for each step (e.g.
Pricing.Viewed,
Signup.Started, Signup.Completed) and later see which sessions include which steps.
- Debug template interactions — fire a trace from a custom helper and
inspect it in the session timeline to verify that your template wiring works as expected.