REST API reference for browser analytics — overview, vitals, flag impact, events, variants, funnels, and export
Last updated March 21, 2026
Analytics API Reference
All analytics endpoints require authentication and project access. Pass your API token via the Authorization: Bearer <token> header.
Overview
GET /api/analytics/overview
Returns aggregate metrics for a site over a time range.
Query parameters
| Parameter | Required | Description |
|---|---|---|
siteId | Yes | Project ID (same as data-site-id in the script tag) |
range | No | Time range: 1h, 24h, 7d, 30d (default: 24h) |
Response
{
"visitors": 1842,
"pageviews": 5231,
"avgSessionDuration": 124500,
"bounceRate": 0.34,
"range": "24h"
}| Field | Type | Description |
|---|---|---|
visitors | number | Unique session IDs in the period |
pageviews | number | Total page view events |
avgSessionDuration | number | Mean session duration in milliseconds |
bounceRate | number | Fraction of single-page sessions (0–1) |
Web Vitals
GET /api/analytics/vitals
Returns percentile data for Core Web Vitals, optionally filtered by flag.
Query parameters
| Parameter | Required | Description |
|---|---|---|
siteId | Yes | Project ID |
range | No | Time range: 1h, 24h, 7d, 30d (default: 24h) |
flagKey | No | Filter vitals to sessions with this flag active |
Response
{
"vitals": [
{ "metric": "lcp", "p50": 1200, "p75": 1850, "p95": 3200, "count": 4521 },
{ "metric": "cls", "p50": 0.03, "p75": 0.08, "p95": 0.18, "count": 4521 },
{ "metric": "inp", "p50": 85, "p75": 145, "p95": 320, "count": 3890 },
{ "metric": "ttfb", "p50": 120, "p75": 280, "p95": 650, "count": 4521 },
{ "metric": "fcp", "p50": 900, "p75": 1400, "p95": 2200, "count": 4521 }
],
"timeSeries": [],
"range": "7d"
}| Field | Type | Description |
|---|---|---|
vitals[].metric | string | Metric name: lcp, cls, inp, ttfb, fcp |
vitals[].p50 | number | 50th percentile value |
vitals[].p75 | number | 75th percentile value |
vitals[].p95 | number | 95th percentile value |
vitals[].count | number | Number of measurements |
Caching: Cache-Control: private, max-age=30
Flag Impact
GET /api/analytics/flag-impact
Returns per-variant performance metrics for each active flag.
Query parameters
| Parameter | Required | Description |
|---|---|---|
siteId | Yes | Project ID |
range | No | Time range: 1h, 24h, 7d, 30d (default: 24h) |
Response
{
"impact": [
{
"flagKey": "new-checkout",
"variants": [
{ "variant": "control", "pageviews": 2100, "sessions": 820, "lcpP75": 1900, "avgCls": 0.05 },
{ "variant": "v2", "pageviews": 2050, "sessions": 810, "lcpP75": 1650, "avgCls": 0.04 }
]
}
],
"range": "24h"
}| Field | Type | Description |
|---|---|---|
impact[].flagKey | string | Feature flag key |
impact[].variants[].variant | string | Variant name or value |
impact[].variants[].pageviews | number | Page views for this variant |
impact[].variants[].sessions | number | Unique sessions for this variant |
impact[].variants[].lcpP75 | number | LCP 75th percentile (ms) |
impact[].variants[].avgCls | number | Average CLS score |
Caching: Cache-Control: private, max-age=30
Events
GET /api/analytics/events
Returns the most recent raw events.
Query parameters
| Parameter | Required | Description |
|---|---|---|
siteId | Yes | Project ID |
limit | No | Number of events (max 100, default: 50) |
Response
{
"events": [
{
"id": 12345,
"type": "webvital",
"url": "/checkout",
"timestamp": "2026-03-20T10:30:00.000Z",
"country": "US",
"browser": "Chrome",
"os": "macOS",
"device": "desktop",
"flags": { "new-checkout": "v2" },
"data": { "metric": "lcp", "value": 1650, "rating": "good" }
}
]
}| Field | Type | Description |
|---|---|---|
events[].type | string | Event type: pageview, webvital, click, error, scroll, custom |
events[].url | string | Page URL where the event occurred |
events[].flags | object | Active flag variants at event time |
events[].data | object | Event-specific payload (varies by type) |
Caching: Cache-Control: private, max-age=5
Flag Variant Statistics
GET /api/analytics/flags/{key}/variants
Returns detailed per-variant analytics for a specific flag, including evaluation counts, conversion rates, and latency.
Query parameters
| Parameter | Required | Description |
|---|---|---|
projectId | Yes | Project ID |
environment | Yes | Environment name (e.g., production) |
period | No | Time period: 1h, 24h, 7d, 30d (default: 24h) |
serviceId | No | Filter to a specific service |
eventName | No | Custom event name for conversion tracking |
Response
{
"flagKey": "new-checkout",
"environment": "production",
"period": "7d",
"variants": [
{
"variant": "control",
"evaluations": 12500,
"conversions": 625,
"conversionRate": 0.05,
"avgEventValue": 42.50,
"latencyP50": 3.2,
"latencyP99": 18.5
}
],
"totalEvaluations": 24800,
"totalConversions": 1363,
"overallConversionRate": 0.055
}Caching: Cache-Control: private, max-age=30
Funnel Analysis
GET /api/analytics/funnel
Analyze multi-step conversion funnels segmented by flag variant.
Query parameters
| Parameter | Required | Description |
|---|---|---|
projectId | Yes | Project ID |
flagKey | Yes | Flag key to segment by |
steps | Yes | Comma-separated event names defining the funnel |
environment | Yes | Environment name |
period | No | Time period (default: 24h) |
serviceId | No | Filter to a specific service |
Response
{
"projectId": "proj_abc123",
"flagKey": "new-checkout",
"steps": ["page_view", "add_to_cart", "checkout", "purchase"],
"funnelSteps": [
{
"step": "page_view",
"stepIndex": 0,
"totalUsers": 5000,
"byVariant": { "control": 2500, "v2": 2500 },
"dropOffRate": 0
},
{
"step": "purchase",
"stepIndex": 3,
"totalUsers": 600,
"byVariant": { "control": 250, "v2": 350 },
"dropOffRate": 0.25
}
],
"variants": ["control", "v2"],
"overallConversionRate": 0.12
}| Field | Type | Description |
|---|---|---|
funnelSteps[].step | string | Event/step name |
funnelSteps[].totalUsers | number | Users who reached this step |
funnelSteps[].byVariant | object | User count per flag variant |
funnelSteps[].dropOffRate | number | Fraction that dropped off from previous step |
Caching: Cache-Control: private, max-age=30
Export
POST /api/analytics/export
Export evaluation metrics and outcome events to a webhook endpoint.
Request body
{
"projectId": "proj_abc123",
"destination": "webhook",
"webhookUrl": "https://example.com/analytics-hook",
"signingSecret": "whsec_...",
"dataTypes": ["evaluations", "outcomes"],
"period": "24h"
}| Field | Required | Description |
|---|---|---|
projectId | Yes | Project ID |
destination | Yes | Export destination (currently webhook) |
webhookUrl | Yes | URL to POST exported data to |
signingSecret | No | HMAC-SHA256 signing secret for webhook verification |
dataTypes | No | Data types to export (default: all) |
period | No | Time period to export (default: 24h) |
Response
{
"ok": true,
"exported": {
"evaluations": 24800,
"outcomes": 1363
}
}Ingestion Endpoint
POST https://ingest.flaggr.dev/e
This is the Cloudflare Worker endpoint that receives events from the browser analytics script. You generally don't call this directly — the script handles it.
Request
- Content-Type:
application/json - Body: JSON array of event objects (max 100 items, max 100KB)
- Optional header:
X-Write-Tokenfor write-protected projects
Response
{
"accepted": 18,
"rejected": 2
}Status: 202 Accepted
Rate Limits
The ingestion endpoint enforces 100 requests per minute per IP via Cloudflare rate limiting rules. API query endpoints follow the standard Flaggr rate limits documented in Rate Limiting.
Next Steps
- Browser Analytics — Install and configure the script
- Analytics Dashboard — Visual guide to the dashboard
- Analytics & A/B Testing — Measure experiments with analytics