Skip to Content
DocsQuickstartCore Concepts

Core Concepts

Shared vocabulary used across the dashboard, SDKs, and API. Read this once — every other doc page builds on these ideas.

Organization and project

Pug is multi-tenant. Your data always lives inside a project; projects belong to an organization.

Organization ← billing & member boundary ├── Members (roles) └── Project ← data boundary ├── API keys (SDK + shared) ├── Events ├── Profiles └── Dashboards
ConceptWhat it isScope
OrganizationTeam workspace with members and billingAll projects in the org
ProjectIsolated analytics environmentEvents, profiles, dashboards
API keyCredential for SDK or server integrationsSingle project

Every dashboard URL is prefixed with the active project: /p/:projectId/…. SDK requests include the project ID in the x-project-id header.

Event pipeline

When your app calls track(), the event travels through an async pipeline before it appears in analytics.

SDK (browser/app) │ track('purchase', { revenue: 29.99 }) EventsService.BatchCreate ← Connect RPC, API key auth NATS (message queue) Event workers ← geo, user agent, bot score enrichment ClickHouse ← analytics storage Dashboard & InsightsService ← queries, charts, KPIs

Timing: Ingestion is near-real-time. Events typically appear in Live within seconds and in Insights queries within the same minute. Profile writes are fully async — see Profiles below.

Events

An event is a named occurrence with properties and a timestamp.

track('button_clicked', { label: 'Sign up', page: '/pricing' })
  • Event name — any string; well-known events have typed schemas
  • Properties — arbitrary key-value pairs (strings, numbers, booleans)
  • Auto-properties — SDK and server attach fields prefixed with $ (e.g. $url, $geo.country). See Auto-properties
  • Timestamp — defaults to client time; override for offline replay

Events are immutable once stored. Corrections require a new event or profile trait update.

Profiles

A profile represents a user — anonymous or identified.

Anonymous → identified flow

  1. Visitor lands on your site. SDK creates an anonymous profile tied to a device/session.
  2. Events accumulate against that anonymous ID.
  3. User signs in. You call identify('user-123', { email: '…' }).
  4. Prior anonymous events merge into the identified profile.
// Before sign-in — events are anonymous track('page_view') track('add_to_cart', { product_id: 'sku-123' }) // After sign-in — merges anonymous history identify('user-123', { email: 'user@example.com', plan: 'pro' }) track('purchase', { revenue: 29.99, currency: 'USD' })

Alias

Alias merges two profile IDs — useful when a user had separate anonymous sessions before and after signup, or when migrating from another system:

anonymous-id-abc ──alias──▶ user-123 pre-migration-id ──alias──▶ user-123

Alias is server-side via ProfilesSDKService. See Profiles API.

Storage model

  • Writes — async via NATS profile workers (identify, trait upsert, alias)
  • Reads — ClickHouse (event-derived traits and history) + Postgres (soft-delete state)
  • Expect a few seconds of lag between identify() and profile appearing in search

Sessions

A session groups events within a single visit. SDKs manage session IDs automatically:

  • New session on first event after timeout (default 30 minutes of inactivity)
  • Session extended on each event within the window
  • Web SDK syncs session ID across browser tabs via localStorage

Force a new session without clearing identity: rotate(). Clear identity and session: reset().

Insights

An insight is a query specification — not a saved chart, but the definition of one:

FieldExample
Eventspage_view, purchase
Time rangeLast 7 days
GranularityDay
AggregationUnique users
Breakdown$geo.country
Filtersplan = 'pro'

The same insight model powers:

  • Overview KPI tiles
  • Insights ad-hoc queries
  • Dashboard tiles
  • InsightsService API queries

Example mental model — “daily unique purchasers by country”:

Events: purchase Range: last 30 days Granularity: day Aggregation: unique users Breakdown: $geo.country

Dashboards

A dashboard is a saved grid of tiles. Each tile is either:

  • Insight tile — bound to an insight query spec (line chart, KPI, funnel, etc.)
  • Markdown tile — free-form notes, links, or runbook text

Dashboards are project-scoped. Tile changes use a full-reconcile upsert — the saved payload is the complete desired state.

Authentication modes

Pug has three auth boundaries. Pick the one that matches your integration:

ModeUsed byAccess
JWTDashboard usersRead/write project data via UI
SDK API keyClient SDKsWrite events, identify
Shared key / JWTServer integrationsInsights, profile reads
Browser SDK ──▶ SDK API key ──▶ EventsService, ProfilesSDKService Dashboard ──▶ JWT ──▶ DashboardsService, ProjectsService, OrgsService Your server ──▶ Shared key ──▶ InsightsService, ProfilesService

See Authentication for headers and examples.

Further reading

Last updated on