# What we store

> Every field Kymo records for a human event and a bot event, and the list of things it deliberately never stores.

Canonical: https://kymo.in/docs/trust/what-we-store
Last updated: 2026-08-11

This is the complete picture of what a Kymo event row contains. Nothing here identifies a person across a day or a site.

## A human event

| Name | Type | Required | Description |
|---|---|---|---|
| `site` | text | yes | Your domain. |
| `path` | text | yes | The page path, capped at 200 chars. |
| `kind` | text | yes | pageview, outbound, or goal. |
| `target` | text | no | Outbound URL or goal name (non-pageviews). |
| `value` | number | no | Goal revenue. |
| `referrer` | text | no | Referrer hostname only; self-referrals dropped. |
| `country / city` | text | no | Coarse geolocation from the request edge headers; no IP stored. |
| `lat / lng` | number | no | Coarse coordinates from the request edge headers, for the map. |
| `device` | text | no | mobile or desktop, derived from width and UA. |
| `browser` | text | no | Browser name derived from the UA (e.g. Chrome). |
| `visitor` | text | yes | The daily-rotating hash. Not reversible, not cross-day. |
| `utm_source / medium / campaign` | text | no | UTM parameters of this visit — the last touch — on pageviews. |
| `ft_source / ft_medium / ft_campaign / ft_term / ft_content` | text | no | UTM parameters of the visit that first brought this browser to the site. |
| `ft_referrer / ft_landing` | text | no | Referrer and landing path of that first visit. Null when attribution is off. |
| `ft_at` | timestamp | no | When that first visit happened, from the visitor browser. |
| `created_at` | timestamp | yes | Server receive time, UTC. |

## A bot event

AI-crawler and search-crawler hits are stored with the crawler's classification instead of a visitor:

| Name | Type | Required | Description |
|---|---|---|---|
| `kind` | text | yes | The literal 'bot'. |
| `bot_provider` | text | no | e.g. ChatGPT, Perplexity, Googlebot. |
| `bot_category` | text | no | ai_answer, indexing, or training. |
| `status` | number | no | The HTTP status the crawler received. |
| `visitor` | text | yes | The literal 'bot' — no hash; a bot is not a person. |

## Never stored

- Raw IP addresses.
- Raw user-agent strings from human visitors. (AI crawler user-agents are kept on the crawler's own event row, so a classification can be audited and corrected. A crawler is not a person.)
- Full referrer URLs with their query strings.
- Cookies — on your site or on Kymo.
- Any cross-day or cross-site identifier. The first-touch key `beat.js` writes on your own domain holds a traffic source and a timestamp, and no identifier of any kind — see [First-touch attribution](https://kymo.in/docs/guides/attribution).
- Names, emails, or form field contents. (A goal name or revenue you pass with `window.kymo` is stored as you send it — so do not put personal data there.)

See [Privacy model](https://kymo.in/docs/trust/privacy) for how identity works without any of the above.

## Data attribution

Kymo identifies the network a crawler request came from using a local IP-to-ASN
database. The lookup happens in memory and the address is discarded immediately;
it is never stored, as stated above.

That database is built from three sources, each licensed under a
[Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/):

- <a href="https://db-ip.com">IP Geolocation by DB-IP</a>
- IP-to-AS data by [Route Views](https://routeviews.org)
- Address allocation statistics by the [NRO](https://nro.net)
