Skip to main content

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

ParameterRequiredDescription
siteIdYesProject ID (same as data-site-id in the script tag)
rangeNoTime range: 1h, 24h, 7d, 30d (default: 24h)

Response

{
  "visitors": 1842,
  "pageviews": 5231,
  "avgSessionDuration": 124500,
  "bounceRate": 0.34,
  "range": "24h"
}
FieldTypeDescription
visitorsnumberUnique session IDs in the period
pageviewsnumberTotal page view events
avgSessionDurationnumberMean session duration in milliseconds
bounceRatenumberFraction 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

ParameterRequiredDescription
siteIdYesProject ID
rangeNoTime range: 1h, 24h, 7d, 30d (default: 24h)
flagKeyNoFilter 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"
}
FieldTypeDescription
vitals[].metricstringMetric name: lcp, cls, inp, ttfb, fcp
vitals[].p50number50th percentile value
vitals[].p75number75th percentile value
vitals[].p95number95th percentile value
vitals[].countnumberNumber 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

ParameterRequiredDescription
siteIdYesProject ID
rangeNoTime 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"
}
FieldTypeDescription
impact[].flagKeystringFeature flag key
impact[].variants[].variantstringVariant name or value
impact[].variants[].pageviewsnumberPage views for this variant
impact[].variants[].sessionsnumberUnique sessions for this variant
impact[].variants[].lcpP75numberLCP 75th percentile (ms)
impact[].variants[].avgClsnumberAverage 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

ParameterRequiredDescription
projectIdYesProject ID
projectSlugNoProject slug used as a fallback filter for admin events
rangeNoTime 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
  }
}
FieldTypeDescription
funnel.steps[].eventstringFunnel step: screen_viewed, flag_viewed, or activation
funnel.steps[].usersnumberActors who reached the step
funnel.steps[].conversionRatenumberShare of entry actors who reached the step
funnel.steps[].dropOffRatenumberShare that dropped from the previous step
experimentCycleTime.sampleSizenumberExperiments with both start and decision events
experimentCycleTime.medianHoursnumber | nullMedian 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

ParameterRequiredDescription
projectIdYesProject ID
projectSlugNoProject slug used as a fallback filter for admin events
rangeNoTime 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
    }
  ]
}
FieldTypeDescription
cohorts[].weekstringISO timestamp for the start of the cohort week
cohorts[].createdProjectsnumberProject-week cohorts with created flags
cohorts[].adoptedProjectsnumberProject-week cohorts with matching flag views
cohorts[].adoptionRatenumberadoptedProjects / createdProjects

Caching: Cache-Control: private, max-age=60


Events

GET /api/analytics/events

Returns the most recent raw events.

Query parameters

ParameterRequiredDescription
siteIdYesProject ID
limitNoNumber 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" }
    }
  ]
}
FieldTypeDescription
events[].typestringEvent type: pageview, webvital, click, error, scroll, custom
events[].urlstringPage URL where the event occurred
events[].flagsobjectActive flag variants at event time
events[].dataobjectEvent-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

ParameterRequiredDescription
projectIdYesProject ID
environmentYesEnvironment name (e.g., production)
periodNoTime period: 1h, 24h, 7d, 30d (default: 24h)
serviceIdNoFilter to a specific service
eventNameNoCustom 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

ParameterRequiredDescription
projectIdYesProject ID
flagKeyYesFlag key to segment by
stepsYesComma-separated event names defining the funnel
environmentYesEnvironment name
periodNoTime period (default: 24h)
serviceIdNoFilter 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
}
FieldTypeDescription
funnelSteps[].stepstringEvent/step name
funnelSteps[].totalUsersnumberUsers who reached this step
funnelSteps[].byVariantobjectUser count per flag variant
funnelSteps[].dropOffRatenumberFraction 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"
}
FieldRequiredDescription
projectIdYesProject ID
destinationYesExport destination (currently webhook)
webhookUrlYesURL to POST exported data to
signingSecretNoHMAC-SHA256 signing secret for webhook verification
dataTypesNoData types to export (default: all)
periodNoTime 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-Token for 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 configured NEXT_PUBLIC_FLAGGR_ANALYTICS_SITE_ID / FLAGGR_ANALYTICS_SITE_ID
  • Timestamp window: occurredAt must 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