Inbox
List Google Business Profile and Facebook reviews in one feed, filter by rating, reply, and react to new, edited and removed reviews by webhook.
Reviews from Google Business Profile locations and Facebook Pages land in one list. You can filter it by rating and reply status, answer from the API, and get a webhook the moment a Google review is posted, edited or removed.
#List reviews
curl "https://api.pozy.ai/v1/inbox/reviews?profileId=6650c1e2a3b4c5d6e7f80911&maxRating=3&hasReply=false" \
-H "Authorization: Bearer $POZY_API_KEY"const res = await fetch("https://api.pozy.ai/v1/inbox/reviews?profileId=6650c1e2a3b4c5d6e7f80911&maxRating=3&hasReply=false", {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
for (const r of data.data) {
console.log(r.platform, r.locationName, r.rating, r.text);
}import os
import requests
resp = requests.get(
"https://api.pozy.ai/v1/inbox/reviews",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
params={"profileId": "6650c1e2a3b4c5d6e7f80911", "maxRating": 3, "hasReply": "false"},
timeout=30,
)
for r in resp.json()["data"]:
print(r["platform"], r["rating"], r["text"]){
"id": "accounts/1023/locations/4567/reviews/AbCdEf123",
"platform": "googlebusiness",
"accountId": "6650c1e2a3b4c5d6e7f80a22",
"locationName": "Acme Coffee, Gran Via",
"reviewer": { "id": null, "name": "Marta P.", "profileImage": null },
"rating": 2,
"text": "Great coffee, but we waited 20 minutes.",
"created": "2026-10-28T18:42:00Z",
"hasReply": false,
"hasPhotos": false,
"reply": null,
"reviewUrl": "https://maps.google.com/?cid=1234567890"
}| Parameter | What it does |
|---|---|
profileId, accountId |
One customer profile or one location/Page |
platform |
googlebusiness or facebook |
minRating, maxRating |
Star range, 1 to 5 |
hasReply |
false gives you the queue still waiting for an answer |
sortBy, sortOrder |
date (default) or rating, desc or asc |
limit, cursor |
Up to 50 per page |
Facebook recommendations have no stars: they come with recommendationType set to positive or negative instead of a numeric rating.
Each account's reviews are read from the platform within a fixed time budget per request and cached for up to a minute, so a location with thousands of reviews can come back truncated. Use the webhooks below to stay current and the list to backfill.
#Reply
curl -X POST "https://api.pozy.ai/v1/inbox/reviews/accounts%2F1023%2Flocations%2F4567%2Freviews%2FAbCdEf123/reply" \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6a2e9b10-77f1-4b6a-9d3c-0c5e8f2a4b71" \
-d '{
"accountId": "6650c1e2a3b4c5d6e7f80a22",
"message": "Thanks Marta, and sorry about the wait. We have added a second barista at lunchtime."
}'import { randomUUID } from "node:crypto";
// Google review ids contain slashes: encode the id so it stays one path segment
const reviewId = encodeURIComponent("accounts/1023/locations/4567/reviews/AbCdEf123");
const res = await fetch(`https://api.pozy.ai/v1/inbox/reviews/${reviewId}/reply`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.POZY_API_KEY}`,
"Idempotency-Key": randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
accountId: "6650c1e2a3b4c5d6e7f80a22",
message: "Thanks Marta, and sorry about the wait. We have added a second barista at lunchtime.",
}),
});
if (!res.ok) throw new Error((await res.json()).error);import os, uuid
from urllib.parse import quote
import requests
review_id = "accounts/1023/locations/4567/reviews/AbCdEf123"
resp = requests.post(
f"https://api.pozy.ai/v1/inbox/reviews/{quote(review_id, safe='')}/reply",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={"accountId": "6650c1e2a3b4c5d6e7f80a22", "message": "Thanks Marta, and sorry about the wait."},
timeout=30,
)
print(resp.json())Google review ids contain slashes, so URL-encode them in the path. To remove a reply, call DELETE /v1/inbox/reviews/{reviewId}/reply with the accountId; that works on Google Business Profile only.
Idempotency-Key works as for comments: the same key and body within 24 hours replays the first response, a different body answers 422.
Answer the specific complaint, name what changes, and keep it short. Public replies are part of the listing that the next customer reads.
#Review webhooks
Google Business Profile reviews are reported in real time:
| Event | When |
|---|---|
review.new |
A new review was posted |
review.updated |
The reviewer edited text or rating, or a reply was added (through Pozy or Google's own tools) |
review.deleted |
Google stopped returning the review, for example after its spam filter removed it |
review.restored |
A review reported as deleted came back |
review.deleted is detected by checking, so it usually arrives 6 to 12 hours after the review disappears, and only for locations covered by a webhook subscribed to review.deleted or review.restored. It can name a review you never received review.new for; ignore ids you do not know.
#Google-specific management
For one location's reviews with Google's own paging and batch reads, use the Google Business Reviews endpoints under /v1/accounts/{accountId}/gmb-reviews.
#Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/inbox/reviews |
List reviews |
POST /v1/inbox/reviews/{reviewId}/reply |
Reply to review |
DELETE /v1/inbox/reviews/{reviewId}/reply |
Delete review reply |
#Webhook events
| Event | When it fires |
|---|---|
review.new |
Review new. |
review.updated |
Review updated. |
review.deleted |
Review deleted. |
review.restored |
Review restored. |