Analytics and privacy

How Nimriz logs click data, what privacy mode changes, and how realtime differs from reporting.

Analytics and privacy

Nimriz separates raw redirect event ingestion from dashboard reporting, and it defaults to a privacy-preserving capture mode.

Data flow

  1. Redirects emit raw click events to Cloudflare Analytics Engine.
  2. Scheduled jobs aggregate those events into Postgres rollups and counters.
  3. Stable reporting should use rollups. Realtime views should use live event queries.

Storage split

  • Raw click events: Cloudflare Analytics Engine
  • Operational records and rollups: Supabase Postgres

This split keeps redirect-path logging fast while still giving dashboards a stable reporting source.

Privacy mode

Privacy mode defaults to on for new accounts.

When privacy mode is on:

  • raw IP addresses are not stored
  • full user-agent strings are not stored
  • event payloads omit IP and user-agent hashes

When privacy mode is off:

  • IP and user-agent are hashed at the edge before storage
  • hashes rotate daily
  • raw identifier values are still never persisted

Best-effort dimensions

These fields are useful for reporting, but they are not guaranteed:

  • country, region, city, colo
  • device_category
  • browser_family
  • os_family
  • referrer
  • referrer_host
  • social_source
  • bot_flag

Build your UI and downstream logic to handle null or missing values gracefully.

GET /api/live-view

Returns recent raw-ish events from Analytics Engine for internal dashboards and debugging flows.

Query parameters

  • domain_id: optional
  • url_id: optional
  • limit: optional

Response shape

{
  "source": "analytics_engine",
  "count": 2,
  "events": [
    {
      "clicked_at": "2026-03-08T12:34:56.000Z",
      "url_id": "22222222-2222-2222-2222-222222222222",
      "domain_id": "11111111-1111-1111-1111-111111111111",
      "short_code": "spring-launch",
      "country": "US",
      "device_category": "mobile",
      "bot_flag": false,
      "referrer_host": "twitter.com",
      "social_source": "twitter",
      "destination_url_capped": "https://example.com/landing"
    }
  ]
}

GET /api/link-breakdowns

Returns per-link top-N analytics breakdowns from Analytics Engine.

Query parameters

  • url_id: required
  • range_days: optional, default 30, max 365
  • include_bots: optional, default false
  • limit: optional, default 5, max 20

Response shape

{
  "ok": true,
  "source": "analytics_engine",
  "url_id": "22222222-2222-2222-2222-222222222222",
  "range_days": 30,
  "include_bots": false,
  "limit": 5,
  "sampled_counts": true,
  "dimensions": {
    "country": [
      { "label": "US", "clicks": 120 }
    ],
    "device": [
      { "label": "Mobile", "clicks": 95 }
    ]
  }
}

Realtime versus reporting

Use realtime when you need:

  • recent traffic debugging
  • rapid validation after a campaign launch
  • confirmation that redirects are still logging

Use reporting rollups when you need:

  • stable charts
  • exports
  • longer time ranges
  • customer-visible analytics summaries

The same link can show recent traffic in live tools before that traffic appears in rollup-backed reports.

Bot handling

Bot traffic is flagged so dashboards can filter it. Not all bots are abusive. Common sources include preview crawlers, scanners, and automated checks.

Integration guidance

  • Use url_id as the stable identifier in downstream systems.
  • Treat missing referrers as normal, not as a bug by default.
  • Do not assume live-view and rollup totals will match at the same moment.

Related guides