Server-side events
The standard tracking snippet captures events from the browser. Some events only happen on your server — a Stripe webhook firing, a signup callback, an internal user action — and those need a server-side path.
What it does
POST /api/tracking/server-events records events that:
- Land in
TrackingEvent(same place as client events). - Enrich the user profile — same path as client tracking, so the event also shows on the profile timeline (
ProfileEvent), advancesProfileFunnelLink.currentStageif applicable, and updates engagement counters. - Are workspace-scoped — events written through this endpoint are bound to the authenticated session's workspace and a tracking site you own.
Auth model
This endpoint takes the session cookie of the logged-in workspace user — not an API key. That makes it safe for first-party use (your dashboard or admin tools running under the same session), but it is not intended for true server-to-server calls from a backend you don't control. For backend integrations on a different host, the standard pattern is:
- Forward the visitor cookie (
_fn_vid) to your backend in the original request. - Pass the visitor ID through Stripe
client_reference_id(see install-tracking). - Or use the MCP
write:custom_eventsmutation tool with an API key.
Request
POST /api/tracking/server-events?workspaceId=ws_123
Content-Type: application/json
Cookie: <session-cookie>
{
"siteId": "site_456",
"events": [
{
"type": "signup",
"visitorId": "<from _fn_vid cookie>",
"email": "[email protected]",
"path": "/api/signup",
"props": { "plan": "pro" }
}
]
}
Constraints
- Max 50 events per request.
- Max 8 KB per event
props. - Rate-limited at 600/hr per session user.
userIdis forced to the session user's ID — payload-supplied user IDs other than yours are rejected.- The
siteIdmust belong to the workspace identified by?workspaceId=.
What gets recorded
For each event:
- A row in
TrackingEventwith the channel categorized fromreferrer/utm. - A row in
ProfileEvent(the profile timeline) tagged withprofileId,workspaceId, andfunnelId. - Identifier rows in
ProfileIdentifierif the event carriesemailoruserId— feeding the cross-device merge logic. - Stage advance to
CONSIDERATIONonsignup/identify, or toTRIALontrial_signup/trial_start(see tracking concepts).
When to use
- Server-side signups that bypass a client-side
funnelfizz('event', 'signup')call. - Stripe webhook side-effects that need to mirror onto the profile timeline (when
client_reference_idisn't enough). - App-internal events like "user invited a teammate" that you want to track without exposing the visitor ID to the browser.