# Server-side sessions and session hints

> How server-side events are grouped into visits with the daily salted visit key and how session_hint splits or joins visits.

Server-side events join visits exactly like browser hits.

## The visit key

The visit key is an HMAC of the **daily salt**, the site, the visitor's
IP and User-Agent (and your `session_hint`, if you send one). The key lives
only in memory (Redis, no persistence) for 30 minutes of inactivity and
never past midnight UTC. The salt is random, rotates daily and is never
stored, so the key can't be recomputed later.

- Forward the **visitor's** IP and User-Agent, not your server's, or every
  visitor looks like one person.
- If you send the same IP and User-Agent from the browser tracker and from
  the server, server events join the visitor's browser visit: a purchase
  confirmed by a webhook is attributed to the campaign that brought the
  visitor. For that, the webhook needs the IP and User-Agent from the
  original checkout request. Store them with the order only for as long as
  the checkout takes, then delete them.

## `session_hint`

An optional opaque string, for example a cart id or a job id:

```json
{ "type": "event", "name": "Checkout step", "url": "https://example.com/checkout", "session_hint": "cart_8f2a…", "user_agent": "…" }
```

It's added to the HMAC input, so:

- events with the same hint (and the same IP/User-Agent) form one visit,
- events with different hints are separate visits, even from the same IP
  and User-Agent (for example, many users behind one office proxy, or a
  backend without the visitor's IP).

The hint is **never stored**: it's hashed together with the daily salt and
discarded. Still, don't use emails or user ids as hints. A random id per
cart or session is enough.

## Timestamps

A `timestamp` up to 72 hours old places the event at that time. Visits are
still keyed by the day the event happened (UTC), so late events join the
right day's visit only if that visit is still in memory (30 minutes
idle). Older back-fills create their own visits.
