Skip to main content
If your organisation’s privacy policy does not allow the collection or processing of user IP addresses, SegmentStream supports an alternative setup. Instead of sending raw IP addresses, you can hash the IP (with salt) and enrich it with geolocation data on your side, before passing it to the SegmentStream data layer. This approach ensures:
  • No personally identifiable IP data is shared with SegmentStream.
  • You still provide necessary contextual information (such as country, city, or region).
  • Compliance with stricter data protection requirements (e.g. GDPR).

1. Required fields in the data layer

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'user_context',
  ip_hash: '1e4b9f1a3d7e... (hashed and salted value)',
  country: 'DE',
  region: 'Berlin',
  city: 'Berlin',
});

Field descriptions

FieldTypeDescription
ip_hashstringHashed (and salted) IP address. The hash ensures anonymity, and the salt prevents reverse-engineering.
countrystringCountry code (e.g. "DE", "FR", "US").
regionstringRegion or state.
citystringCity name.

2. How to prepare the IP address

All processing, including normalisation and hashing, should happen on your server. This ensures the raw IP address never leaves your infrastructure and that only anonymised data is shared with SegmentStream.

Step 1: Normalise IPv6 addresses (server-side)

IPv6 addresses are more detailed than IPv4 and can include device-specific parts. To ensure privacy, the IPv6 address should be normalised to keep only the network portion (the first half) and replace the device-specific bits with zeros.
TypeIPv6 exampleMeaning
Full IPv62001:0db8:85a3:0000:0000:8a2e:0370:7334Device-level identifier
Normalised2001:0db8:85a3:0000:0000:0000:0000:0000Network-level identifier (safe to hash)
// Run on your backend
function normalizeIPv6(ip) {
  if (!ip.includes(':')) return ip; // IPv4 - no normalization
  const segments = ip.split(':').slice(0, 4);
  while (segments.length < 8) segments.push('0000');
  return segments.join(':');
}
If the IP is IPv4, you can skip this step.

Step 2: Apply salted hashing (server-side)

After normalisation, hash the IP using a secure algorithm like SHA-256 and a private salt stored safely on your backend (e.g. in environment variables).
  • Do not hash or salt IPs in the browser.
  • The salt must remain secret and never be exposed to the client.
  • Only send the hashed IP and geo data to the frontend.
import crypto from 'crypto';

const SALT = process.env.IP_HASH_SALT; // store securely in environment variables

function hashIP(ip) {
  return crypto.createHash('sha256').update(ip + SALT).digest('hex');
}
Example output:
f2c992f0a9f8d5c8b87e1a2b36a52e5bce9df51de60cdb3eaf5d66a6dfdfe281

Step 3: Example of each stage

StepDescriptionExample
Full IPv6Original address2001:0db8:85a3:0000:0000:8a2e:0370:7334
NormalisedNetwork-only portion (safe to hash)2001:0db8:85a3:0000:0000:0000:0000:0000
Hashed (with salt)Final anonymised valuef2c992f0a9f8d5c8b87e1a2b36a52e5bce9df51...

3. Geolocation data

Use your own geolocation service (e.g. MaxMind, IP2Location, or a cloud provider’s API) to extract country and region information before hashing.

4. Example architecture

Below is a complete setup showing where each process occurs.

Server (Node.js / Python / etc.)

app.get('/api/user-context', async (req, res) => {
  const ip = getClientIP(req); // your logic for IP extraction
  const normalized = normalizeIPv6(ip);
  const hashed = hashIP(normalized);
  const geo = await lookupGeo(ip); // from your geolocation provider

  res.json({
    ip_hash: hashed,
    country: geo.country,
    region: geo.region,
    city: geo.city,
  });
});

Client (browser)

(async () => {
  const context = await fetch('/api/user-context').then(r => r.json());

  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'user_context',
    ip_hash: context.ip_hash,
    country: context.country,
    region: context.region,
    city: context.city,
  });
})();
This way:
  • The raw IP never leaves your infrastructure.
  • The client receives only anonymised and geo-enriched data.
  • SegmentStream operates in full privacy compliance.

5. Summary checklist

  • Normalise IPv6 addresses on the server.
  • Hash IPs with a private salt on the server.
  • Send only hashed IP + geo data to the browser.
  • Never expose the salt or raw IP in client code.
  • Ensure consistency and privacy compliance.