API & MCP
Everything you see in the PageLens dashboard is available as JSON. Use the REST API from scripts and backends, or connect the MCP server so Claude, Cursor and other AI assistants can answer questions about your traffic.
API keys
Create keys in the dashboard under API & MCP. A key acts as you, with the same access you have to each site. When you create one you choose:
- Read only or Read & write. Write keys can also create goals, funnels and annotations, update site settings, add sites and send server-side events.
- All sites or one site.
Keys start with pl_ and are shown once. We store only a hash. Send them in the Authorization header:
Authorization: Bearer pl_your_key
Keys can't manage other keys, billing or members, and can't delete sites. Those actions need a signed-in browser session.
MCP server
Endpoint: https://app.pagelens.io/mcp (Streamable HTTP). Authenticate with an API key.
Claude Code
claude mcp add --transport http pagelens https://app.pagelens.io/mcp \
--header "Authorization: Bearer pl_your_key"
Cursor, Windsurf and other clients with remote-server support
{
"mcpServers": {
"pagelens": {
"url": "https://app.pagelens.io/mcp",
"headers": { "Authorization": "Bearer pl_your_key" }
}
}
}
Claude Desktop
Add this to claude_desktop_config.json (Settings → Developer → Edit config) and restart. Requires Node.js.
{
"mcpServers": {
"pagelens": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://app.pagelens.io/mcp",
"--header", "Authorization: Bearer pl_your_key"]
}
}
}
Tools
| Tool | What it does |
|---|---|
list_sites | Sites the key can access, with visitors in the last 24 hours |
get_overview | Visitors, sessions, pageviews, bounce rate and duration, compared with the previous period, plus a time series |
get_breakdown | Top pages, entry/exit pages, referrers, channels, UTM tags, countries, cities, browsers, OS, devices, languages, events |
get_pages | Per-page visitors, entries, bounce rate and time on page |
get_realtime | Visitors online now and what they're viewing |
list_sessions, get_session | Sessions and the full timeline of one session |
get_events | Custom events and outbound clicks with properties |
get_errors, get_web_vitals | JavaScript errors; LCP, INP, CLS, FCP and TTFB percentiles |
get_journeys, run_funnel | Common paths; step-by-step conversion |
list_goals, list_segments | Goals with conversion rates; saved segments (any tool accepts segment_id) |
list_users, get_user, get_retention | Identified users, profiles and cohort retention |
get_bots_and_ai | AI crawlers, AI assistants, search bots, and visits referred by ChatGPT, Perplexity, Claude and others |
create_goal, add_annotation | Write keys only: create a goal, mark a date on the charts |
REST API
Base URL: https://app.pagelens.io. Responses are JSON. Timestamps are ISO 8601 in UTC.
curl "https://app.pagelens.io/api/sites/SITE_ID/overview?from=2026-09-01T00:00:00Z&to=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer pl_your_key"
Common query parameters
| Parameter | Description |
|---|---|
from, to | ISO dates or timestamps. to is exclusive. Default: the last 7 days. |
tz | IANA timezone used to group days and hours, e.g. Europe/Berlin. Default: UTC. |
bucket | hour, day, week or month for time series. Picked automatically if omitted. |
filter | Repeatable dimension:value, e.g. filter=country:DE&filter=channel:Organic%20Search. Keeps whole sessions that match. Operators go after the dimension: page!:/x is not, page~:blog contains, page!~:blog does not contain, page^:/docs starts with (URL-encode ^ and ~). |
segment | Id of a saved segment (GET /api/sites/:id/segments). Its filters are combined with any filter. |
limit | Rows for lists (default 10, max 500). |
Filter and breakdown dimensions: page, title, hostname, referrer, channel, utm_source, utm_medium, utm_campaign, browser, os, device, screen, country, city, language, event. Breakdowns also accept entry, exit and outbound.
Endpoints
| Method & path | Returns |
|---|---|
GET /api/sites | Your sites |
GET /api/sites/:id | One site with its settings |
GET /api/sites/:id/overview | current and previous totals, series, previousSeries |
GET /api/sites/:id/breakdown/:dimension | rows of value, visitors, sessions, count. Supports search. |
GET /api/sites/:id/pages | Per-page metrics |
GET /api/sites/:id/realtime | Visitors in the last 5 minutes |
GET /api/sites/:id/sessions | Sessions. tab = engaged, bounced, errors or replay. user = an identified user id. |
GET /api/sites/:id/sessions/:sid | Events of one session |
GET /api/sites/:id/events | Custom events and properties |
GET /api/sites/:id/errors | JavaScript errors |
GET /api/sites/:id/performance | Web Vitals |
GET /api/sites/:id/journeys | Common paths |
GET /api/sites/:id/goals | Goals with conversions |
POST /api/sites/:id/funnel | Body {"steps":[{"type":"page","value":"/"},{"type":"event","value":"signup"}]} |
GET /api/sites/:id/users | Users. tab = identified or anonymous. Supports search. |
GET /api/sites/:id/users/:uid | One user's profile and sessions |
GET /api/sites/:id/retention | Cohorts; unit = day or week |
GET /api/sites/:id/bots | Bot and AI traffic |
GET /api/sites/:id/export/:type | CSV download |
GET /api/sites/:id/segments | Saved segments |
POST /api/sites/:id/goals, /funnels, /annotations, /segments | Write keys: create. DELETE …/:itemId removes. |
Server-side events
Track events from your backend (payments, sign-ups, webhooks) with a write key. Pass the visitor's IP and user agent if you have them; they're used for location and device and are not stored.
curl https://app.pagelens.io/api/track \
-H "Authorization: Bearer pl_your_write_key" \
-H "Content-Type: application/json" \
-d '{
"site_id": "SITE_ID",
"type": "custom_event",
"name": "purchase",
"url": "https://example.com/checkout",
"props": { "plan": "pro", "amount": 49 },
"ip": "203.0.113.7",
"user_agent": "Mozilla/5.0 ..."
}'
Limits & errors
| Plan | Requests per day |
|---|---|
| Free trial | 5,000 |
| Starter | 2,000 |
| Pro | 10,000 |
| Business | 50,000 |
Every key is also limited to 120 requests per minute. Responses include X-RateLimit-Limit and X-RateLimit-Remaining. When you hit a limit you get 429 with Retry-After.
Errors look like {"error": "message"}:
401: missing, invalid or revoked key.402: the trial has ended.403: the key can't call this route.404: the site isn't accessible with this key.
Questions or missing endpoints: hello@pagelens.io