Google Business Profile
Reviews of your customers' business locations, and the owner's replies, through your Google Cloud project with the single business.manage scope.
The permissions each capability needs are in App Review: Google Business Profile.
- One Connected Profile is one location, so connecting a grant once discovers every location under every account it administers — a chain connects all its shops from one Connection.
- Reviews are read-only: Google exposes no method that creates, edits, hides, deletes, or flags a review, so replying is the only owner action.
- A reply has no id of its own — it is addressed by the id of the review it answers — so publishing one again replaces it and there is no separate update;
textis bounded at 4,096 **bytes** as UTF-8, not characters. - Google moderates every reply: a successful publish returns
PENDINGand becomesAPPROVEDorREJECTEDafterwards. Read the review to see the current state. - Reviews are listed most recently changed first, so a review the reviewer edits arrives again as an
updatedevent. A review deleted on Google simply stops being listed: no event is emitted for it. - Google publishes review notifications to a Cloud Pub/Sub topic rather than an HTTP callback, so reviews are collected by polling at a fifteen-minute floor and there is no webhook URL to configure.
- A review carries
ratingas whole stars on a 1–5 scale (withpercent, which compares across providers) and omits it when Google reports none;reviewercarries a display name and photo, or neither for an anonymous reviewer, because Google publishes no stable reviewer id.
Your Google Cloud project must be approved before it can make a single call
| Content type | Operations | Events | Backfill |
|---|---|---|---|
google_business_profile.locations.reviews | list, get | created, updated | no |
google_business_profile.locations.review_replies | get, publish, delete | none | no |
google_business_profile.locations.reviews
list
List the location's reviews, most recently changed first.
| Field | Type | Required | Description |
|---|---|---|---|
connectedProfileId | string | yes | Koil Connected Profile associated with the operation. |
cursor | string | no | Opaque cursor for fetching the next result page. |
limit | number | no | Maximum number of items to return. |
includeProviderRaw | boolean | no | Whether to include transient provider-native payloads. |
JSON Schema
{
"additionalProperties": false,
"type": "object",
"properties": {
"connectedProfileId": {
"description": "Koil Connected Profile associated with the operation.",
"minLength": 1,
"type": "string"
},
"cursor": {
"description": "Opaque cursor for fetching the next result page.",
"minLength": 1,
"type": "string"
},
"limit": {
"description": "Maximum number of items to return.",
"minimum": 1,
"type": "number"
},
"includeProviderRaw": {
"description": "Whether to include transient provider-native payloads.",
"type": "boolean"
}
},
"required": [
"connectedProfileId"
]
}get
Get one review of the location by provider id.
| Field | Type | Required | Description |
|---|---|---|---|
connectedProfileId | string | yes | Koil Connected Profile associated with the operation. |
externalId | string | yes | |
includeProviderRaw | boolean | no | Whether to include transient provider-native payloads. |
JSON Schema
{
"additionalProperties": false,
"type": "object",
"properties": {
"connectedProfileId": {
"description": "Koil Connected Profile associated with the operation.",
"minLength": 1,
"type": "string"
},
"externalId": {
"minLength": 1,
"type": "string"
},
"includeProviderRaw": {
"description": "Whether to include transient provider-native payloads.",
"type": "boolean"
}
},
"required": [
"connectedProfileId",
"externalId"
]
}Not offered
publish: not applicable — A review is written by a customer on Google, never by the business.update: provider not supported — Google exposes no method that edits a review.moderate: provider not supported — Google exposes no hide, spam, or report method on a review. Replying is the only owner action, on google_business_profile.locations.review_replies.delete: provider not supported — Google exposes no method that deletes a review; flagging one for a policy violation is a Business Profile UI action with no API.
Events
content.google_business_profile.locations.reviews.createdcontent.google_business_profile.locations.reviews.updated
Backfill: not offered — not implemented.
Item schema
What list and get return and what events carry as data.
| Field | Type | Required | Description |
|---|---|---|---|
externalId | string | yes | Provider-owned content identifier. |
locationExternalId | string | yes | |
rating | object | no | A score on the provider's own scale, with its position on that scale as a percentage. |
text | string | no | Caption/body text for content. |
reviewer | object | yes | The reviewer as Google reports them: a name and photo, or neither when anonymous. Google publishes no stable reviewer id. |
media | object[] | no | |
reply | object | no | |
publishedAt | string (date-time) | no | Provider publish timestamp as an ISO-8601 string. |
updatedAt | string (date-time) | no | Provider update timestamp as an ISO-8601 string. |
providerRaw | unknown | no | Optional provider-native payload included only for transient delivery/debug use. |
contentType | "google_business_profile.locations.reviews" | yes |
google_business_profile.locations.review_replies
get
Get the owner's reply to one review.
| Field | Type | Required | Description |
|---|---|---|---|
connectedProfileId | string | yes | Koil Connected Profile associated with the operation. |
externalId | string | yes | The review's id; a reply has no id of its own. |
includeProviderRaw | boolean | no | Whether to include transient provider-native payloads. |
JSON Schema
{
"additionalProperties": false,
"type": "object",
"properties": {
"connectedProfileId": {
"description": "Koil Connected Profile associated with the operation.",
"minLength": 1,
"type": "string"
},
"externalId": {
"minLength": 1,
"description": "The review's id; a reply has no id of its own.",
"type": "string"
},
"includeProviderRaw": {
"description": "Whether to include transient provider-native payloads.",
"type": "boolean"
}
},
"required": [
"connectedProfileId",
"externalId"
]
}publish
Write the owner's reply to a review, replacing any existing reply. Google moderates it before it appears.
Submit through POST /v1/publish-requests with contentType: "google_business_profile.locations.review_replies". These fields go in the item's args; connectedProfileId and variant are item fields.
| Field | Type | Required | Description |
|---|---|---|---|
target | object | yes | The provider content this publish targets, identified as events identify it. |
text | string | yes | The reply, at most 4096 bytes as UTF-8. Google moderates it: a successful publish is accepted, not yet visible. |
JSON Schema
{
"additionalProperties": false,
"type": "object",
"properties": {
"target": {
"additionalProperties": false,
"description": "The provider content this publish targets, identified as events identify it.",
"type": "object",
"properties": {
"contentType": {
"const": "google_business_profile.locations.reviews",
"type": "string"
},
"externalId": {
"description": "Provider-owned content identifier.",
"minLength": 1,
"type": "string"
}
},
"required": [
"contentType",
"externalId"
]
},
"text": {
"minLength": 1,
"maxLength": 4096,
"description": "The reply, at most 4096 bytes as UTF-8. Google moderates it: a successful publish is accepted, not yet visible.",
"type": "string"
}
},
"required": [
"target",
"text"
]
}delete
Remove the owner's reply to a review.
| Field | Type | Required | Description |
|---|---|---|---|
connectedProfileId | string | yes | Koil Connected Profile associated with the operation. |
externalId | string | yes | The review whose reply to remove. |
JSON Schema
{
"additionalProperties": false,
"type": "object",
"properties": {
"connectedProfileId": {
"description": "Koil Connected Profile associated with the operation.",
"minLength": 1,
"type": "string"
},
"externalId": {
"minLength": 1,
"description": "The review whose reply to remove.",
"type": "string"
}
},
"required": [
"connectedProfileId",
"externalId"
]
}Not offered
list: provider no endpoint — Google exposes no listing of replies; each appears on the review it answers.update: not applicable — Publishing again for the same review replaces the reply; Google keeps one per review.moderate: not applicable — Google moderates the owner's reply, not Koil.
Events
None: this content type is read-only.
Backfill: not offered — not implemented.
Item schema
What list and get return and what events carry as data.
| Field | Type | Required | Description |
|---|---|---|---|
externalId | string | yes | Provider-owned content identifier. |
locationExternalId | string | yes | |
text | string | yes | Caption/body text for content. |
state | "PENDING" | "APPROVED" | "REJECTED" | no | Google's moderation state of the owner's reply. |
policyViolation | string | no | |
updatedAt | string (date-time) | no | Provider update timestamp as an ISO-8601 string. |
providerRaw | unknown | no | Optional provider-native payload included only for transient delivery/debug use. |
contentType | "google_business_profile.locations.review_replies" | yes |
Facebook Pages through your Meta app with Facebook Login; every operation acts with the Page's own access token, which Koil obtains when the profile is connected.
Instagram professional (Business and Creator) accounts through your Meta app, discovered and connected through the Facebook Page each account is linked to.