Skip to main content
Free5 minutesBeginner

IP Address Handling

How Zenovay processes IP addresses: geolocation, rate limiting, hashing before analytics storage, and the bounded places a raw address does exist.

ip-addressanonymizationgeolocationprivacygdpr
Last updated:

Zenovay treats IP addresses as personal data. The raw address is used at request time for geolocation, rate limiting, and abuse detection, and it is hashed before it reaches your analytics tables. This article explains exactly what happens to an IP, including the specific places a raw address does exist and for how long.

How IPs Are Handled

When a tracking request arrives, the visitor's raw IP does a small amount of operational work and is then replaced by a hash for everything you see in your dashboard. Nothing in this flow is configurable: it is the default behaviour for every website on every plan.

  1. Geolocation: Determine country, region, and (approximate) city.
  2. Rate limiting: Count requests per address so a single source cannot flood ingestion.
  3. Abuse and bot detection: Filter automated and malicious traffic, and block sources that keep abusing the endpoint.
  4. Hashing: Derive a daily-rotating SHA-256 identifier. From this point the analytics pipeline works with the hash, not the address.

The Process

Incoming Request
      ↓
IP Address (e.g., 203.0.113.50)
      ↓
┌─────────────────────────────┐
│  Geolocation Lookup         │
│  → Country: United States   │
│  → Region: California       │
│  → City: San Francisco      │
│  (result cached for 24h)    │
└─────────────────────────────┘
      ↓
┌─────────────────────────────┐
│  Rate limit + abuse checks  │
│  → allow / throttle / block │
└─────────────────────────────┘
      ↓
┌─────────────────────────────┐
│  Visitor ID Generation      │
│  Daily-rotating SHA-256     │
│  → v_abc123def456           │
└─────────────────────────────┘
      ↓
Analytics tables receive the hash
(plus geo and device fields, no raw address)

What the Analytics Tables Store

Your analytics data holds a hash, not an address. The ip_address column on the visitor record is written empty, and only the hash and the resolved geolocation are kept:

  • The visitor identifier is derived from the address, the website ID, and the calendar date.
  • Because the date is part of the input, the identifier rotates daily. A returning visitor produces a different identifier tomorrow than today, so the visitor identifier does not build a long-term profile of one address.
  • Audit logs hold no plaintext address either. The plaintext column was removed from the account audit log, and the team audit log hashes the value on insert.

This is the behaviour on every plan, and there is no setting that turns it off.

Treat the hash as pseudonymous data rather than anonymous data. It is a one-way function with no key that turns it back into an address, but the inputs are the address, the website ID, and the date, so someone holding a hash and a candidate address can test that candidate. Your own privacy notice should describe it that way.

Where a Raw Address Does Exist

Being precise about this is more useful than a blanket claim. Outside the analytics tables, the raw address appears in these places, each of them bounded:

WhereWhyHow long
Geolocation providersCountry, region, and city lookups are sent to ipinfo.io and ipwho.is with the address in the requestGoverned by each provider's own retention
Geolocation cacheAvoids repeating the same lookup for the same address24 hours
Rate-limit countersPer-address request counting at the edgeMinutes, the length of the rate-limit window
Blocklist entriesTemporarily blocking a source that is abusing ingestion24 hours
Ban recordsLonger blocks for repeat abuse30 days by default
Security events and reputation recordsAbuse detection needs history to distinguish a spike from an attack7 days for events, 30 days for reputation
Abuse-prevention and device-authorization tablesRecords of abuse signals, device authorization codes, and bansUntil the record is purged by its own retention
Infrastructure logsRate-limit, security, and block events are logged by Cloudflare WorkersGoverned by the platform log retention

None of this feeds your dashboard, and none of it is exposed through the API or exports. It exists so that ingestion can resolve a location and stay available under attack.

Geolocation Accuracy

Geolocation is derived from the IP at request time. Accuracy decreases as you move from country to city level:

Full IP (203.0.113.50):
└── Country: United States
    └── Region: California
        └── City: San Francisco (approximate)

City-level results are best-effort and can be imprecise, especially for mobile carriers, corporate networks, and VPN traffic. Country-level data is the most reliable.

Server-Side Tracking

Forwarding the Visitor IP

When you send events from your own backend rather than the browser, Zenovay sees your server's IP unless you forward the original visitor IP. Pass it along with the standard X-Forwarded-For header so geolocation reflects the real visitor:

// Express.js example
app.post('/track', async (req, res) => {
  const clientIP = req.headers['x-forwarded-for'] || req.socket.remoteAddress;

  await fetch('https://api.zenovay.com/e/YOUR_TRACKING_CODE', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Forwarded-For': clientIP  // Forward for geolocation
    },
    body: JSON.stringify({
      type: 'page_view',
      url: 'https://yoursite.com/page'
    })
  });

  res.sendStatus(204);
});

Whatever IP you forward is treated exactly like a browser request: geolocated, checked against the rate limit and abuse rules, and hashed before it reaches your analytics tables. Forwarding an address means you are sending it to the same geolocation providers listed above, so forward only what you need geolocation for.

Compliance Considerations

GDPR

IP addresses are personal data under GDPR. Zenovay keeps the address out of your analytics tables, replaces it with a daily-rotating hash, and confines the raw value to geolocation and abuse prevention with the retention limits listed above. Document your analytics processing in your own privacy policy, and note that the geolocation lookups are a transfer to those providers.

CCPA

IP addresses count as personal information under CCPA. Disclose your use of analytics in your privacy policy. What you retain and can act on in Zenovay is a hash plus coarse location, not the address itself. Whether that changes any of your own disclosure or opt-out duties depends on your jurisdiction.

Technical Details

Visitor ID Hash

The visitor identifier is built like this:

Visitor_ID = SHA-256( IP_Address + "|" + Website_ID + "|" + Date )

Where Date is the current calendar date (e.g. "2026-08-17").

Example:
SHA-256("203.0.113.50|abc123|2026-08-17") = "a3b8c9d4e5f6..."

Properties:

  • One-way: SHA-256 has no inverse, and there is no key or lookup table that turns a stored identifier back into an address. That is not the same as unguessable, which is why the note above matters.
  • Scoped per website: the same visitor on two of your sites produces two different visitor identifiers, so visits are not correlated across your properties by this identifier.
  • Consistent within a day: the same visitor on the same day and site produces the same identifier.
  • Rotates daily: the date is part of the input, so the identifier changes every day and is not a permanent identifier.

One identifier deliberately behaves differently. B2B company identification uses a separate hash that neither rotates daily nor is scoped per website, because correlating visits from the same company network over time is the entire point of the feature. Daily rotation and per-website scoping apply to the visitor and session identifiers, not to that one.

Geolocation Source

Zenovay resolves country and approximate location at request time from Cloudflare's edge geolocation and from lookups against two external providers, ipinfo.io and ipwho.is. Results are cached for 24 hours so a repeat visitor does not trigger a repeat lookup. Accuracy varies by region and is most reliable at the country level.

Troubleshooting

No Geographic Data

If geolocation isn't working:

  • Make sure the visitor IP is being forwarded when tracking server-side (behind a proxy or load balancer).
  • Confirm you aren't testing from a localhost or internal IP, which is skipped.

Inaccurate Location

Geolocation can be wrong due to:

  • VPN usage
  • Mobile carriers
  • Corporate proxies
  • Geo-IP database lag

Next Steps

Was this article helpful?