Skip to main content

Live

Where they are

The countries of the people currently on your site.

GET/sites/{siteId}/realtime/countries
Where they are
curl --request GET \
  --url 'https://truestat.io/api/v1/sites/{siteId}/realtime/countries' \
  --header 'Authorization: Bearer <token>'
{
  "data": [
    {
      "views": 2,
      "visitors": 1,
      "country_code": "US"
    }
  ],
  "meta": {
    "page": {
      "limit": 100,
      "offset": 0,
      "has_more": false
    },
    "minutes": 30,
    "site_id": "6fed8980-a119-4a9c-a4d4-53e448ef9f9e"
  }
}

The people on your site right now, grouped by country.

Takes minutes rather than a window, like every live endpoint — see online now for what a lookback is and why crawlers are never counted.

These rows do not add up to online

That is intentional, and it is the one thing worth knowing before you build anything on this endpoint.

Some visits arrive without geo headers. Those visitors are real, they are counted in online now, and they cannot be placed on a map — so they have no row here.

The alternatives were both worse. A row with a blank label reads as a bug in your dashboard. A row labelled "Unknown" invites treating a gap in measurement as a place, and people put it on charts next to real countries.

So the country list is the placeable subset, and the complete total lives on /realtime. If you show both, take the headline from there.

The default lookback is different here

This endpoint defaults to 30 minutes; /realtime defaults to 10.

That matches the dashboard, where the counter is tighter than the map. But it means calling both with no parameters and comparing them is misleading — you will see a smaller headline than the map's rows suggest, and nothing is wrong.

Pass the same minutes to both when they sit next to each other:

GET /sites/{siteId}/realtime?minutes=30
GET /sites/{siteId}/realtime/countries?minutes=30

Verified on a live site: at minutes=10 both returned 0, at 30 both returned 1, at 60 both returned 2. Matched lookbacks agree exactly.

Paging

Ordered by visitors. limit and offset work as everywhere else, and meta.page.has_more is measured rather than inferred from the row count.

Authorizations

Authorizationstringheaderrequired

An API key from Settings → API keys. Scopes available: analytics:read, sites:read, sites:write, settings:read, settings:write, goals:read, goals:write, funnels:read, funnels:write, notes:read, notes:write, alerts:read, alerts:write, team:read, team:write, revenue:read, revenue:write.

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path parameters

siteIdstring (uuid)pathrequired
The site's id, from `GET /sites`. A site that is not yours and a site that does not exist both answer 403, so this cannot be used to discover other people's ids.

Query parameters

minutesintegerquery
How far back to look, in minutes. A visitor counts as present if they did something within it. Refused above 360 rather than clamped — past that the question is no longer 'who is here' and `/timeseries` answers it better.
limitintegerquerydefault: 100
Rows per page, 1 to 1000.
offsetintegerquerydefault: 0
Rows to skip.

Response

application/json

The answer.

dataunknown
See the example.
metaobject