Docs·Pages

GET/api/v1/event/analytics/web-analytics/pages

List top pages

Every page viewed in the date range, one row per path and hostname, with its views, visitors, sessions, time on page, entries and exits: the Pages tab of the Pages page. Rows are ranked by uniqueVisitors unless sortBy and sortDir say otherwise.

Page views count when they happened. Entries and exits come from sessions that started in the range, and exits only from sessions that have ended (the tracking script ends a session when its tab is hidden or closed).

Watch bounceRate on this endpoint: it is exits divided by pageViews, not the share of single-page sessions that the summary reports. The Pages page shows it in its Bounce column.

Keys: an account key. Getting started explains both kinds.

Parameters

PropInTypeNotes
contactListIdquerystringThe id of the audience (the tracked site) to read, a UUID: anything else returns a 400. You must be a member of the workspace the audience belongs to, or the call returns a 401. An id that matches no audience is not an error: the call returns no data.
startDatequerystringStart of the date range, read as UTC: a date such as 2026-09-01 (from midnight), or an exact time such as 2026-09-01T09:30:00Z. Use one of these two forms.
endDatequerystringEnd of the date range, read as UTC. A date such as 2026-09-30 includes that whole day; an exact time such as 2026-09-30T18:00:00Z ends the range right before that moment. If the workspace has gone past its plan's event allowance this billing period, the range is cut short at the moment the allowance ran out.
pagequerynumberPage number, starting at 0.
pageSizequerynumberRows per page.
search?querystringKeep only paths that contain this text, ignoring case.
filter?querystringNarrows the results: a URL-encoded JSON array of conditions, each [key, values, operator], where a missing operator means is. Example: [["country",["US","GB"]],["page",["/pricing"],"startsWith"]] keeps visits from the US or the UK that viewed a page starting with /pricing. Every condition must match, and each key can appear once (a second condition on the same key replaces the first). A condition matches any of its values, except that isNot, notContains and notRegex rule out all of them. Operators: is and isNot (exact), contains, notContains, startsWith and endsWith (ignoring case), regex and notRegex (RE2 syntax, so no lookarounds; a pattern that does not compile returns a 400), and isNull and isNotNull (the value is not set, or is set; send [] as the values). Keys: channel, referrer_source, referrer, utm_source, utm_medium, utm_campaign, utm_term, utm_content, country (a two-letter code), region, city, browser, browser_version, os, os_version, screen_size (Desktop, Mobile or Tablet), hostname, entry_page, exit_page, page and event_name (visits that viewed such a page or sent such an event), identified (["true"] or ["false"]), goal_id (people who completed the goal in the range) and cohort_id (members of a segment). The last two take ids and only is or isNot. Unknown keys, and a filter that is not valid JSON, are ignored rather than refused. Here a page or hostname condition also narrows the rows themselves, so filtering on /blog lists only /blog.
sortBy?queryPageSortByThe column to rank by: uniqueVisitors (the default, also accepted as visitors), revenue, path, pageViews, sessions, avgTimeOnPage, bounceRate, exits, entryRate or exitRate. Ranking by revenue leaves previousSessions out of the rows.
sortDir?querySortDirectiondesc (the default) puts the highest value first, or Z to A for a name or path; asc the reverse. The order covers every page, not just the one returned.

Response

PropTypeNotes
contentPageAnalyticsRow[]One row per path and hostname.
sizenumberThe pageSize you asked for.
pagenumberThe page you asked for, counted from 0.
totalItemsnumberRows across all pages.
totalPagesnumbertotalItems divided by size, rounded up.

Each item in content

PropTypeNotes
pathstringThe page path, without query string or trailing slash (the home page is /).
hostnamestringThe hostname the page was on.
titlestringThe most recent non-empty page title seen for this path, '' when none was ever sent.
uniqueVisitorsnumberDistinct visitors who viewed the page.
pageViewsnumberTimes the page was viewed.
sessionsnumberDistinct sessions that viewed the page.
previousSessionsnumbersessions over the period of the same length right before the range, 0 when there were none. Left out when sortBy=revenue.
avgTimeOnPagenumberAverage time on the page in milliseconds, over the views where a time was recorded. The time is reported when the visitor moves to the next page or the session ends.
bounceRatenumberexits divided by pageViews, as a percentage from 0 to 100 with two decimals. Despite the name, this is not the session bounce rate.
exitsnumberSessions that started in the range, have ended, and whose last page was this one.
entryRatenumberSessions that started on this page, as a percentage of all sessions that started in the range (0 to 100).
exitRatenumberexits as a percentage of all sessions that started in the range (0 to 100). /exit-pages divides by page views instead.
revenuenumberEverything the page's visitors paid in the range, net, in the audience's reporting currency (Settings → Revenue). A visitor counts on every page they viewed, so rows add up to more than the total.

Request

curl 'https://app.spreelytics.com/api/v1/event/analytics/web-analytics/pages?contactListId=…&startDate=…&endDate=…&page=…&pageSize=…' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const url = new URL('https://app.spreelytics.com/api/v1/event/analytics/web-analytics/pages');
url.searchParams.set('contactListId', '…');
url.searchParams.set('startDate', '…');
url.searchParams.set('endDate', '…');
url.searchParams.set('page', '…');
url.searchParams.set('pageSize', '…');

const res = await fetch(url, {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
});
const data = await res.json();
import requests

res = requests.get(
    "https://app.spreelytics.com/api/v1/event/analytics/web-analytics/pages",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"contactListId": "…", "startDate": "…", "endDate": "…", "page": "…", "pageSize": "…"},
)
data = res.json()

Response

{
  "content": [
    {
      "path": "string",
      "hostname": "string",
      "title": "string",
      "uniqueVisitors": 0,
      "pageViews": 0,
      "sessions": 0,
      "previousSessions": 0,
      "avgTimeOnPage": 0,
      "bounceRate": 0,
      "exits": 0,
      "entryRate": 0,
      "exitRate": 0,
      "revenue": 0
    }
  ],
  "size": 0,
  "page": 0,
  "totalItems": 0,
  "totalPages": 0
}

See your own numbers today.

Free up to 100k events a month · no credit card

Contact

Tell us what you need.

A real person reads these. We usually reply within one working day.

Or email us directly at contact@spreelytics.com.