05

API Tracking

Track API endpoint usage, latency, error rates, and caller patterns with Express middleware or manual calls.

Express middleware
import { BetterMeter } from "@bettermeter/node";
import express from "express";

const bm = new BetterMeter({
  siteId: "my-api",
  apiKey: "bm_...",
});

const app = express();

// Auto-track all requests
app.use(bm.expressMiddleware());
Manual tracking
bm.trackApi({
  method: "POST",
  endpoint: "/api/users",    // Use patterns, not actual paths with IDs
  statusCode: 201,
  durationMs: 45,
});

What gets tracked

HTTP method, endpoint pattern, status code, and duration. Request/response bodies, headers, query parameters, and path parameters are never sent. Use endpoint patterns (/api/users/:id) not actual paths (/api/users/abc123).

09

API Reference

All analytics endpoints accept GET requests with query parameters. Authenticate with Authorization: Bearer <api_key>.

Event Ingestion

POST /api/eventIngest an event (web, CLI, MCP, or API). Returns 202.

Web events must reference a registered site and the event URL must match that site domain. CLI, MCP, and API events require Authorization: Bearer [api_key]; forwarded user-agent and client-IP headers are trusted only after that key is validated for the site.

Event payload
{
  "site_id": "example.com",
  "event_name": "pageview",        // or "cli.command", "mcp.tool", "api.request"
  "event_source": "web",           // "web" | "cli" | "mcp" | "api"
  "url": "https://example.com/page",
  "pathname": "/page",
  "hostname": "example.com",
  "referrer": "https://google.com",
  "screen_width": 1920,
  "timezone": "America/New_York",
  "user_id": "optional_user_id",
  "properties": { "key": "value" }
}

Signup Interest

POST /api/waitlistCapture public waitlist submissions and email farbour@paraito.ca for each new lead. The alert includes clearly labeled name and organization clues derived from the address, account status, same-domain interest, and a link to the admin record. Duplicate submissions do not send another alert.

Real-Time & Heartbeat

GET /api/analytics/live?activity=1&cursor=…Live visitor count. Add activity=1 for recent human events, active visitor IDs, goal definitions, and a resumable cursor. Accepts ?siteId=...
POST /api/heartbeatReceive browser heartbeats for live visitor tracking
POST /api/hStealth alias for /api/heartbeat (ad-blocker resistant)

Query Endpoints

All accept ?siteId=...&from=YYYY-MM-DD&to=YYYY-MM-DD. List endpoints also accept limit=all when you need the complete set for pagination or search.

Human-traffic endpoints exclude known and high-confidence automated traffic by default. Pass includeBots=true for unfiltered totals. Overview responses include trafficFilter counts so the exclusion is auditable.

Web Analytics

GET /api/analytics/overviewVisitors, pageviews, sessions + % change and hasPreviousPeriodData for empty comparison windows
GET /api/analytics/pages?limit=allPages by visitor count. Add limit=all to return the full searchable list.
GET /api/analytics/sources?limit=allTraffic sources with AI detection
GET /api/analytics/timeseriesDaily visitor/pageview trend
GET /api/analytics/ai-trafficAI referral breakdown by platform
GET /api/analytics/bots?limit=allBot/crawler traffic
GET /api/analytics/countries?limit=allVisitors by country
GET /api/analytics/devicesDevice type breakdown
GET /api/analytics/browsers?limit=allBrowser breakdown
GET /api/analytics/visitors?limit=allVisitor list with activity
GET /api/analytics/visitors/[visitorId]Person profile with first-touch attribution, sessions, lifecycle, and event timeline
PATCH /api/analytics/visitors/[visitorId]Update the person's identity and lifecycle (Editor or Admin)
GET /api/analytics/visitors/[visitorId]/propertiesRead every key/value property on a visitor, with the source that wrote each
PATCH /api/analytics/visitors/[visitorId]/propertiesWrite or delete visitor properties; a null value deletes the key (Editor or Admin)
POST /api/visitor-propertiesPublic endpoint used by the tracker's setProperties(); the visitor is derived from the request, never supplied by the caller
GET /api/analytics/events?limit=allCustom events
GET /api/analytics/campaigns?limit=allAutomatically captured campaign URL attribution (UTM + click IDs)
GET /api/analytics/campaigns/[campaign]Single campaign detail — visit quality (bounce rate, avg duration, quality score vs. site average), variant/keyword performance, device/browser/country breakdowns, hourly pattern, custom events
GET /api/analytics/campaigns/[campaign]/visitorsThe people one campaign brought in, with each visitor's landing page, variant, device, country and post-click activity
GET /api/analytics/keywords?limit=allKeywords (utm_term) aggregated across campaigns with visit quality (bounce rate, avg duration) and campaign/source attribution
GET /api/analytics/marketingMarketing performance: campaigns, landing pages, channel mix, campaign vs non-campaign traffic
GET /api/analytics/channelsChannel breakdown
GET /api/analytics/session-statsSession statistics
GET /api/analytics/sessions?limit=allSession list

CLI Analytics

GET /api/analytics/cli-overviewInvocations, callers, success rate
GET /api/analytics/cli-commands?limit=allTop commands
GET /api/analytics/cli-timeseriesDaily CLI activity

MCP Analytics

GET /api/analytics/mcp-overviewInvocations, callers, success rate
GET /api/analytics/mcp-tools?limit=allTop tools
GET /api/analytics/mcp-clients?limit=allClient breakdown
GET /api/analytics/mcp-timeseriesDaily MCP activity

API Analytics

GET /api/analytics/api-overviewInvocations, callers, error rate
GET /api/analytics/api-endpoints?limit=allTop endpoints
GET /api/analytics/api-timeseriesDaily API activity

Conversion Goals

GET /api/analytics/goalsList all conversion goals with conversions, unique converters, and conversion rates
POST /api/analytics/goalsCreate a new conversion goal (pageview URL, custom event, outbound link, or download)
GET /api/analytics/goals/[goalId]Get human-only current/prior evolution, stable converters, first-touch acquisition, exposed-visitor efficiency, and momentum; includeBots=true opts into automation
PATCH /api/analytics/goals/[goalId]Update a conversion goal definition
DELETE /api/analytics/goals/[goalId]Delete a conversion goal
GET /api/analytics/goals/suggestAnalyze traffic patterns and suggest high-value conversion targets

Builder

GET /api/builders/dashboardsList saved custom dashboards for a site and its left-nav dashboard menu
POST /api/builders/dashboardsCreate a custom dashboard
GET /api/builders/dashboards/[dashboardId]Get one custom dashboard
PATCH /api/builders/dashboards/[dashboardId]Update a custom dashboard
DELETE /api/builders/dashboards/[dashboardId]Delete a custom dashboard
GET /api/builders/reportsList saved report templates
POST /api/builders/reportsCreate a report template
GET /api/builders/reports/[reportId]Get one report template
PATCH /api/builders/reports/[reportId]Update a report template
DELETE /api/builders/reports/[reportId]Delete a report template
POST /api/builders/reports/previewPreview a report outline

Search Rankings and AI Visibility

GET /api/analytics/brandSearch rankings visibility report
GET /api/analytics/brand/historyHistorical ranking data
GET /api/analytics/brand/compareCompetitor comparison
GET /api/analytics/brand/alertsRanking alert rules
GET /api/analytics/brand/exportExport ranking data
GET /api/analytics/backlinksBacklink profile
GET /api/analytics/ai-mentionsAI chatbot brand mentions
GET /api/analytics/ai-mentions/historyAI mention history

Pulse AI

GET /api/pulse/insightsAnomalies, trends, opportunities, and domain shifts
GET /api/pulse/healthProduct health score (0-100)
GET /api/pulse/briefingDaily or weekly briefing
GET /api/pulse/forecastTraffic/usage forecast
GET /api/pulse/comparePeriod comparison
GET /api/pulse/alertsList monitoring alerts
POST /api/pulse/alertsCreate alert rule
DELETE /api/pulse/alertsDelete alert rule
GET /api/pulse/notificationsGet notifications
PATCH /api/pulse/notificationsMark notifications as read
POST /api/pulse/chatStreaming Pulse chat with adaptive, linked visitor-level answers
GET /api/pulse/conversationsList your Pulse conversation threads for a site
POST /api/pulse/conversationsStart a new Pulse conversation thread
GET /api/pulse/conversations/[id]One thread with its full message history
PATCH /api/pulse/conversations/[id]Rename a conversation thread
DELETE /api/pulse/conversations/[id]Delete a conversation and its messages
GET /api/pulse/screenshotCapture a landing page on your own site as an authenticated, same-origin image
GET /api/analytics/ad-spendCampaign spend joined to tracked traffic
GET /api/integrations/adsList connected ad accounts for a site
POST /api/integrations/adsConnect a Meta ad account with a system user token
POST /api/integrations/ads/syncPull ad spend now instead of waiting for the nightly sync