Docs·Web analytics

GET/api/v1/event/analytics/web-analytics/:dimension

Get a breakdown

A ranked list of the values of one dimension in the date range, each with its visitors and revenue: the data behind the Overview page's Breakdowns cards. The last part of the path picks the dimension:

  • channels: how the visit arrived, such as Organic Search, Paid Social or Direct.
  • sources: the referring source, such as Google or ChatGPT, or the referring site's host. Visits with none read Direct/None.
  • referrers: the referring address, as host and path. Add source to list one source's addresses only.
  • utm_sources, utm_mediums, utm_campaigns, utm_terms and utm_contents: the value of that UTM tag on the page the visit landed on.
  • countries: two-letter country codes, such as US.
  • regions and cities: names, each row with the countryCode it is in.
  • browsers and operating-systems: names, such as Chrome or Windows.
  • browser-versions and operating-system-versions: versions (major and minor, such as 120.0) of the one browser or system named in browser or os, which these two paths require.
  • devices: Desktop, Mobile or Tablet.

A visitor is counted under every value their sessions in the range had, so uniqueVisitors can add up to more than the total. Sessions with no value for the dimension are left out, except on sources, where they form the Direct/None row.

Revenue means two different things here. On the acquisition lists (channels, sources, referrers and the five UTM lists) it is attributed: each payment in the range is credited to the buyer's non-direct visits in the lookback window before it, following model and window. Revenue no visit can take, such as payments from visitors who only ever came direct, goes on the Direct row of channels and the Direct/None row of sources, so those two lists add up to the revenue in the summary; the UTM and referrer lists add up only to the share that came through tagged visits. A row can show revenue with 0 visitors when the visit that earned it came before the range. On every other list, a row's revenue is everything the people behind its visitors paid in the range, net of refunds, counted again under each value they appear under, so those rows can add up to more than the total. A payment sent from a server with no visitor id still counts there when its email matches someone we know.

Rows are ranked by uniqueVisitors unless sortBy and sortDir say otherwise, and paged with page and pageSize.

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

Paths

Path
/analytics/web-analytics/channels
/analytics/web-analytics/sources
/analytics/web-analytics/referrers
/analytics/web-analytics/utm_sources
/analytics/web-analytics/utm_mediums
/analytics/web-analytics/utm_campaigns
/analytics/web-analytics/utm_terms
/analytics/web-analytics/utm_contents
/analytics/web-analytics/countries
/analytics/web-analytics/regions
/analytics/web-analytics/cities
/analytics/web-analytics/browsers
/analytics/web-analytics/browser-versions
/analytics/web-analytics/operating-systems
/analytics/web-analytics/operating-system-versions
/analytics/web-analytics/devices

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 the values that contain this text, ignoring case. On the version lists it is matched against the version.
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.
sortBy?queryDimensionSortByThe column to rank by: uniqueVisitors (the default, also accepted as visitors), revenue or name. The version lists also take version, which ranks the same as name.
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.
model?querystringAcquisition lists only (channels, sources, referrers and the UTM lists). How a payment is credited to the visits that led to it: last_touch gives all of it to the buyer's last non-direct visit before paying, linear splits it evenly among all their non-direct visits in the lookback window (see window). Direct visits never take credit. Left out, the audience's choice in Settings → Revenue applies (last-touch unless someone changed it). Any other value returns a 400.
window?querynumberAcquisition lists only. Lookback window in days: how long before a payment a visit can be and still take credit. A whole number from 1 to 90; anything else returns a 400. Left out, the audience's setting in Settings → Revenue applies (30 days unless someone changed it).
source?querystringreferrers only: a source exactly as sources returns it, such as Google, to list that source's referring addresses. Left out, every referring address is listed.
browserquerystringbrowser-versions only, and required there: the browser exactly as browsers returns it, such as Chrome.
osquerystringoperating-system-versions only, and required there: the system exactly as operating-systems returns it, such as Windows.

Response

PropTypeNotes
contentSessionDimensionRow[]One row per value, ranked by sortBy.
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
namestringThe value, as described above. On the version lists it is the browser or system with its version, such as Chrome 120.0.
uniqueVisitorsnumberDistinct visitors with a session in the range that had this value. On the acquisition lists it can be 0 for a row that only earned revenue.
revenuenumberIn the reporting currency, two decimals: attributed revenue on the acquisition lists, everything the people behind the row's visitors paid on the others (see above).
topSourcesDimensionTopSource[]Acquisition lists only: how the row's revenue splits by source (the referring site, such as Google), as { name, uniqueVisitors, revenue }, largest first. It ends with a Direct entry for credit from visits with no source and, on the Direct and Direct/None rows, for the revenue no visit could take, so the entries add up to the row's revenue. uniqueVisitors counts the row's visitors from each source. When the row has no revenue, the entries are ordered by visitors instead.
countryCodestringregions and cities only: the two-letter code of the country the place is in.

Request

curl 'https://app.spreelytics.com/api/v1/event/analytics/web-analytics/channels?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/channels');
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/channels",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"contactListId": "…", "startDate": "…", "endDate": "…", "page": "…", "pageSize": "…"},
)
data = res.json()

Response

{
  "content": [
    {
      "name": "string",
      "uniqueVisitors": 0,
      "revenue": 0,
      "topSources": [
        {
          "revenue": null,
          "uniqueVisitors": null,
          "name": null
        }
      ],
      "countryCode": "string"
    }
  ],
  "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.