Event reference
All 18 Listings API webhook events, grouped by resource, with the exact fields and an example payload for each.
Eighteen events, grouped by the REST resource they relate to. Every event on
this page is delivered to your single webhooks URL. There is no per-event
subscription, so branch on event and ignore what you don't need.
All of them use the standard envelope
except listing.submission, which is called out below. Optional fields inside
data are omitted when empty rather than sent as null.
Index
Listings
Pairs with the Listings endpoints, in particular
GET /locations/{locationId}/listings/premium,
which returns the per-citation syncStatus and listingUrl this event
announces.
listing.submission
Trigger: a citation submission for one location on one directory site reaches a terminal state.
Top level:
Inside data:
{ "event": "listing.submission", "data": { "business_id": 279381, "v4_business_id": "TG9jYXRpb246Mjc5Mzgx", "location_id": "TG9jYXRpb246Mjc5Mzgx", "site": { "id": 42, "name": "Yelp", "url": "https://www.yelp.com" } }, "status": "success", "live_link": "https://www.yelp.com/biz/acme-dental-downtown"}Locations
Location lifecycle, 1:1 with createLocation,
updateLocation and
archiveLocations. Location-scoped:
location_id is always a numeric string.
profile.created
Trigger: a new location is created.
{ "event": "profile.created", "timestamp": "2026-08-25T10:04:00Z", "account_id": 11073, "location_id": "901234", "data": { "source": "api" }}profile.updated
Trigger: an existing location's details are edited.
Debounced to one delivery per location per 60 seconds, on the leading edge.
Edits inside the window are collapsed, not delayed. They never arrive. Treat
changed_fields as a hint about the edit that opened the window, not as a
complete diff.
The event arrives at the start of the window, so reading the location back when it lands shows you only that first edit. Schedule a second read-back once the window has closed — at least 60 seconds later — and reconcile locations on a timer too, since this event gets one delivery attempt and no retry. See recovering from a missed event.
{ "event": "profile.updated", "timestamp": "2026-08-25T10:06:12Z", "account_id": 11073, "location_id": "901234", "data": { "source": "user", "changed_fields": ["name", "phone"] }}profile.deleted
Trigger: a location is archived. This is a soft delete. There is no hard
delete, and an archive can be cancelled with
cancelArchiveLocations, which does not
emit an event.
{ "event": "profile.deleted", "timestamp": "2026-08-25T10:20:44Z", "account_id": 11073, "location_id": "901234", "data": { "source": "user" }}Connected accounts
Google and Facebook connection lifecycle and health, alongside the
Connected Accounts endpoints. Location-scoped.
platform is always google or facebook; other providers do not emit these
events.
connected_account_id is always present as a key, but is null on the two
Google verification events.
connection.location_connected
Trigger: a Google or Facebook listing is linked to a location.
{ "event": "connection.location_connected", "timestamp": "2026-08-25T14:32:10Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc" }}connection.location_disconnected
Trigger: a Google or Facebook listing is unlinked from a location.
{ "event": "connection.location_disconnected", "timestamp": "2026-08-25T14:35:02Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc" }}connection.reauth_required
Trigger: the connected account's credentials were invalidated. Nothing will sync for this connection until someone re-authorizes it.
{ "event": "connection.reauth_required", "timestamp": "2026-08-25T14:40:18Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc", "reason": "Google credentials are invalid. Please reconnect." }}connection.listing_inaccessible
Trigger: the connected account can no longer reach the location's listing.
Distinct from reauth_required: the credentials may still be perfectly valid,
but access to that particular listing was removed.
{ "event": "connection.listing_inaccessible", "timestamp": "2026-08-25T14:42:55Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "facebook", "connected_account_id": "cf12de77-2211-4a09-b7c1-0a6f3b2e91aa", "reason": "No longer has access to this listing." }}connection.google_verification_verified
Trigger: a location's Google Business Profile passes verification.
{ "event": "connection.google_verification_verified", "timestamp": "2026-08-25T14:50:00Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": null }}connection.google_verification_failed
Trigger: a Google Business Profile verification reaches a terminal failure. No REST call starts one; the status itself is readable, as above.
Only terminal states emit an event: VERIFIED fires the _verified event,
and SUSPENDED or DUPLICATE (failure_type rejected) and
ERROR_WHILE_FETCHING (transient) fire this one. The in-progress states
(PENDING_VERIFICATION, UNDER_REVIEW, NOT_VERIFIED, NOT_CONNECTED)
produce no event at all, so absence of an event is not a signal — poll
googleVerificationStatus on a location read while a verification is in
flight.
{ "event": "connection.google_verification_failed", "timestamp": "2026-08-25T14:52:31Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": null, "failure_type": "rejected", "reason": "This profile is suspended." }}Reviews
Reviews and responses, alongside the Reviews endpoints including respond, edit response and archive response.
Reviews in the Social category are filtered out and never delivered.
interaction.review
Trigger: a review is ingested or changes.
{ "event": "interaction.review", "timestamp": "2026-08-25T09:12:44Z", "account_id": 11073, "location_id": "279381", "data": { "interaction": { "id": "6f8a1d20-3e11-4a55-9f7d-2b0c9e5a4471", "type": "Review", "content": "Friendly staff and no waiting.", "rating": 5, "title": null, "author_name": "Dana R.", "author_avatar": "https://lh3.googleusercontent.com/a/example", "date": "2026-08-25T08:58:02Z", "source": "google.com", "permalink": "https://maps.google.com/example-review", "category": "Review", "interaction_status": "unread", "parent_id": null, "interaction_request_id": "3c1e9b74-88a2-4d0e-9c31-77a1f0be5d92" } }}interaction.response
Trigger: a response to a review is posted, edited, or archived. The same
shape as interaction.review, with two differences: type is Response, and
parent_id points at the review being responded to.
All the other fields listed under
interaction.review are present with the same meaning.
{ "event": "interaction.response", "timestamp": "2026-08-25T09:30:07Z", "account_id": 11073, "location_id": "279381", "data": { "interaction": { "id": "b2d7c095-5f43-4e21-8a10-6d9c3f77e208", "type": "Response", "content": "Thanks Dana, see you next time!", "rating": null, "author_name": "Acme Dental Downtown", "date": "2026-08-25T09:29:55Z", "source": "google.com", "permalink": "https://maps.google.com/example-review", "category": "Review", "interaction_status": "responded", "parent_id": "6f8a1d20-3e11-4a55-9f7d-2b0c9e5a4471", "interaction_request_id": "3c1e9b74-88a2-4d0e-9c31-77a1f0be5d92" } }}Posts
Google Business Profile local posts, alongside the Posts
endpoints. Location-scoped, location_id is a numeric string.
The four events share one data shape; the optional fields differ. All
optional fields are omitted when empty.
local_post.created
Trigger: a post item is created and queued for submission to Google. It is not live yet.
{ "event": "local_post.created", "timestamp": "2026-08-25T11:02:00Z", "account_id": 11073, "location_id": "279381", "data": { "post_id": 88421, "post_item_id": 5512309, "post_type": "STANDARD" }}local_post.published
Trigger: Google accepted the post and it is live.
{ "event": "local_post.published", "timestamp": "2026-08-25T11:06:41Z", "account_id": 11073, "location_id": "279381", "data": { "post_id": 88421, "post_item_id": 5512309, "post_type": "STANDARD", "post_external_id": "accounts/123/locations/456/localPosts/789" }}local_post.rejected
Trigger: Google rejected the post, or submitting it failed.
{ "event": "local_post.rejected", "timestamp": "2026-08-25T11:07:15Z", "account_id": 11073, "location_id": "279381", "data": { "post_id": 88421, "post_item_id": 5512310, "post_type": "OFFER", "rejection_reason": "Rejected" }}local_post.deleted
Trigger: the post item is deleted.
{ "event": "local_post.deleted", "timestamp": "2026-08-25T15:40:09Z", "account_id": 11073, "location_id": "279381", "data": { "post_id": 88421, "post_item_id": 5512309, "post_type": "STANDARD", "post_external_id": "accounts/123/locations/456/localPosts/789" }}Review analytics
Scheduled review roll-ups, one event per location per period.
Both events share one data shape:
A location with no activity in the period emits nothing — but so does a
location whose snapshot never made it. A missing snapshot is ambiguous, and
for this family the benign reading is the least likely one. It can mean: no
activity; a delivery that failed or timed out (there is one attempt and no
retry); delivery gated off because the account lacks the webhooks entitlement,
has no configured URL, or is unverified or blocked; or — most likely here — the
per-minute cap dropping part of the burst as rate_limited.
Never record a zero on the strength of an absent snapshot. Reconcile against
GET /locations/{locationId}/review-analytics-overview
for the same period, and if that read fails too, report the period as
unavailable rather than as zero.
review_analytics.daily_snapshot
Trigger: the daily roll-up job, once per location per day.
{ "event": "review_analytics.daily_snapshot", "timestamp": "2026-08-25T02:00:00Z", "account_id": 11073, "location_id": "279381", "data": { "period": "2026-08-24", "granularity": "daily", "total_reviews": 1240, "new_reviews_in_period": 3, "average_rating": 4.6667, "previous_average_rating": 5.0 }}review_analytics.weekly_snapshot
Trigger: the weekly roll-up job, once per location per week. period is
the first day of the week being summarized.
{ "event": "review_analytics.weekly_snapshot", "timestamp": "2026-08-24T02:00:00Z", "account_id": 11073, "location_id": "279381", "data": { "period": "2026-08-17", "granularity": "weekly", "total_reviews": 1237, "new_reviews_in_period": 18, "average_rating": 4.6123, "previous_average_rating": 4.5901 }}Events you may receive but should not build on
The platform emits other families: review campaigns, rankings, social posts
and boosts, social connections, AI post ideas, and Google Business Profile
ownership. They have no published REST surface in the Listings API, they are
not documented here, and their shapes are not covered by any compatibility
guarantee. Because there is one URL and no per-event subscription, your handler
should ignore any event it does not recognize and still return 200.