CLI Tracking
Track how developers use your CLI tool. See which commands are popular, how long they take, and what errors occur -- without collecting PII.
npm install @bettermeter/nodeimport { BetterMeter } from "@bettermeter/node";
import { Command } from "commander";
const bm = new BetterMeter({
siteId: "my-cli-tool",
apiKey: "bm_...",
});
const program = new Command();
// Wraps all commands — tracks name, flags, exit code
bm.wrapCommander(program, { version: "1.0.0" });
program.command("deploy").action(() => { /* ... */ });
program.parse();
// Flush on exit
process.on("SIGTERM", () => bm.shutdown());bm.trackCommand({
command: "deploy",
subcommand: "preview",
flags: ["--prod", "--verbose"],
version: "2.1.0",
durationMs: 4500,
exitCode: 0,
isCi: !!process.env.CI,
});What gets tracked
Command names and flag names only. Flag values, arguments, and file paths are never sent. The SDK captures OS and architecture for environment analytics.
CLI Reference
The BetterMeter CLI lets you query analytics from the terminal with beautiful visual output. All commands accept -r/--range and --json, and every one but all-sites also accepts -s/--site — that one is account-wide and takes no site. -l/--limit applies only to the commands that return a ranked list.
npm install -g bettermeter
bettermeter login -t <apiKey> -u https://bettermeter.comOutput Formats
By default, the CLI renders rich visual output with ASCII art charts, colored text, sparklines, and box-drawn stat cards. All output uses Unicode characters compatible with every modern terminal. Colors auto-detect terminal capabilities and respect the NO_COLOR environment variable.
Default (visual)Line charts, bar charts, sparklines, styled tables with color--jsonRaw JSON data -- ideal for scripting, piping to jq, or programmatic useVisual output includes:
- Line charts for timeseries data (daily visitors, invocations)
- Horizontal bar charts for ranked lists (pages, sources, countries)
- Sparklines inline with overview stats for quick trend visualization
- Box-drawn stat cards with colored change indicators for overviews
- Styled tables with box-drawing borders for detailed data
# Visual output (default)
bettermeter stats -s example.com
# JSON output for scripting
bettermeter stats -s example.com --json | jq '.visitors'Authentication
login -t <key> -u <url>Authenticate with API key and dashboard URLlogoutRemove stored credentialswhoamiShow current authenticated userReal-Time
live -s <siteId> [--activity] [--cursor <cursor>] [--json]Live visitor count, or add --activity for the recent human event feed and --cursor for incremental polling (--json for raw output)live:screen -s <siteId> [--json]Print the authenticated Big Screen URL for the rewindable live visitor display and its 30-minute activity timeline (--json for structured output)Portfolio
all-sites [-r <range>] [--json]Traffic for every site you can access, side by side: visitors, pageviews, sessions and custom events per site, each site's period-over-period visitor change, and the account-wide totals. Takes no -s/--siteWeb Analytics
Human-traffic commands exclude known bots, explicit headless automation, and high-confidence scraper cohorts by default. Add --include-bots to stats, pages, sources, timeseries, AI traffic, countries, devices, browsers, sessions, session-stats, channels, goals, goal:show, or goals:suggest to include them.
-l/--limit is accepted by the commands that return a ranked list: pages, sources, bots, countries, browsers, visitors, sessions, events, campaigns, conversions, keywords, campaign:visitors, export, cli-commands, mcp-tools, mcp-clients, and api-endpoints. It has no default of its own: omit it and the command returns the endpoint's own default page, which differs per dataset — today visitors returns 50 rows where pages returns 10 — and the flag is how you ask for a specific number. The summary, trend, and detail commands do not accept it — stats, ai-traffic, timeseries, devices, channels, marketing, ads, campaign, event, and the cli, mcp, and api overview and timeseries commands. On sources --filter and bots --category the limit is applied before the filter, so a filtered result can hold fewer rows than the limit.
statsOverview: visitors, pageviews, sessions + % change, or a new-baseline state when the previous period is emptypagesTop pages by visitor countsourcesTraffic sources (--filter all|ai|traditional)ai-trafficAI referral breakdown by platformbotsBot/crawler traffic (--category all|ai-crawler|search|monitoring|scraper)timeseriesDaily visitor/pageview trendcountriesVisitors by countrydevicesDevice breakdownbrowsersBrowser breakdownvisitorsPeople with their event source (web / CLI / MCP / API / bot) and its detail, plus first-touch source, campaign, repeat visits, and lifecyclesessionsEvery session with duration, pages, events, entry to exit path, engagement tier, and bounce, under period totalsvisitor <visitorId>One person's profile, first touch, sessions, and event timelinevisitor:update <visitorId>Set an opaque user ID, display name, or visitor/customer lifecycle statusvisitor:properties <visitorId>List the key/value properties stored on a visitorvisitor:tag <visitorId>Set or remove arbitrary key/value properties on a visitorvisitor:findFind a visitor by email, CRM contact id, or exact property key/valueeventsCustom events with countsevent <name>One custom event in depth: total fires, unique visitors, property value breakdown, recent firescampaignsAutomatically captured campaign URL attribution (UTM + click IDs)campaign <name>Detailed campaign report (quality, variants, breakdowns)campaign:visitors <name>Everyone one campaign brought in: who clicked, the page they landed on, their variant, device and country, and what they did afterwardskeywordsKeywords driving traffic (utm_term, with visit quality)marketingFull marketing report: campaigns, landing pages, channel mixscreenshot <path>Capture one landing page and save it as an image (--site, optional --output)channelsChannel breakdown (Direct, Paid Search, Organic, etc.)exportFull report (--format json|csv|md)CLI Analytics
cli-overviewInvocations, callers, success rate, avg durationcli-commandsTop commands by invocation countcli-timeseriesDaily CLI activityMCP Analytics
mcp-overviewInvocations, callers, success rate, avg durationmcp-toolsTop MCP tools by invocation countmcp-clientsClient breakdown (Claude, Cursor, etc.)mcp-timeseriesDaily MCP activityAPI Analytics
api-overviewInvocations, callers, error rate, avg durationapi-endpointsTop endpoints by invocation countapi-timeseriesDaily API activityBuilder
dashboardsList saved custom dashboard layouts shown in the dashboard left navdashboard:createCreate a custom dashboard layout, including the Editor/Admin-only paidPerformance Meta widgetdashboard:update -i <id>Update a custom dashboard layout (only the flags you pass change)dashboard:deleteDelete a custom dashboard layoutreportsList saved report templatesreport:createCreate a report template, including the Editor/Admin-only paidMedia sectionreport:previewPreview a report with live Meta delivery when paidMedia is enabledreport:update -i <id>Update a report template (only the flags you pass change)report:deleteDelete a report templatePulse AI
pulse askAsk Pulse anything — including linked visitor journeys behind recent conversionspulse threadsList your saved Pulse conversations for a siteadsMeta spend and link clicks compared with compatible tracked campaign trafficad-creativeThe ad behind a visit, or every ad in a campaign; --utm-content resolves one exact creativeads:syncPull ad spend from connected ad accounts nowconversionsCRM records carrying one of our ad click IDs, with matched, unmatched and awaiting-upload counts (--won for closed only)ad-connections -s <siteId>Connected ad accounts for a site and their sync healthcrmConnected CRMs for a site and their sync healthcrm:syncPull CRM conversions now instead of waiting for the next scheduled sync (--full to re-read everything)slackSlack channels wired to this site's Pulse alerts, with delivery healthslack:connectConnect a Slack Incoming Webhook; a test message is posted before it is storedslack:testPost to a connected channel now, to prove the webhook still worksslack:updateEnable, disable, rename or re-threshold a connected channelslack:removeDisconnect a Slack channel; alerts already recorded are keptpulse threadReplay one Pulse conversation as a transcriptpulse thread-deleteDelete a Pulse conversationpulse insightsAnomalies, trends, milestones, and campaign, channel, geography, conversion and engagement shiftspulse healthProduct health score (0-100, grade A-F)pulse briefingDaily/weekly briefing (-p/--period daily|weekly)pulse forecastTraffic forecast (-m/--metric, -d/--days)pulse compareCompare two periods (-r/--range, --from2, --to2)pulse alertsList monitoring alert rulespulse alerts:createCreate alert (-t/--type, -n/--name, -c/--condition)pulse alerts:deleteDelete an alert (-i/--id)pulse notificationsRecent notifications (--unread for unread only)Search Rankings and AI Visibility
brand-report <domain>Generate search rankings report (-q/--queries)brand-config <domain>View/update brand monitoring configbrand-compare <domain>Compare rankings vs competitors (-q, -c)brand-alerts <domain>Manage ranking alerts (-a list|create|delete|enable|disable)ai-mentions <domain>AI chatbot brand mentions (-q/--queries, -p/--providers)ai-mentions:history [domain]Stored AI mention scans, newest first — reads history, never runs a paid scanbacklinks <domain>Backlink profile: domain rank, referring domainsPaid external scans accept 1-10 queries per request. Competitor comparison accepts up to 10 competitors.
Conversion Goals
goals -s <siteId> [--include-bots]List human conversion goals, stable converters, rates, and momentumgoal:show -s <siteId> -g <goalId> [--include-bots]Compare current/prior evolution, first-touch acquisition, exposed-visitor efficiency, and momentumgoal:create -s <siteId> -n <name>Create a conversion goal (pageview URL, custom event, outbound link, or download)goal:update -s <siteId> -g <goalId>Update a conversion goal — rename, retarget, revalue or archive itgoal:delete -s <siteId> -g <goalId>Delete a conversion goalgoals:suggest -s <siteId> [--include-bots]Analyze human traffic and suggest high-value conversion targets with rationalesSite Management
sites listList all sitessites add <domain>Add a new site — sign in to the dashboard; an API key cannot create sitessites remove <siteId>Remove a site — sign in to the dashboard; an API key cannot delete sitessites info <siteId>Show site details and tracking snippetsites update <siteId> --currency <code>Set the display currency (ISO 4217 code, defaults to CAD)install <siteId>Get tracker snippet for a siteTeam Management
members list -s <siteId>List site membersmembers add <email>Add a member (-s, -r viewer|editor|admin, --all-sites)members remove <id>Remove a member (-s)invitation:cancel <id>Cancel a pending invitation (-s), before it is acceptedmembers update-role <id>Update member role (-s, -r)Billing
billingShow current plan, usage, and billing info (--json)Options
-s, --siterequired except all-sites-r, --range-l, --limit--json