SSO & Event Capture
Dashboard SSO, customer app identify after SSO, and the full send-and-catch configuration checklist.
TrackStack has two SSO layers:
- TrackStack dashboard login — Clerk enterprise SSO for your workspace admins
- Your product's customer SSO — SDK
identify()+capture()so conversion events attach to signed-in users
This guide covers both, required env vars and headers, and how events reach the edge.
TrackStack dashboard SSO (Clerk)
The TrackStack dashboard authenticates via Clerk. Workspace admins can enable enterprise SSO for team login:
- Open the Clerk dashboard for your TrackStack Clerk instance
- Go to Configure → SSO connections (SAML/OIDC)
- Connect your IdP (Okta, Azure AD, Google Workspace, etc.)
- Map email and name attributes for member provisioning
No TrackStack application code changes are required for dashboard SSO. This is separate from conversion tracking in your product.
Your app — identify after customer SSO
When users sign in through your app's SSO (Clerk, Auth0, NextAuth, etc.), wire TrackStack after the session is established:
trackstack.identify(user.id, {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
externalId: user.id,
});
Why identify matters for B2B
Ad platform CAPI match rates depend on hashed identifiers in each event payload. The SDK identify() call:
- Syncs PostHog person profiles when PostHog is configured
- Does not automatically attach traits to subsequent
capture()calls on the edge
Always include email (and name when available) on conversion events, especially after SSO login:
trackstack.capture("SignUp", {
email: user.email,
eventId: `signup_${user.id}`,
});
trackstack.capture("Purchase", {
email: user.email,
value: 9900,
currency: "USD",
transactionId: "txn_123",
plan: "Growth",
});
Provider-specific helpers
| Provider | Component | Package |
|---|---|---|
| Clerk | TrackStackClerkIdentify | @trackstack/sdk/react-clerk |
| Auth0 | TrackStackAuth0Identify | @trackstack/sdk/react-auth0 |
| NextAuth / Auth.js | TrackStackNextAuthIdentify | @trackstack/sdk/react-nextauth |
| Better Auth | TrackStackBetterAuthIdentify | @trackstack/sdk/react-better-auth |
| Supabase Auth | TrackStackSupabaseIdentify | @trackstack/sdk/react-supabase |
| Firebase Auth | TrackStackFirebaseIdentify | @trackstack/sdk/react-firebase |
Clerk example (auto-identify + SignUp within 2 minutes of account creation):
import { TrackStackClerkIdentify } from "@trackstack/sdk/react-clerk";
<ClerkProvider>
<TrackStackProvider instance={trackstack}>
<TrackStackClerkIdentify />
{children}
</TrackStackProvider>
</ClerkProvider>
Custom auth (Better Auth, custom SAML callback):
import { useIdentifyFromAuth } from "@trackstack/sdk/react-auth";
const identifyFromAuth = useIdentifyFromAuth();
// In your SSO callback / session effect:
identifyFromAuth({
userId: session.user.id,
email: session.user.email,
firstName: session.user.firstName,
isNewSignUp: false,
});
Required environment variables
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_TRACKSTACK_KEY | Yes | Publishable API key from API Keys |
NEXT_PUBLIC_EDGE_URL | No | Edge base URL. Default: https://edge.gettrackstack.com |
NEXT_PUBLIC_POSTHOG_KEY | No | PostHog project key when using first-party /_ph proxy |
Vite / SPA: use VITE_TRACKSTACK_KEY and pass to createTrackStack({ publicKey: import.meta.env.VITE_TRACKSTACK_KEY }).
Edge request headers
| Header | Required | Description |
|---|---|---|
x-ts-key | Yes | Same publishable key as SDK publicKey |
Content-Type | Yes | application/json for POST /events |
X-SDK-Version | No | Set automatically by @trackstack/sdk |
x-ts-domain | Server only | Origin hostname when sending without a browser Origin header |
Example server-side capture:
await fetch(`${edgeUrl}/events`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-ts-key": process.env.TRACKSTACK_SECRET_KEY!,
"x-ts-domain": "app.example.com",
},
body: JSON.stringify({
events: [{
event: "Purchase",
eventId: "txn_server_001",
email: "buyer@example.com",
value: 1299,
currency: "USD",
transactionId: "txn_001",
}],
}),
});
Use a server-side secret key for backend calls — never expose destination CAPI tokens in client code.
Ingestion paths (send & catch)
| Path | How | Where to verify |
|---|---|---|
| Client SDK | capture() → batched POST /events | Delivery Logs |
| Server-side | Same OpenAPI contract, direct POST /events | Delivery Logs |
| PostHog proxy | Optional /_ph first-party analytics | PostHog + Integrations |
Configure routing (destinations, credentials, event allowlists, domain policy) in Configure.
Full configuration checklist
- Create org + API key — publishable key for SDK init
- Configure destinations — enable platforms, enter CAPI credentials
- Event mapping / allowlist — choose canonical events per destination
- Domain allowlist — restrict origins (recommended for production)
- Install SDK + public key —
@trackstack/sdk, provider, env vars - Identify on login (SSO) —
identify()after session; email on every capture - capture() — SignUp, Purchase, PageView from auth, billing, navigation
- Verify in Delivery Logs — confirm edge receipt and platform delivery
The Configure screen includes a live checklist with auto-detection where possible.
Edge identity handling
The edge normalizes inbound events via userData (email, phone, name, location) and customData (value, currency, transactionId). Identifiers are hashed per destination before CAPI delivery — do not pre-hash in app code.
Traits passed to identify() are not persisted on the edge for later event enrichment today. Include user identifiers on each capture() payload for reliable CAPI match rates.
Next steps
- Quickstart — first event in minutes
- SDK setup — React/Next.js patterns
- Events — canonical event catalog
- API playground — test
POST /events