REST API reference for browser and admin analytics — overview, vitals, flag impact, admin funnels, adoption cohorts, events, variants, funnels, and export
Last updated May 31, 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
Admin Funnel
GET /api/analytics/admin-funnel
Returns first-party Flaggr console activation metrics for a project.
Query parameters
| Parameter | Required | Description |
|---|---|---|
projectId | Yes | Project ID |
projectSlug | No | Project slug used as a fallback filter for admin events |
range | No | Time range: 24h, 7d, 30d (default: 7d) |
Response
{
"projectId": "proj_abc123",
"range": "7d",
"funnel": {
"steps": [
{ "event": "screen_viewed", "users": 120, "conversionRate": 1, "dropOffRate": 0 },
{ "event": "flag_viewed", "users": 86, "conversionRate": 0.72, "dropOffRate": 0.28 },
{ "event": "activation", "users": 51, "conversionRate": 0.43, "dropOffRate": 0.41 }
]
},
"experimentCycleTime": {
"sampleSize": 8,
"medianHours": 18.5
}
}| Field | Type | Description |
|---|---|---|
funnel.steps[].event | string | Funnel step: screen_viewed, flag_viewed, or activation |
funnel.steps[].users | number | Actors who reached the step |
funnel.steps[].conversionRate | number | Share of entry actors who reached the step |
funnel.steps[].dropOffRate | number | Share that dropped from the previous step |
experimentCycleTime.sampleSize | number | Experiments with both start and decision events |
experimentCycleTime.medianHours | number | null | Median hours from experiment_started to experiment_decision |
Caching: Cache-Control: private, max-age=30
Adoption Cohorts
GET /api/analytics/adoption-cohorts
Returns weekly create-to-view adoption cohorts for a project.
Query parameters
| Parameter | Required | Description |
|---|---|---|
projectId | Yes | Project ID |
projectSlug | No | Project slug used as a fallback filter for admin events |
range | No | Time range: 7d, 30d, 90d (default: 30d) |
Response
{
"projectId": "proj_abc123",
"range": "30d",
"cohorts": [
{
"week": "2026-05-11T00:00:00.000Z",
"createdProjects": 12,
"adoptedProjects": 9,
"adoptionRate": 0.75
}
]
}| Field | Type | Description |
|---|---|---|
cohorts[].week | string | ISO timestamp for the start of the cohort week |
cohorts[].createdProjects | number | Project-week cohorts with created flags |
cohorts[].adoptedProjects | number | Project-week cohorts with matching flag views |
cohorts[].adoptionRate | number | adoptedProjects / createdProjects |
Caching: Cache-Control: private, max-age=60
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
Admin Event Ingestion
POST /ingest/admin-events
This endpoint receives first-party console analytics from the Flaggr admin web app. You generally do not call it directly; the console instrumentation batches events automatically.
Request
- Content-Type:
application/json - Body: JSON array of admin event objects (max 100 events per batch)
- Allowed site IDs:
flaggr_admin_prod,flaggr_admin_preview,flaggr_admin_dev, or the configuredNEXT_PUBLIC_FLAGGR_ANALYTICS_SITE_ID/FLAGGR_ANALYTICS_SITE_ID - Timestamp window:
occurredAtmust be no more than 2 hours old and no more than 60 seconds in the future
[
{
"source": "flaggr-admin",
"siteId": "flaggr_admin_preview",
"sessionId": "session_abc",
"installId": "install_abc",
"userId": "user_123",
"event": "flag_viewed",
"occurredAt": "2026-05-17T02:30:00.000Z",
"appVersion": "admin-web",
"buildNumber": "development",
"appVariant": "development",
"platform": "web",
"apiOrigin": "http://127.0.0.1:3000",
"properties": {
"project_id": "proj_abc123",
"project_slug": "acme",
"flag_key": "checkout-flow"
}
}
]Response
{
"accepted": 1,
"rejected": 0,
"siteId": "flaggr_admin_preview"
}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
- Admin Analytics — Console activation funnels and adoption cohorts
- Analytics & A/B Testing — Measure experiments with analytics