# Convalytics
> Free web and product analytics for Convex apps. Agent-friendly HTTP API with a public write key, a Convex backend component for server-side ingest, and an auto-tracking browser script for page views and custom events.
Convalytics is built specifically for apps that run on Convex (https://convex.dev). It gives teams one dashboard for marketing-site page views, in-app product events, user identification, retention, and funnels, without requiring a paid plan to get started.
## Canonical URLs
- Site: https://convalytics.dev
- API base: https://api.convalytics.dev
- OpenAPI spec: https://convalytics.dev/openapi.json
- Agent setup manual: https://convalytics.dev/llms.txt
- This full manual: https://convalytics.dev/llms-full.txt
- Pricing: https://convalytics.dev/pricing.md
- Sitemap: https://convalytics.dev/sitemap.xml
- robots.txt: https://convalytics.dev/robots.txt
- Source: https://github.com/Dan-Cleary/convalytics
- License: MIT
## What's included
- Page views (free, uncounted against quota)
- Custom product events with arbitrary properties
- User identification (anonymous → identified, with email/name for dashboard display)
- Session tracking
- Dashboards: traffic, pages, referrers, UTM, retention, funnels
- CSV export
- Team billing via Stripe
- Quota alerts and rate limiting
- CLI for provisioning, verification, and event inspection
- Convex backend component for server-side ingest without leaking the write key's origin
- Browser auto-tracking script
## Three ways to send events
### 1. Convex backend component (recommended for Convex apps)
Install the component in your Convex project so product events can be emitted from server functions alongside your existing business logic. See https://github.com/Dan-Cleary/convalytics-convex-component and https://convalytics.dev/skill.md for the agent setup guide.
### 2. Browser auto-tracking script
```html
```
This captures page views automatically. For custom events from the browser:
```js
window.convalytics.track("signup_completed", { plan: "pro" });
window.convalytics.identify("user_123", { email: "a@b.com", name: "Alice" });
window.convalytics.reset(); // on logout
```
### 3. Direct HTTP (any language)
```
POST https://api.convalytics.dev/ingest
Content-Type: application/json
{
"writeKey": "wk_...",
"name": "signup_completed",
"userId": "user_123",
"sessionId": "sess_abc",
"timestamp": 1714000000000,
"props": { "plan": "pro" }
}
```
Batch endpoint (up to 100 events per request): `POST /ingest/batch` with `{ writeKey, events: [...] }`.
## MCP server (read-only queries for AI assistants)
Convalytics exposes a Model Context Protocol server at `POST https://api.convalytics.dev/mcp` so Claude Desktop, Claude Code, Cursor, Windsurf, and other MCP-capable clients can answer questions about analytics data in chat. Protocol: JSON-RPC 2.0.
**Auth.** Bearer token, not the write key. Users generate a read-scoped API token at https://convalytics.dev/tokens, then pass it as `Authorization: Bearer cnv_...`. Tokens bind to one team and grant read access to every project on that team.
**Plan requirement.** The MCP endpoint is gated to the Solo ($29/mo) and Pro ($99/mo) plans. API-token creation itself is free on every plan, but the `/mcp` endpoint returns `402 plan_required` for Free-tier teams.
**Environment filter.** Clients can scope an entire MCP session to one environment by setting the `x-convalytics-environment` request header to `production` or `development`. When set, every tool (top_pages, events_count, user_activity, weekly_digest, etc.) auto-filters rows to that environment — matches the Environment toggle on the dashboard. Omit the header to see all events. The Smithery config exposes this as an optional "Environment filter" field at install time.
**Rate limit.** 120 requests per minute per team. Exceeding returns `429 rate_limit_exceeded` with `Retry-After` and `resetAt`.
**Tools (9).** The project-scoped tools all take `project` (the project's case-insensitive name or its id from `list_projects`).
Page views (the automatic hits from the browser script) and custom product events (emitted by `analytics.track()`) live in separate tables. `pageviews_count`, `top_pages`, and `top_referrers` query page views. `events_count` and `recent_events` query custom events. `weekly_digest` combines both at a project level; `user_activity` combines both at a user level.
User identification: four of the tools (`top_pages`, `pageviews_count`, `events_count`, `recent_events`) accept an optional `user` filter, and `user_activity` makes `user` required. `user` accepts either a userEmail (case-insensitive) or a visitorId (exact match — that's the `userId` argument passed to the original `track()` call, stored as `visitorId` on the event row). Identify your users via `convalytics.identify(userId, { email, name })` in the browser or by passing `userEmail` / `userName` to `analytics.track()` server-side, and these queries can then answer "how is this user using my app?" style questions.
- `list_projects`: all projects on the token's team (id, name, writeKey, site URL, Convex deployment slug). Team-scoped, no arguments.
- `get_usage`: this month's custom-event count, monthly quota, retention days, plan name. Team-scoped, no arguments.
- `top_pages({ project, since?, until?, limit?, user? })`: pages ranked by view count with unique visitors and share of total.
- `top_referrers({ project, since?, until?, limit? })`: referring hosts ranked by visits, includes "(direct)".
- `pageviews_count({ project, since?, until?, user? })`: total page views + unique visitors in a window. Use this for "how much web traffic did I get" questions.
- `events_count({ project, name?, since?, until?, user? })`: count of CUSTOM events, optionally filtered by event name and/or user. Does not cover page views.
- `recent_events({ project, name?, limit?, redact?, user? })`: most recent custom events. Default `redact: true` nulls `userEmail`, `userName`, and `props` for PII hygiene; set `redact: false` to include them.
- `user_activity({ project, user, since?, until? })`: composite per-user snapshot — identity block, total pageviews, total events, session count, top pages visited, top event names, and the user's 20 most recent events with props. Prefer this over chaining tools with `user` filters when the agent just wants "how is X using the app?"
- `weekly_digest({ project, days?, compare? })`: composite "how did we do this window?" snapshot. Returns visitors, pageviews, sessions, bounce rate, avg session duration, top 5 pages, top 5 referrers, custom-events total, top 5 event names, plus period-over-period deltas. Default `days: 7`, `compare: true`. Prefer this when the agent just wants to summarize a period rather than chain multiple tools.
Full tool schemas live in the `tools/list` response and at https://convalytics.dev/.well-known/mcp/server-card.json.
**Install in Claude Code:**
```
claude mcp add --transport http convalytics https://api.convalytics.dev/mcp --header "Authorization: Bearer $CONVALYTICS_TOKEN"
```
**Install in Claude Desktop** (edit `claude_desktop_config.json`):
```
{
"mcpServers": {
"convalytics": {
"url": "https://api.convalytics.dev/mcp",
"headers": { "Authorization": "Bearer cnv_..." }
}
}
}
```
Not in v1: `funnel` tool, write/admin tools, OAuth, MCP Apps UI resources, stdio transport. See https://convalytics.dev/mcp for latest details.
## Authentication
Convalytics uses a **public write key** as its sole API credential. It is a scoped, non-secret identifier with these properties:
- Safe to ship in client code, in HTML `