Visitor profiles
Per-visitor records with lifetime pageview, event and revenue totals, plus an activity timeline.
2 endpoints, all relative to https://analytics.appfor.you. Shared rules live in Conventions, Rate limits and Error codes.
List profiles
GET
/api/v2/sites/{siteId}/profilesscope: readProfiles are lifetime records. Date parameters are optional here: pass `range`, or `from` together with `to`, to additionally restrict on `lastSeenAt`; omit them to get the full lifetime list.
- The `q` search input is regex-escaped before use, so it is safe to pass raw user input.
Path parameters
| siteId | string | The Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere. |
Query parameters
| Name | Type | Description |
|---|---|---|
| q | string | Free-text search (max 100 chars), case-insensitive, over email, identifiedId, name and anonymousId. |
| tag | string | Match a profile tag. |
| country | string | Match `lastCountry`. |
| device | string | Match `lastDevice`. |
| identified | 'true' | 'false' | Only identified or only anonymous profiles. Must be exactly `true` or `false`, otherwise 400. |
| sort | string | One of lastSeenAt, firstSeenAt, totalRevenue. Default `lastSeenAt`; unknown values fall back to it. `totalPageviews` and `totalEvents` are deliberately NOT sortable: both counters are incremented on essentially every pageview, so the indexes such a sort would need are too expensive to maintain on that write path. |
| dir | 'asc' | 'desc' | Sort direction. Default `desc`. |
| range | string | Relative window: `today`, `7d`, `30d`, `90d`, `6m` or `12m`. Default `7d`. Ignored when both `from` and `to` are supplied. |
| from | string (YYYY-MM-DD) | Explicit window start (inclusive), from `T00:00:00.000Z` on that day. Supply together with `to` to override `range`. An unparseable value, a window that ends before it starts, or a window that starts in the future returns 400. |
| to | string (YYYY-MM-DD) | Explicit window end (inclusive) — the WHOLE day, through `T23:59:59.999Z`, clamped to now when it is in the future. `from=X&to=X` is therefore a full 24-hour day. Supply together with `from` to override `range`. An unparseable value, a window that ends before it starts, or a window that starts in the future returns 400. |
| limit | integer | Rows to return. Default 50, minimum 1, maximum 500. |
| offset | integer | Rows to skip, for paging. Default 0. |
Example request
curl -H "Authorization: Bearer $ANALYTICS_API_KEY" \ "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/profiles?identified=true&sort=totalRevenue&limit=20"
Example response
{
"profiles": [
{
"_id": "65121108bcf86cd799439118",
"siteId": "6507f1f77bcf86cd799439011",
"anonymousId": "s_9f2c...",
"identifiedId": "user_8412",
"email": "ada@example.com",
"name": "Ada Lovelace",
"tags": ["trial"],
"lastCountry": "GB",
"lastDevice": "desktop",
"totalPageviews": 84,
"totalEvents": 12,
"totalRevenue": 24000,
"firstSeenAt": "2025-01-04T11:02:00.000Z",
"lastSeenAt": "2025-03-20T18:41:00.000Z"
}
],
"total": 1,
"limit": 20,
"offset": 0
}Get a profile
GET
/api/v2/sites/{siteId}/profiles/{profileId}scope: readThe timeline interleaves the most recent events and pageviews for the profile, newest first — 25 of each by default, or `limit` of each when `limit` is supplied (max 500).
- The profile must belong to `{siteId}`. An invalid id, or a profile from another site, returns 404 "Profile not found".
Path parameters
| siteId | string | The Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere. |
| profileId | string | Identifier of the visitor profile. |
Query parameters
| Name | Type | Description |
|---|---|---|
| limit | integer | Timeline entries to fetch from EACH source (events and pageviews). Default 25, max 500. |
Example request
curl -H "Authorization: Bearer $ANALYTICS_API_KEY" \ "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/profiles/65121108bcf86cd799439118"
Example response
{
"profile": {
"_id": "65121108bcf86cd799439118",
"siteId": "6507f1f77bcf86cd799439011",
"anonymousId": "s_9f2c...",
"email": "ada@example.com",
"totalPageviews": 84,
"totalRevenue": 24000,
"lastSeenAt": "2025-03-20T18:41:00.000Z"
},
"timeline": [
{
"type": "event",
"name": "signup_click",
"pathname": "/pricing",
"metadata": { "plan": "pro" },
"timestamp": "2025-03-20T18:41:00.000Z"
},
{
"type": "pageview",
"pathname": "/pricing",
"duration": 42,
"timestamp": "2025-03-20T18:39:00.000Z"
}
]
}