SingleAnalytics Documentation
SingleAnalytics is a unified web analytics platform that combines traffic intelligence with product analytics. One SDK gives you page views, traffic attribution, custom events, funnels, retention cohorts, user journey tracking, and real-time data — all in one dashboard.
Introduction
SingleAnalytics replaces the need for separate traffic analytics (like Google Analytics) and product analytics (like Mixpanel or Amplitude) tools. With a single lightweight script on your website, you automatically get:
- Automatic page view tracking with full traffic source attribution
- Session management with 30-minute inactivity timeout
- Custom event tracking with arbitrary properties
- User identification to link anonymous and authenticated sessions
- SPA (Single Page Application) navigation detection
- Declarative click tracking via HTML data attributes
- Privacy-first: respects Do Not Track, no cookies by default
Quick Start
Get analytics running on your site in under 2 minutes:
1. Sign up and create a project
Create an account at the SingleAnalytics dashboard and create your first project. You'll receive an API key that looks like sa_4f8a2b1c9d3e7f6a.
2. Add the tracking script
Paste this snippet into your website's <head> tag:
<script
src="https://api.singleanalytics.com/sa.js"
data-api-key="YOUR_API_KEY"
data-host="https://your-api-host.com/api"
defer
></script>3. You're done
Page views are tracked automatically. Visit your dashboard to see data flowing in within seconds. Optionally, add custom events and user identification as you need them.
Create a Project
Each project represents a website or application you want to track. A project has a unique API key used to authenticate tracking requests. You can create multiple projects from the dashboard's Settings page.
After creation, your project will have an API key like sa_4f8a2b1c9d3e7f6a. You can regenerate this key at any time from Settings. Regenerating invalidates the previous key immediately.
Installation
The SingleAnalytics SDK is a single JavaScript file (~4KB) that runs in the browser. It has zero dependencies and works with any website or framework.
Script Tag (Recommended)
<script
src="https://api.singleanalytics.com/sa.js"
data-api-key="YOUR_API_KEY"
data-host="https://your-api-host.com/api"
defer
></script>| Parameter | Type | Required | Description |
|---|---|---|---|
| data-api-key | string | required | Your project API key from the dashboard |
| data-host | string | optional | API endpoint URL. Auto-detected from script src if omitted. |
defer attribute so the script loads without blocking page rendering.NPM / Module Bundlers
If you prefer to bundle the SDK with your application, you can self-host sa.js and import it, or simply copy the script tag into your HTML template. The SDK exposes a global sa object (also available as window.SingleAnalytics).
Auto-Tracking
As soon as the script loads, it automatically tracks a page_view event with:
- Full page URL and path
- Page title
- Document referrer
- UTM parameters (utm_source, utm_medium, utm_campaign)
- An anonymous user ID (stored in localStorage)
- A session ID (resets after 30 minutes of inactivity)
The server-side automatically extracts the browser, operating system, device type, and geolocation from the request headers.
sa.track(eventName, properties?)
Track a custom event with an arbitrary name and optional properties object.
// Basic event
sa.track('signup');
// Event with properties
sa.track('purchase', {
plan: 'growth',
amount: 49,
currency: 'USD',
});
// Feature usage
sa.track('feature_used', {
feature: 'funnel_builder',
duration: 120,
});| Parameter | Type | Required | Description |
|---|---|---|---|
| eventName | string | required | Name of the event (e.g. "signup", "button_click") |
| properties | object | optional | Key-value pairs of additional data. Values can be strings, numbers, or booleans. |
sa.identify(userId, traits?)
Link the current anonymous user to a known identity. Call this after login or registration. All subsequent events will be associated with this user ID.
// After user logs in
sa.identify('user_123');
// With additional traits
sa.identify('jane@example.com', {
name: 'Jane Doe',
plan: 'growth',
company: 'Acme Inc',
});| Parameter | Type | Required | Description |
|---|---|---|---|
| userId | string | required | Unique user identifier (email, database ID, etc.) |
| traits | object | optional | User properties like name, plan, company. |
identify(), all future events (even across page reloads) will use this ID until reset() is called.sa.page(properties?)
Manually trigger a page view. This is automatically called on initial load and on SPA navigations, but you can call it explicitly for custom scenarios.
// Manually track a page view
sa.page();
// With custom properties
sa.page({ section: 'blog', category: 'tutorials' });sa.reset()
Clear the current user identity and session. Call this on logout to ensure the next visitor gets a fresh anonymous ID.
// On logout
function handleLogout() {
sa.reset();
// redirect to login...
}Declarative HTML Attribute Tracking
Track click events without writing JavaScript by adding data-sa-event to any HTML element. Any additional data-sa-* attributes become event properties.
<!-- Track a button click -->
<button data-sa-event="cta_click" data-sa-label="hero" data-sa-variant="blue">
Get Started Free
</button>
<!-- Track a link click -->
<a href="/pricing" data-sa-event="nav_click" data-sa-target="pricing">
View Pricing
</a>
<!-- Track a form submission button -->
<button type="submit" data-sa-event="form_submit" data-sa-form="contact">
Send Message
</button>The click handler walks up to 3 parent levels to find the nearest annotated element, so wrapping content inside a tracked element works naturally.
SPA Support
SingleAnalytics automatically detects navigation in Single Page Applications by hooking into:
history.pushState()— standard SPA navigationhistory.replaceState()— URL replacementpopstateevent — browser back/forward
A page_view event is fired after each navigation. Duplicate fires for the same path are automatically deduplicated.
Pre-Load Queue
If you need to track events before the SDK script has loaded, you can queue them with a lightweight stub:
<script>
window.sa = window.sa || { q: [] };
sa.track = function() { sa.q.push(['track', ...arguments]); };
sa.identify = function() { sa.q.push(['identify', ...arguments]); };
sa.page = function() { sa.q.push(['page', ...arguments]); };
</script>
<!-- Your tracking calls can now happen before sa.js loads -->
<script>
sa.track('early_event', { source: 'inline' });
</script>
<!-- The SDK will process the queue when it loads -->
<script src="https://api.singleanalytics.com/sa.js" data-api-key="YOUR_KEY" defer></script>Configuration Options
The SDK behavior can be customized via data-* attributes on the script tag:
| Parameter | Type | Required | Description |
|---|---|---|---|
| data-api-key | string | required | Project API key |
| data-host | string | optional | API endpoint. Defaults to the script origin + /api |
Internal defaults:
- Session timeout: 30 minutes of inactivity
- Batch interval: 5 seconds
- Batch size: flushes at 20 queued events
- Privacy: respects
navigator.doNotTrack - Storage: uses localStorage (no cookies)
REST API Authentication
All event ingestion endpoints require an API key. Pass it via the x-api-key header or the api_key query parameter.
# Header authentication (recommended)
curl -X POST https://your-api.com/api/events/track \
-H "Content-Type: application/json" \
-H "x-api-key: sa_your_api_key" \
-d '{"eventName": "test"}'
# Query parameter authentication
curl -X POST "https://your-api.com/api/events/track?api_key=sa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"eventName": "test"}'POST /api/events/track
Track a single event.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| eventName | string | required | Name of the event |
| userId | string | optional | User identifier (anonymous or identified) |
| sessionId | string | optional | Session identifier |
| properties | object | optional | Arbitrary key-value metadata |
| url | string | optional | Full page URL |
| path | string | optional | URL path (e.g. /pricing) |
| title | string | optional | Page title |
| referrer | string | optional | Document referrer URL |
| timestamp | ISO 8601 | optional | Event timestamp. Defaults to server time. |
Example
curl -X POST https://your-api.com/api/events/track \
-H "Content-Type: application/json" \
-H "x-api-key: sa_your_api_key" \
-d '{
"eventName": "purchase",
"userId": "user_123",
"sessionId": "sess_abc",
"properties": {
"plan": "growth",
"amount": 49
},
"url": "https://myapp.com/pricing",
"referrer": "https://google.com"
}'Response
{
"success": true,
"data": {
"_id": "65f...",
"eventName": "purchase",
"projectId": "65f...",
"userId": "user_123",
"source": "google",
"medium": "organic",
"browser": "Chrome",
"os": "macOS",
"device": "desktop",
"timestamp": "2025-01-15T10:30:00.000Z"
}
}POST /api/events/track/batch
Track multiple events in a single request. More efficient for high-volume tracking.
curl -X POST https://your-api.com/api/events/track/batch \
-H "Content-Type: application/json" \
-H "x-api-key: sa_your_api_key" \
-d '{
"events": [
{
"eventName": "page_view",
"userId": "user_123",
"url": "https://myapp.com/"
},
{
"eventName": "button_click",
"userId": "user_123",
"properties": { "label": "signup" }
}
]
}'POST /api/events/identify
Identify a user and attach traits. Creates a special $identify event.
| Parameter | Type | Required | Description |
|---|---|---|---|
| userId | string | required | Unique user identifier |
| traits | object | optional | User properties (name, email, plan, etc.) |
curl -X POST https://your-api.com/api/events/identify \
-H "Content-Type: application/json" \
-H "x-api-key: sa_your_api_key" \
-d '{
"userId": "jane@example.com",
"traits": {
"name": "Jane Doe",
"plan": "growth",
"company": "Acme Inc"
}
}'REST API: Analytics Endpoints
All analytics endpoints are read-only and require authentication via bearer token or session cookie. Replace :projectId with your project's ID.
All analytics endpoints accept the following optional query parameters for filtering:
| Parameter | Type | Required | Description |
|---|---|---|---|
| startDate | ISO 8601 | optional | Start of date range (default: 30 days ago) |
| endDate | ISO 8601 | optional | End of date range (default: now) |
| country | string | optional | Filter by country code (e.g. "US") |
| device | string | optional | Filter by device type (desktop, mobile, tablet) |
| browser | string | optional | Filter by browser name |
| os | string | optional | Filter by operating system |
| source | string | optional | Filter by traffic source |
| medium | string | optional | Filter by traffic medium |
| path | string | optional | Filter by page path |
| eventName | string | optional | Filter by event name |
# Example: Get overview metrics for last 7 days, filtered to mobile
curl -X GET "https://your-api.com/api/analytics/PROJECT_ID/overview?startDate=2025-01-08&endDate=2025-01-15&device=mobile" \
-H "Authorization: Bearer YOUR_TOKEN"REST API: Goals
Goals let you define target events and track completion rates, revenue, and conversions over time.
Create a Goal
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectId | string | required | Project ID |
| name | string | required | Display name for the goal |
| eventName | string | required | Event name that counts as a completion |
| targetValue | number | optional | Target number of completions |
| currency | string | optional | Currency code for revenue goals (e.g. "USD") |
curl -X POST https://your-api.com/api/goals \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"projectId": "PROJECT_ID",
"name": "Trial Signup",
"eventName": "signup",
"targetValue": 100,
"currency": "USD"
}'List Project Goals
Analyze a Goal
curl -X GET "https://your-api.com/api/goals/GOAL_ID/analyze?startDate=2025-01-01&endDate=2025-01-31" \
-H "Authorization: Bearer YOUR_TOKEN"REST API: Experiments
Run A/B tests by creating experiments with multiple variants and tracking conversions against a goal event.
Create an Experiment
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectId | string | required | Project ID |
| name | string | required | Experiment name |
| variants | array | required | Array of { name, weight } variant objects |
| goalEvent | string | required | Event name that counts as a conversion |
curl -X POST https://your-api.com/api/experiments \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"projectId": "PROJECT_ID",
"name": "Pricing Page CTA",
"variants": [
{ "name": "control", "weight": 50 },
{ "name": "new_cta", "weight": 50 }
],
"goalEvent": "purchase"
}'Get Experiment Results
Assign a Variant
Returns the assigned variant name for the given user. Assignment is deterministic — the same user always receives the same variant.
Dashboard: Overview
The Overview page gives you a bird's-eye view of your analytics with six key metrics:
- Total Users — unique user IDs that sent events in the selected period
- Sessions — total sessions (30-min inactivity window)
- Page Views — total
page_viewevents - Events — total events of all types
- Avg Session Duration — average time between first and last event in a session
- Bounce Rate — percentage of sessions with only 1 page view
Below the metrics, a time-series chart shows daily trends for users, page views, and events over the selected date range (default: last 30 days).
Dashboard: Traffic Sources
The Traffic page shows where your visitors come from, broken down by:
- Source / Medium — e.g. google / organic, twitter / social, newsletter / email
- Pie chart — visual breakdown of top 8 sources by session count
- Top Pages — most viewed pages with view counts and unique visitors
Traffic sources are determined by UTM parameters first, then by referrer domain matching. Direct visits (no referrer, no UTM) are attributed as direct / none.
Dashboard: Events
The Events page lists all tracked event names with their total count and unique user count. A bar chart visualizes the distribution of the top 15 events. Use this to understand which features and actions are most popular.
Dashboard: Funnels
Funnels let you measure conversion through an ordered sequence of events. For example: page_view → signup → subscription_started.
To create a funnel:
- Click "Create Funnel" and give it a name
- Enter the event names as comma-separated steps (minimum 2 steps)
- Click the funnel to see the analysis with conversion rates and drop-off at each step
Funnel analysis checks ordered completion: a user must complete step 1 before step 2, etc. The visualization shows horizontal bars with percentage conversion and drop-off counts.
Dashboard: Retention
The Retention page shows a weekly cohort retention table. Each row represents a group of users who were first seen in a given week. The columns show what percentage returned in subsequent weeks.
Cells are color-coded from light (low retention) to dark indigo (high retention). This helps you quickly spot whether product changes are improving or hurting long-term engagement.
Dashboard: User Journeys
The Users page shows a paginated list of all tracked users with their first seen date, last activity, total events, and session count. Click on any user to see their full event timeline.
The User Journey view shows a chronological timeline of every event that user performed, including:
- Event name and timestamp
- Page path
- Traffic source (if not direct)
- Event properties (as expandable JSON)
Dashboard: Real-time
The Real-time page auto-refreshes every 10 seconds and shows:
- Active Users — users who sent an event in the last 5 minutes
- Events/Min — event throughput in the last minute
- Active Pages — which pages currently have active users
- Recent Events — live stream of the latest events as they come in
SDK: Web Vitals
The SDK automatically measures Core Web Vitals using the browser's PerformanceObserver API. Five key metrics are captured: LCP (Largest Contentful Paint), FID (First Input Delay), CLS (Cumulative Layout Shift), FCP (First Contentful Paint), and TTFB (Time to First Byte).
Each vital is sent as a web_vital event with the following properties:
| Parameter | Type | Required | Description |
|---|---|---|---|
| metric | string | required | Metric name (LCP, FID, CLS, FCP, TTFB) |
| value | number | required | Metric value in milliseconds (or unitless for CLS) |
| path | string | required | Page path where the measurement was taken |
Measurements are collected 1 second after page load to allow the browser time to finalize the metrics. No configuration is needed — Web Vitals tracking is automatic whenever the SDK loads.
SDK: Session Replay
Session Replay records user interactions so you can replay exactly what a visitor did on your site. Enable it by adding data-replay="true" to the script tag:
<script
src="https://api.singleanalytics.com/sa.js"
data-api-key="YOUR_API_KEY"
data-host="https://your-api-host.com/api"
data-replay="true"
defer
></script>You can also control replay programmatically:
// Start recording
sa.startReplay();
// Stop recording
sa.stopReplay();Session Replay captures the following interactions:
- Mouse movements and cursor position
- Clicks (element, coordinates, timestamp)
- Scroll position changes
- Input field changes (text, select, checkbox)
- Window resize events
type="password" or type="email" have their values masked with *** before data leaves the browser.Replay data is sent as $replay events and flushed to the server every 10 seconds.
SDK: Heatmaps
Heatmaps visualize where users click and how far they scroll. Enable heatmap collection by adding data-heatmap="true" to the script tag:
<script
src="https://api.singleanalytics.com/sa.js"
data-api-key="YOUR_API_KEY"
data-host="https://your-api-host.com/api"
data-heatmap="true"
defer
></script>Or control heatmap recording programmatically:
// Start heatmap recording
sa.startHeatmap();
// Stop heatmap recording
sa.stopHeatmap();Heatmap tracking records:
- Click positions — normalized to percentage coordinates relative to the viewport
- Scroll depth — maximum scroll percentage, reported when the user exits the page
Data is sent as $heatmap events and flushed every 30 seconds.
SDK: Error Tracking
The SDK automatically captures JavaScript errors by listening to window.onerror and unhandledrejection events. No configuration is needed — error tracking is always active.
Each error is sent as a js_error event with these properties:
| Parameter | Type | Required | Description |
|---|---|---|---|
| message | string | required | Error message |
| filename | string | required | Source file where the error occurred |
| line | number | required | Line number |
| column | number | required | Column number |
| stack | string | required | Stack trace (truncated to 500 characters) |
js_error event name.Full Script Tag Example
Here is a complete script tag with all available data-* attributes enabled:
<script
src="https://api.singleanalytics.com/sa.js"
data-api-key="YOUR_API_KEY"
data-host="https://your-api-host.com/api"
data-replay="true"
data-heatmap="true"
defer
></script>This single tag gives you page view tracking, custom events, user identification, SPA support, Web Vitals, session replay, heatmaps, and error tracking — all out of the box.
Dashboard: Geography
The Geography page provides a country-level breakdown of your visitors. For each country you can see:
- Users — unique visitors from that country
- Sessions — total sessions originating from that country
- Page Views — total page views from that country
Click on any country row to drill down to city-level data, including region and country context. The standard date range picker and filter controls are available to narrow results.
Dashboard: Devices
The Devices page breaks down your audience by technology. You get separate views for:
- Device Type — desktop, mobile, and tablet split
- Browser — Chrome, Safari, Firefox, Edge, etc.
- Operating System — macOS, Windows, iOS, Android, Linux, etc.
- Screen Resolution — common viewport sizes
Each breakdown includes pie charts for quick visual comparison and percentage breakdowns in a sortable table.
Dashboard: Campaigns
The Campaigns page shows UTM campaign performance in a sortable table. Columns include:
- Campaign Name — from
utm_campaign - Source — from
utm_source - Medium — from
utm_medium - Users — unique visitors attributed to this campaign
- Sessions — total sessions from this campaign
- Events — total events generated by campaign visitors
Use this page to measure the effectiveness of your marketing campaigns and compare acquisition channels.
Dashboard: Web Vitals
The Web Vitals dashboard visualizes your site's Core Web Vitals performance. Each metric is displayed with a color-coded rating:
- LCP (Largest Contentful Paint) — loading performance
- FID (First Input Delay) — interactivity
- CLS (Cumulative Layout Shift) — visual stability
- FCP (First Contentful Paint) — perceived load speed
- TTFB (Time to First Byte) — server responsiveness
Ratings follow the standard thresholds: green (good), amber (needs improvement), and red (poor). Track trends over time to ensure your site stays fast.
Dashboard: Goals
Goals let you define target outcomes and track progress. To create a goal:
- Navigate to the Goals page and click "Create Goal"
- Give the goal a name, choose the event that counts as a completion
- Optionally set a target value and currency for revenue tracking
Once created, the goal dashboard shows:
- Completions — how many times the goal event was triggered
- Revenue — total revenue if a currency is configured
- Conversion Rate — completions relative to total sessions
- Timeseries — goal completions plotted over time
Dashboard: A/B Testing
Run controlled experiments directly from your dashboard. To create an experiment:
- Navigate to A/B Testing and click "Create Experiment"
- Define two or more variants with traffic weight percentages (e.g. 50/50)
- Choose a goal event that counts as a conversion
- Start the experiment and let traffic accumulate
The results page shows conversion rates per variant, total conversions, and the number of users assigned to each variant. Variant assignment is deterministic — a user always sees the same variant.
Dashboard: Segments
Segments let you create dynamic groups of users based on condition rules. For example, you can define a segment for "Power Users" as users who triggered more than 50 events in the last 30 days.
Each segment is defined by one or more conditions that filter on event properties, user traits, or behavioral patterns. After creating a segment, click "Evaluate" to see the list of matching users and their count.
Dashboard: Alerts
Set up automated alerts to get notified when a metric crosses a threshold. To create an alert:
- Navigate to Alerts and click "Create Alert"
- Choose a metric (e.g. daily active users, error count, bounce rate)
- Set a condition: above or below a threshold value
- Choose a notification channel: email or webhook
When the alert condition is met, you receive a notification with the current metric value and the threshold that was exceeded. Alerts are evaluated periodically against your analytics data.
Dashboard: Privacy & GDPR
SingleAnalytics is designed with privacy in mind. The Privacy settings page lets you configure:
- Data Retention — configure how long event data is stored before automatic deletion
- IP Anonymization — toggle to strip or hash IP addresses before storage
- Cookieless Tracking — enable fully cookieless mode using localStorage-only identifiers
- Do Not Track — respect the browser's DNT header (enabled by default)
For GDPR compliance, SingleAnalytics also supports:
- Right to Erasure — delete all data for a specific user by user ID
- Right to Access — export all data for a specific user as a downloadable file
Data Model: Events
Every tracked action creates an event document with these fields:
{
projectId: ObjectId, // Project this event belongs to
eventName: String, // "page_view", "signup", "purchase", etc.
userId: String, // Anonymous ID or identified user ID
sessionId: String, // Session identifier
properties: Object, // Arbitrary key-value metadata
url: String, // Full page URL
path: String, // URL pathname (e.g. "/pricing")
title: String, // Document title
referrer: String, // Referrer URL
source: String, // Traffic source (e.g. "google")
medium: String, // Traffic medium (e.g. "organic")
campaign: String, // UTM campaign name
browser: String, // Detected browser (e.g. "Chrome")
os: String, // Operating system (e.g. "macOS")
device: String, // "desktop", "mobile", or "tablet"
country: String, // Geo from CF-IPCountry header
timestamp: Date // When the event occurred
}Compound indexes exist on (projectId, timestamp), (projectId, eventName), (projectId, userId), and (projectId, sessionId) for fast queries.
Data Model: Sessions
Sessions group events from a single visit. A new session is created when a user has been inactive for more than 30 minutes. Session documents track:
{
projectId: ObjectId,
sessionId: String, // Matches the sessionId in events
userId: String,
startedAt: Date,
lastActivityAt: Date,
duration: Number, // Seconds
pageviews: Number, // Count of page_view events
events: Number, // Total event count
source: String, // Acquisition source
medium: String,
campaign: String,
device: String,
browser: String,
os: String,
country: String,
landingPage: String, // First page path
exitPage: String, // Last page path
isActive: Boolean // Active in last 5 minutes
}Traffic Attribution
Traffic source attribution follows a priority-based system:
- UTM parameters — If the URL contains
utm_source, it takes highest priority. Theutm_mediumandutm_campaignvalues are also captured. - Referrer detection — If no UTM params, the referrer URL is analyzed. Known domains are mapped to sources:
- google.* → google / organic
- facebook.com, fb.com → facebook / social
- twitter.com, t.co → twitter / social
- linkedin.com → linkedin / social
- youtube.com → youtube / social
- tiktok.com → tiktok / social
- Other referrers → domain / referral
- Direct — If neither UTM params nor a referrer are present, the visit is classified as
direct / none.
Need help? Reach out at support@singleanalytics.com or visit the dashboard to get started.