Skip to main content

Overview

Loom’s analytics system provides PostHog-style product analytics for tracking user behavior, running experiments, and analyzing conversion funnels. The system supports both anonymous and identified users with automatic identity resolution.
Analytics integrates with feature flags to automatically track flag exposures for experiment analysis.

Key Features

  • Person profiles for anonymous and identified users
  • Event tracking with flexible properties
  • Identity resolution linking anonymous sessions to authenticated users
  • Multi-tenant analytics scoped to organizations
  • API keys for client-side (write-only) and server-side (read/write) access

Core Concepts

Person

A person represents a user being tracked, identified by one or more distinct_id values:

Event

Events track user actions with an event name, distinct ID, and optional properties:
Event naming conventions:
  • Lowercase alphanumeric with _, $, or .
  • Must start with lowercase letter or $ (for system events)
  • Maximum 200 characters
  • Examples: button_clicked, $pageview, checkout.completed

Identity Resolution

Loom uses PostHog’s identity model:
1

Anonymous user arrives

SDK generates UUIDv7, stored in localStorage/cookie as distinct_id
2

Events captured

All events tagged with this anonymous distinct_id
3

User identifies

SDK calls identify(anonymous_id, user_id) with real identifier
4

Merge occurs

Both distinct_ids linked to same Person, properties merged
5

Future events

Can use either distinct_id, both resolve to same Person

Rust SDK

Install the SDK:

Basic Usage

TypeScript SDK

Install the SDK:

Browser Usage

Special Events

System events use the $ prefix:

Person Properties vs Event Properties

Person Properties

Persistent attributes attached to the PersonExamples: email, plan, companySet via identify() or set()

Event Properties

Ephemeral data for a single eventExamples: button_name, page_url, order_valueSet via capture() properties parameter

API Keys

Use Write-only keys for client-side code (safe to expose). Use Read/Write keys only server-side.

Creating API Keys

API Endpoints

Capture Events

POST /api/analytics/capture
endpoint
Capture a single eventRequest:
POST /api/analytics/batch
endpoint
Capture multiple events in one requestRequest:

Identity Operations

POST /api/analytics/identify
endpoint
Link anonymous distinct_id to authenticated userRequest:
POST /api/analytics/alias
endpoint
Link two distinct_ids togetherRequest:
POST /api/analytics/set
endpoint
Update person propertiesRequest:

Query APIs

Query endpoints require a Read/Write API key.
GET /api/analytics/persons
endpoint
List persons for organizationQuery Parameters:
  • limit - Max results (default: 100)
  • offset - Pagination offset
GET /api/analytics/persons/by-distinct-id/:distinct_id
endpoint
Get person by distinct_idResponse:
GET /api/analytics/events
endpoint
Query events with filtersQuery Parameters:
  • event_name - Filter by event name
  • distinct_id - Filter by distinct_id
  • start_date - Start timestamp (ISO 8601)
  • end_date - End timestamp (ISO 8601)
  • limit - Max results

Experiment Integration

Analytics automatically tracks feature flag exposures for A/B testing:
Query experiment results by joining flag exposures with conversion events:

Validation & Limits

Events that exceed validation limits will be rejected.

Best Practices

Use Descriptive Names

Event names should be clear and consistent:checkout_completed, video_playedaction_1, event, click

Property Consistency

Use consistent property names across events:✅ Always use page_url for URLs❌ Mix url, page, page_url

Reset on Logout

Call analytics.reset() when users log out to start fresh session

Client-Side Keys

Only use Write API keys in client-side code (safe to expose publicly)

See Also

Crash Tracking

Link crashes to person profiles

Sessions

Track user engagement periods