Google connection activity
Overview
Get the connection events for every location under your partner, with funnel counts: sign-ins started, connections, failed sign-ins, sign-ins that found no locations, and disconnects.
Use this to follow up with owners who haven't finished connecting.
You'll need a partner token; filter by date or account.
Returns the event feed and the funnel totals. The totals count every event that matches your filters, not just the current page. Events are newest first, and paginated.
Prerequisites
- A Partner token. See Authentication.
- Optional: an account id (
company_id) or a location id (store_id) to filter by.
Base URL
| Environment | URL |
|---|---|
| Production | https://production-api.shoutaboutus.com |
| Development | https://development-api.shoutaboutus.com |
Endpoint
GET /api/v1/partner/gbp-connection-events
Authentication
Partner token
- Returns only events for your own partner. A
company_idorstore_idfrom outside your partner matches nothing. - Any other token gets
403.
Rate limit
This endpoint has no rate limit.
Request parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
from | query | string (date) | No | Only events on or after this day, for example 2026-06-01. |
to | query | string (date) | No | Only events up to and including this day. Must be on or after from. |
event | query | string | No | One event type: oauth.started, oauth.denied, oauth.callback_error, token.exchange_failed, token.scope_not_granted, token.refresh_failed, locations.fetched, locations.none_found, connection.connected, connection.reconnected, connection.account_switched, connection.disconnected_manual, connection.disconnected_auto, respond.opted_in or respond.opted_out. |
source | query | string | No | Where the event happened: invite_link, connect_google_page, registration, settings, debugger, app, system or unknown. |
company_id | query | integer | No | Only events for this account and every location under it. |
store_id | query | integer | No | Only events for this location. |
search | query | string | No | Part of the connected Google account's email address. Up to 255 characters. |
page | query | integer | No | Page number, from 1. Default 1. |
limit | query | integer | No | Events per page, 10 to 100. Default 10. Values below 10 are raised to 10; above 100 returns 422. |
Request body
None.
Request payload
None.
Response body
The payload is inside data.
| Field | Type | Description |
|---|---|---|
kpis.logins_started | integer | Google sign-ins started (oauth.started). |
kpis.connections | integer | Locations connected, reconnected or switched to another Google location. |
kpis.failed_logins | integer | Sign-ins that failed: declined consent, callback errors, failed token exchanges, missing permissions. |
kpis.no_locations_found | integer | Sign-ins where the Google account had no locations. |
kpis.disconnects | integer | Disconnections, by the user or because the connection was lost. |
events.data[] | array | The events on this page, newest first. |
events.data[].id | integer | The event's id. |
events.data[].event | string | The event type (see event above). |
events.data[].source | string or null | Where it happened (see source above). |
events.data[].store_id | integer or null | The location's id. |
events.data[].store_name | string or null | The location's name. |
events.data[].google_email | string or null | The Google account's email address. |
events.data[].error_code | string or null | The error code, for failed events. |
events.data[].message | string or null | The error message, for failed events. |
events.data[].details | string | A readable summary of the event, with any error code and message after it. |
events.data[].user_email | string or null | The email of the user who triggered the event. |
events.data[].created_at | string | When the event happened (ISO 8601). |
events.current_page | integer | The page number. |
events.per_page | integer | Events per page. |
events.total | integer | Events matching your filters. |
events.last_page | integer | The last page number. |
events.from / events.to | integer or null | The positions of the first and last event on this page. |
events.first_page_url / events.last_page_url / events.next_page_url / events.prev_page_url | string or null | Page links. next_page_url and prev_page_url are null at the ends. |
events.path | string | The endpoint URL without the query string. |
events.links | array | Page links for a pager: url, label, active. |
Response payload
{
"data": {
"kpis": {
"logins_started": 42,
"connections": 30,
"failed_logins": 7,
"no_locations_found": 3,
"disconnects": 2
},
"events": {
"current_page": 1,
"data": [
{
"id": 101,
"event": "connection.connected",
"source": "invite_link",
"store_id": 3007,
"store_name": "Acme Coffee Downtown",
"google_email": "[email protected]",
"error_code": null,
"message": null,
"details": "Location connected successfully",
"user_email": "[email protected]",
"created_at": "2026-07-07T09:15:00+00:00"
},
{
"id": 100,
"event": "token.exchange_failed",
"source": "connect_google_page",
"store_id": 3008,
"store_name": "Acme Coffee Uptown",
"google_email": null,
"error_code": "invalid_grant",
"message": "Auth code expired",
"details": "invalid_grant — Auth code expired",
"user_email": null,
"created_at": "2026-07-07T08:02:11+00:00"
}
],
"first_page_url": "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events?page=1",
"from": 1,
"last_page": 9,
"last_page_url": "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events?page=9",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events?page=1",
"label": "1",
"active": true
},
{
"url": "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events?page=2",
"label": "Next »",
"active": false
}
],
"next_page_url": "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events?page=2",
"path": "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events",
"per_page": 10,
"prev_page_url": null,
"to": 10,
"total": 84
}
}
}Examples
Success payload
See Response payload.
Error payload
403 Not a Partner token
{
"message": "Only partner-level users can view Google connection activity.",
"status": "error",
"errors": []
}422 Invalid filters
{
"message": "The to field must be a date after or equal to from. (and 1 more error)",
"errors": {
"to": [
"The to field must be a date after or equal to from."
],
"event": [
"The selected event is invalid."
]
}
}422 limit above 100
{
"message": "The limit field must not be greater than 100.",
"errors": {
"limit": [
"The limit field must not be greater than 100."
]
}
}| Status | Meaning |
|---|---|
200 | The totals and a page of events. |
401 | The token is missing, expired or invalid. |
403 | The token isn't a Partner token. |
422 | A filter is invalid, or limit is above 100. |
500 | Unexpected server error. |
Example request
curl --request GET \
--url "https://production-api.shoutaboutus.com/api/v1/partner/gbp-connection-events?from=2026-06-01&to=2026-06-30&page=1&limit=10" \
--header 'Authorization: Bearer <bearer-token>' \
--header 'Accept: application/json'Updated 17 days ago
Did this page help you?
