Integration Reference
Everything you need to add Frostline to an app. No account required to read this.
Quick start
Add the Frostline script tag to your root layout — not individual page files. This ensures it loads on every route. Replace fl_YOUR_KEY with your API key.
HTML / plain site
<!-- Add to the shared <head> in your base template, not just index.html --> <script src="https://getfrostline.com/t.js" data-key="fl_YOUR_KEY" async ></script>
Next.js (App Router)
// app/layout.tsx
import Script from "next/script";
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src="https://getfrostline.com/t.js"
data-key="fl_YOUR_KEY"
strategy="afterInteractive"
/>
</body>
</html>
);
}Next.js (Pages Router)
// pages/_app.tsx
import Script from "next/script";
export default function App({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<Script
src="https://getfrostline.com/t.js"
data-key="fl_YOUR_KEY"
strategy="afterInteractive"
/>
</>
);
}Astro
<!-- src/layouts/BaseLayout.astro --> <script src="https://getfrostline.com/t.js" data-key="fl_YOUR_KEY" is:inline ></script>
$session_start and $pageview on every page. No extra code needed for basic analytics.Custom events
Track meaningful actions with frostline.track(eventName, properties). Call it after the script has loaded.
// Basic event
frostline.track("signup_completed");
// With properties
frostline.track("cta_clicked", { button: "hero", variant: "A" });
frostline.track("purchase_completed", { plan: "pro", amount: 49 });
frostline.track("core_action_performed", { feature: "export" });Recommended events by recipe
Landing page
frostline.track("cta_clicked"); // visitor clicks primary CTA
frostline.track("signup_completed"); // form submitted / account createdSaaS web app
frostline.track("cta_clicked"); // CTA on marketing site
frostline.track("signup_completed"); // account created
frostline.track("core_action_performed"); // user does the main thing your app does
frostline.track("feature_used", { name: "export" }); // secondary featuresWaiting for the script to load
// The tracker queues events while loading — this is safe to call immediately:
frostline.track("signup_completed");
// If you need to confirm it's ready first:
window.addEventListener("frostline:ready", () => {
frostline.track("signup_completed");
});Identify users
Call frostline.identify(userId) after a user signs in to link their events to a persistent ID.
// After sign-in:
frostline.identify("user_abc123");
// With optional traits:
frostline.identify("user_abc123", { plan: "pro", email: "user@example.com" });identify(), events are grouped by anonymous session ID. Call it as early as possible in your auth flow.Auto-tracked events
The script fires these automatically — no extra code needed.
| Event | When it fires | Properties |
|---|---|---|
| $session_start | First page load in a new session | session_id, referrer_domain, device_type, browser, os |
| $pageview | Every page load and client-side navigation | url, path, referrer, session_id |
Verify the integration
After installing the script and adding custom events, confirm data is flowing.
Onboarding status — 6-check health overview
GET https://getfrostline.com/api/onboarding/status?key=fl_YOUR_KEY
# Response shape:
{
"status": "complete" | "in_progress" | "not_started",
"checks": {
"api_reachable": true,
"browser_pageview": true,
"session_tracking": true,
"custom_events": false,
"referrer_capture": true,
"device_detection": true
},
"next_step": "Add frostline.track() calls for your recipe events."
}Data accuracy — full health report
GET https://getfrostline.com/api/verify-numbers?key=fl_YOUR_KEY # Returns markdown: event counts, expected vs. present events, # session health, active filters, and actionable recommendations.
Repair & debug
When data isn't flowing or checks are failing, the repair endpoint diagnoses the integration and tells you exactly what to fix.
GET https://getfrostline.com/api/repair?key=fl_YOUR_KEY
# Returns structured checks with pass / fail / warn status:
{
"status": "issues_found",
"checks": [
{
"id": "custom_events",
"status": "fail",
"title": "No custom events received",
"detail": "Expected: cta_clicked, signup_completed. Received: none in last 24h.",
"action": "Add frostline.track('cta_clicked') to your CTA button onClick handler."
}
]
}Common problems
Script loads but no events appear
Check that data-key matches your API key exactly. Keys start with fl_. Check the browser network tab for a request to /api/events.
frostline is not defined
The tracker hasn't loaded yet when your code runs. Use the frostline:ready event or call frostline.track() after script load.
Custom events not appearing
Confirm frostline.track() is called in response to a real user action, not inside a useEffect that never runs or a condition that's always false. Open DevTools and add console.log before the track call to confirm it executes.
Events appear in DevTools but not in the dashboard
Wait 5 minutes — events are processed asynchronously. If still missing after 15 minutes, call /api/repair for a diagnosis.
API reference
All endpoints are at https://getfrostline.com/api/. Public endpoints require your API key as a query param. No other auth needed.
/api/onboarding/status?key=fl_xxx6-check integration health. Returns status + next_step guidance./api/verify-numbers?key=fl_xxxFull data accuracy report — event counts, session health, actionable issues./api/repair?key=fl_xxxStructured diagnostics with pass/fail/warn per check and exact fix instructions./api/eventsIngest an event. Called by the tracker script — you don't usually call this directly./api/events/recent?key=fl_xxxLast N raw events for this app. Useful for live debugging./api/propertiesList registered apps for this API key. Requires Authorization: Bearer header./api/propertiesRegister a new app. Requires Authorization: Bearer header./api/feedbackReport integration friction. Body: { key, step, issue, severity, llm }./api/trialCreate a trial account from an email address. Returns a fl_trial_xxx key.