Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring content
Preparing Ring content
Preparing Ring content
Use Founder / Developer tabs in the docs sidebar to filter this page. Admin console surfaces consume these routes; third-party providers are optional env hooks.
Ring ships a first-party analytics pipeline: client telemetry is ingested over /api/analytics/*, Zod-validated at the route boundary, persisted to analytics_events / web_vitals / analytics_errors, and read back by admin-scoped GET routes. Storage can be disabled entirely per environment — every route then acknowledges without writing.
| Previous (GA-only setup) | Ring equivalent |
|---|---|
| Third-party SDK only, data leaves your clone | First-party ingestion into your own database |
| One opaque dashboard | Admin-scoped reads + platform stats with role gates |
| No device/session context | sessionId batches, device telemetry with tunnel fan-out |
| Web Vitals left unmeasured | Core Web Vitals ingestion + computed performanceScore |
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/analytics/app | POST | optional userId | Batched app events → analytics_events |
/api/analytics/device | POST | session required | Device telemetry → device_telemetry + user tunnel fan-out |
/api/analytics/navigation | POST | — | Light acknowledgement stub (no storage) |
/api/analytics/errors | POST | optional userId | Client error capture → analytics_errors (deferred write) |
/api/analytics/errors | GET |
platform admin.ANALYTICS_DISABLE_STORAGE=true turns persistence off without code changes; endpoints keep answering.getPlatformAnalytics).| Variable | Provider |
|---|---|
GA_TRACKING_ID / GA4_MEASUREMENT_PROTOCOL_SECRET | Google Analytics |
MIXPANEL_TOKEN | Mixpanel |
AMPLITUDE_API_KEY | Amplitude |
SENTRY_DSN | Sentry error tracking |
| Variable | Default | Effect |
|---|---|---|
ANALYTICS_DISABLE_STORAGE | unset | "true" acknowledges events without writing to the database |
Use Founder / Developer tabs in the docs sidebar to filter this page. Admin console surfaces consume these routes; third-party providers are optional env hooks.
Ring ships a first-party analytics pipeline: client telemetry is ingested over /api/analytics/*, Zod-validated at the route boundary, persisted to analytics_events / web_vitals / analytics_errors, and read back by admin-scoped GET routes. Storage can be disabled entirely per environment — every route then acknowledges without writing.
| Previous (GA-only setup) | Ring equivalent |
|---|---|
| Third-party SDK only, data leaves your clone | First-party ingestion into your own database |
| One opaque dashboard | Admin-scoped reads + platform stats with role gates |
| No device/session context | sessionId batches, device telemetry with tunnel fan-out |
| Web Vitals left unmeasured | Core Web Vitals ingestion + computed performanceScore |
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/analytics/app | POST | optional userId | Batched app events → analytics_events |
/api/analytics/device | POST | session required | Device telemetry → device_telemetry + user tunnel fan-out |
/api/analytics/navigation | POST | — | Light acknowledgement stub (no storage) |
/api/analytics/errors | POST | optional userId | Client error capture → analytics_errors (deferred write) |
/api/analytics/errors | GET |
platform admin.ANALYTICS_DISABLE_STORAGE=true turns persistence off without code changes; endpoints keep answering.getPlatformAnalytics).| Variable | Provider |
|---|---|
GA_TRACKING_ID / GA4_MEASUREMENT_PROTOCOL_SECRET | Google Analytics |
MIXPANEL_TOKEN | Mixpanel |
AMPLITUDE_API_KEY | Amplitude |
SENTRY_DSN | Sentry error tracking |
| Variable | Default | Effect |
|---|---|---|
ANALYTICS_DISABLE_STORAGE | unset | "true" acknowledges events without writing to the database |
Use Founder / Developer tabs in the docs sidebar to filter this page. Admin console surfaces consume these routes; third-party providers are optional env hooks.
Ring ships a first-party analytics pipeline: client telemetry is ingested over /api/analytics/*, Zod-validated at the route boundary, persisted to analytics_events / web_vitals / analytics_errors, and read back by admin-scoped GET routes. Storage can be disabled entirely per environment — every route then acknowledges without writing.
| Previous (GA-only setup) | Ring equivalent |
|---|---|
| Third-party SDK only, data leaves your clone | First-party ingestion into your own database |
| One opaque dashboard | Admin-scoped reads + platform stats with role gates |
| No device/session context | sessionId batches, device telemetry with tunnel fan-out |
| Web Vitals left unmeasured | Core Web Vitals ingestion + computed performanceScore |
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/api/analytics/app | POST | optional userId | Batched app events → analytics_events |
/api/analytics/device | POST | session required | Device telemetry → device_telemetry + user tunnel fan-out |
/api/analytics/navigation | POST | — | Light acknowledgement stub (no storage) |
/api/analytics/errors | POST | optional userId | Client error capture → analytics_errors (deferred write) |
/api/analytics/errors | GET |
platform admin.ANALYTICS_DISABLE_STORAGE=true turns persistence off without code changes; endpoints keep answering.getPlatformAnalytics).| Variable | Provider |
|---|---|
GA_TRACKING_ID / GA4_MEASUREMENT_PROTOCOL_SECRET | Google Analytics |
MIXPANEL_TOKEN | Mixpanel |
AMPLITUDE_API_KEY | Amplitude |
SENTRY_DSN | Sentry error tracking |
| Variable | Default | Effect |
|---|---|---|
ANALYTICS_DISABLE_STORAGE | unset | "true" acknowledges events without writing to the database |
| platform admin |
| Error listing with severity/component filters |
/api/analytics/web-vitals | POST | optional userId | Core Web Vitals + performanceScore → web_vitals (deferred write) |
/api/analytics/web-vitals | GET | platform admin | scope=platform summary or per-user; timeframe 24h / 7d / 30d |
/api/analytics/platform-stats | GET | platform admin | Live counts for users, entities, opportunities |
DD_API_KEY / DD_APP_KEY |
| Datadog |
None are required — Ring's own pipeline works without them.
web-vitalswebVitalsInputSchema + calculatePerformanceScore |
web_vitals with detected platform/browser |
navigation | none (stub) | nothing — returns { ok: true } |
GET /api/analytics/platform-stats — isPlatformAdmin(session.user.role) gate; concurrent countDocs over users / entities / opportunities.GET /api/analytics/web-vitals?scope=platform&timeframe=30d — platform summary via getPlatformAnalyticsSummary; omit scope for per-user metrics.features/analytics/services/get-platform-analytics.ts (core summary + docs not-found + personal-page stats).| platform admin |
| Error listing with severity/component filters |
/api/analytics/web-vitals | POST | optional userId | Core Web Vitals + performanceScore → web_vitals (deferred write) |
/api/analytics/web-vitals | GET | platform admin | scope=platform summary or per-user; timeframe 24h / 7d / 30d |
/api/analytics/platform-stats | GET | platform admin | Live counts for users, entities, opportunities |
DD_API_KEY / DD_APP_KEY |
| Datadog |
None are required — Ring's own pipeline works without them.
web-vitalswebVitalsInputSchema + calculatePerformanceScore |
web_vitals with detected platform/browser |
navigation | none (stub) | nothing — returns { ok: true } |
GET /api/analytics/platform-stats — isPlatformAdmin(session.user.role) gate; concurrent countDocs over users / entities / opportunities.GET /api/analytics/web-vitals?scope=platform&timeframe=30d — platform summary via getPlatformAnalyticsSummary; omit scope for per-user metrics.features/analytics/services/get-platform-analytics.ts (core summary + docs not-found + personal-page stats).| platform admin |
| Error listing with severity/component filters |
/api/analytics/web-vitals | POST | optional userId | Core Web Vitals + performanceScore → web_vitals (deferred write) |
/api/analytics/web-vitals | GET | platform admin | scope=platform summary or per-user; timeframe 24h / 7d / 30d |
/api/analytics/platform-stats | GET | platform admin | Live counts for users, entities, opportunities |
DD_API_KEY / DD_APP_KEY |
| Datadog |
None are required — Ring's own pipeline works without them.
web-vitalswebVitalsInputSchema + calculatePerformanceScore |
web_vitals with detected platform/browser |
navigation | none (stub) | nothing — returns { ok: true } |
GET /api/analytics/platform-stats — isPlatformAdmin(session.user.role) gate; concurrent countDocs over users / entities / opportunities.GET /api/analytics/web-vitals?scope=platform&timeframe=30d — platform summary via getPlatformAnalyticsSummary; omit scope for per-user metrics.features/analytics/services/get-platform-analytics.ts (core summary + docs not-found + personal-page stats).