Integrations
What is connected
The payment provider and the data integrations for one site, with enough state to explain an empty panel.
curl --request GET \
--url 'https://truestat.io/api/v1/sites/{siteId}/integrations' \
--header 'Authorization: Bearer <token>'{
"data": {
"revenue": {
"import": {
"error": null,
"state": "done",
"imported": 3,
"finished_at": "2026-09-08T06:45:02Z"
},
"status": "active",
"provider": "stripe",
"last_error": null,
"account_name": "Codivupload",
"connected_at": "2026-09-08T06:44:12Z",
"last_event_at": "2026-09-16T19:03:44Z",
"account_currency": "usd",
"display_currency": "usd"
},
"platforms": [
{
"provider": "search_console",
"last_error": null,
"sync_state": "idle",
"property_id": "sc-domain:codivupload.com",
"account_email": "owner@example.com",
"last_synced_at": "2026-09-17T00:15:03Z",
"initial_sync_done": true
}
],
"revenue_visible": true
},
"meta": {
"site_id": "6fed8980-a119-4a9c-a4d4-53e448ef9f9e"
}
}What a site is connected to, and whether each connection is working.
No credential is ever returned
Not the provider key, not the webhook secret, not an OAuth token — in any form, on any endpoint. There is nothing to opt into and no header that changes it.
The keys are encrypted at rest with a key held outside the database, so they stay unreadable through every surface. But the reason they are absent here is simpler: nothing needs them. You supplied the key; you have it.
Two kinds of integration, two scopes
| Covered by | |
| Search Console, Google Analytics, social | settings:read |
| The payment provider | also needs revenue:read |
settings:read opens the endpoint. A key without revenue:read gets the
platforms and revenue: null.
That is a withholding, not a refusal — the two halves are independent, and a key issued to watch whether the Search Console sync is healthy has no reason to be told which payment provider you use, nor any reason to be denied the answer it did ask for.
revenue_visible says which null you got
{ "revenue": null, "revenue_visible": false }Without that flag, "no payment provider connected" and "this key may not see it" look identical — and a monitoring script would report a perfectly healthy site as unconnected.
revenue_visible: true,revenue: null→ nothing is connectedrevenue_visible: false→ the key needsrevenue:read
import.state answers "why is the revenue empty"
A freshly connected provider has no figures until the history import has run. That is a different question from whether the connection is healthy, so it has its own field:
| State | Meaning |
idle | Queued. The importer has not picked it up yet. |
running | Walking the provider's history now. |
done | Finished. imported says how many payments it wrote. |
failed | Stopped. error says why; it is not retried automatically. |
After connecting or re-syncing, this is the field to poll.
last_event_at answers "is it still working"
The last webhook that arrived.
It is stamped at connection rather than left null until the first sale — otherwise a merchant who connects on a quiet day and a connection whose key was revoked would look identical, both reporting nothing.
So silence means something: on a busy site, a last_event_at that has stopped
moving is the first thing to check.
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)pathrequiredResponse
The answer.
dataobjectmetaobjecterrorobjecterrorobjecterrorobjecterrorobject