Search Console
Totals
Clicks, impressions and average position from Google Search Console.
curl --request GET \
--url 'https://truestat.io/api/v1/sites/{siteId}/search/totals' \
--header 'Authorization: Bearer <token>'{
"data": {
"ctr": 0.013,
"clicks": 129,
"partial": true,
"position": 31.49,
"impressions": 9920
},
"meta": {
"range": {
"to": "2026-09-16T00:00:00.000Z",
"tz": "UTC",
"from": "2025-09-16T00:00:00.000Z",
"clamped": false
},
"site_id": "6fed8980-a119-4a9c-a4d4-53e448ef9f9e"
}
}The headline Search Console figures for a window.
These are Google's numbers, not ours
Everything under /search/ is imported from Google Search Console. It is the
one part of the API that does not come from your site's script, and it will
not reconcile with the rest — by design, not by fault.
| Search Console | The rest of TrueStat | |
| What a "click" is | Somebody clicked your result in Google | Somebody arrived and the script ran |
| Method | Sampled and rounded by Google | Counted |
| Day boundary | Pacific time | Whatever tz you pass |
So clicks here and visitors on
overview will differ, and the difference
grows with how many people click and leave before the page finishes loading.
Neither number is wrong; they are answers to different questions.
Use these figures for how you appear in Google, and the site's own figures for what happens after the click.
position is already averaged correctly
Average position cannot be computed by averaging positions. A term seen ten thousand times at position 3 and one seen twice at position 90 do not average to 46.5 — the first is what nearly everybody saw.
The figure returned here is impression-weighted, which is the only correct mean. You do not need to weight it yourself, and you should not average several of these together without re-weighting by impressions.
partial means the number will grow
Google fills in recent days over the following hours. When your window
includes one of those, partial is true.
Present that. A figure shown as final and then larger tomorrow reads as a drop that never happened, and it is the most common way a Search Console panel misleads its own reader.
No connection returns null, not an error
If the site has no Search Console connection, data is null with a normal
200. That is a configuration state, not a failed request — a 404 would say
you asked for the wrong thing, which is not true.
A window with no impressions also returns null, and the two are not
distinguished: both lead to the same empty panel, and a caller that has to
tell them apart wants
the integration status rather than this
endpoint.
Authorizations
AuthorizationstringheaderrequiredAn 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)pathrequiredQuery parameters
periodenum<string>querytodayyesterdaylast24hlast7dlast30dlast12mmonthyearallfromstring (date-time)querytostring (date-time)querytzstringquerydefault: UTCbotsenum<string>querydefault: excludedexcludedincludedResponse
The answer.
dataobjectmetaobjecterrorobjecterrorobjecterrorobjecterrorobject