Skip to main content

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:

  1. Land in TrackingEvent (same place as client events).
  2. Enrich the user profile — same path as client tracking, so the event also shows on the profile timeline (ProfileEvent), advances ProfileFunnelLink.currentStage if applicable, and updates engagement counters.
  3. 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_events mutation 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.
  • userId is forced to the session user's ID — payload-supplied user IDs other than yours are rejected.
  • The siteId must belong to the workspace identified by ?workspaceId=.

What gets recorded

For each event:

  • A row in TrackingEvent with the channel categorized from referrer / utm.
  • A row in ProfileEvent (the profile timeline) tagged with profileId, workspaceId, and funnelId.
  • Identifier rows in ProfileIdentifier if the event carries email or userId — feeding the cross-device merge logic.
  • Stage advance to CONSIDERATION on signup / identify, or to TRIAL on trial_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_id isn't enough).
  • App-internal events like "user invited a teammate" that you want to track without exposing the visitor ID to the browser.