Docs·Tracking
/1.0/track/statsGet visitor stats
Returns the counters Spreelytics keeps for one visitor, meaning one browser: how many pages it has viewed and how many visits it has made on your site, and when it last did each. It is the only Tracking API route that reads anything back, and all it reads is this one visitor's counters. Your reports are in the reporting API.
The tracking script asks for these counts two seconds after every pageview, for its own use. It does not show them or hand them to your code. Call the route yourself when your page needs them, for example to show a returning visitor something different from a first-time one.
The request
GET https://sdk.spreelytics.com/1.0/track/stats, with two query parameters:
| Parameter | Required | What it is |
|---|---|---|
clientKey | Yes | Your client key, from Settings → API keys, under Site tracking key. |
visitorId | Yes | The visitor to look up. On a page that runs the script, Spreelytics.getVisitorId() returns it. Without it, the request fails with 400. |
There is no way to look up a person. The counters belong to one browser, so someone who uses two devices has two sets of them, even after you identify them.
The answer
| Field | Type | What it is |
|---|---|---|
success | boolean | Always true. |
pageCount | number | The pageviews recorded for this visitor, ever. |
visitCount | number | The visits recorded for this visitor: the pageviews that were sent with isEntryPage: true. |
currentSessionId | string or null | The session id of the visitor's latest visit. It stays set after that visit ends. |
lastPageAt | string or null | The timestamp of the visitor's latest recorded pageview, exactly as it was sent. |
lastVisitAt | string or null | The timestamp of the pageview that started the visitor's latest visit, exactly as it was sent. |
A visitor id that Spreelytics has never seen is not an error. The answer has pageCount and
visitCount at 0, and null in the other three fields.
How fresh the counts are
Pageviews are recorded in the background, so a pageview reaches these counts shortly after it is sent. That is why the script waits two seconds before it asks. A count read straight after a pageview can still be missing it.
What it answers
| Answer | What it means |
|---|---|
200 with JSON | The counts, as above. |
200 with the body OK | Dropped: the User-Agent belongs to a bot, a tool or an HTTP library, or the request comes from a cloud address. The body is plain text, not JSON, so check the Content-Type before you parse it. |
400 | visitorId is missing. |
401 with the body Event API: Unauthorised | No client key, an unknown client key, or a request from a site that is not in Allowed domains (Settings → Details). |
The same User-Agent and address checks apply here as on the other tracking routes; the hard limit on
your plan's allowance does not. The full rules are in
What the Tracking API drops. From a server, send a
browser's User-Agent and, when the audience has Allowed domains, an Origin header with a
hostname from the list.
On a cookieless audience
With cookieless tracking on, the visitor id is made by the collector rather than the
browser, and a visitor gets a new one each day. Spreelytics.getVisitorId() returns it once the
script's first call to the collector has come back, and the counts cover the current id only, so
they start again from zero every day.
Request
# curl's own User-Agent is dropped as a tool, so this sends a browser's.
curl 'https://sdk.spreelytics.com/1.0/track/stats?clientKey=YOUR_CLIENT_KEY&visitorId=vid_6f1c2a4e-8d3b-4c55-9a7e-2b8f0c9d1e23' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36' \
-H 'Origin: https://www.example.com'
// On a page that runs the tracking script.
const visitorId = Spreelytics.getVisitorId();
if (visitorId) {
const url = new URL('https://sdk.spreelytics.com/1.0/track/stats');
url.searchParams.set('clientKey', 'YOUR_CLIENT_KEY');
url.searchParams.set('visitorId', visitorId);
const res = await fetch(url);
// A dropped request answers 200 with the text OK, so check before parsing.
const isJson = res.headers.get('content-type')?.includes('application/json');
const stats = isJson ? await res.json() : null;
if (stats?.visitCount > 1) {
// A returning visitor.
}
}
import requests
res = requests.get(
"https://sdk.spreelytics.com/1.0/track/stats",
params={"clientKey": "YOUR_CLIENT_KEY", "visitorId": visitor_id},
headers={
# The visitor's own User-Agent. The requests default is dropped as a tool.
"User-Agent": visitor_user_agent,
# A hostname from Allowed domains.
"Origin": "https://www.example.com",
},
)
is_json = res.headers.get("content-type", "").startswith("application/json")
stats = res.json() if is_json else None
Response
{
"success": true,
"pageCount": 12,
"visitCount": 3,
"currentSessionId": "sess_0b7d9e4a-3c21-4f6a-8e5d-7a9c1b2d3e4f",
"lastPageAt": "2026-10-01T09:36:12.000Z",
"lastVisitAt": "2026-10-01T09:30:00.000Z"
}
Related
- Track a pageview: the pageviews these counts are made of.
- Identify a visitor: tie a browser to a person, for numbers that span devices.
- Profiles: a visitor's full history in the app.