Reviews & GBP API
Two surfaces backed by module-BDE-M:
- Reviews (
/v1/reviews/*) — list a brand's reviews and public testimonials (free), generate AI replies, send review requests, and read reputation analytics (free). - Google Business Profile (
/v1/gbp/*) — list locations and posts (free), preview a post (free), and publish a post with media (metered "GBP Posting" product).
Authentication
Authorization: Bearer ai92_live_<key> # production
Authorization: Bearer ai92_test_<key> # sandboxMutating requests support Idempotency-Key and are brand-gated (platform_brand_id / brand_id is verified against the account).
Credit costs at a glance
| Endpoint | Cost |
|---|---|
GET /v1/reviews | Free |
GET /v1/reviews/testimonials | Free |
POST /v1/reviews/reply | 1 cr |
POST /v1/reviews/request | 2 cr |
GET /v1/reviews/analytics | Free |
GET /v1/gbp/locations | Free |
GET /v1/gbp/posts | Free |
POST /v1/gbp/posts/preview | Free |
POST /v1/gbp/posts/publish-with-media | 50 cr |
GET /v1/gbp/connection | Free |
Reviews
GET /v1/reviews
Cost: Free
List a brand's reviews via module-BDE-M.
Auth: Bearer
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
platform_brand_id | query | string | Yes | The brand. Verified against the account. |
limit | query | integer | No | Page size. Default 50. |
offset | query | integer | No | Page offset. Default 0. |
Request
curl "https://api.ai92.ai/v1/reviews?platform_brand_id=acme&limit=20" \
-H "Authorization: Bearer ai92_test_51a9c0de…"Response 200 OK
{
"reviews": [
{ "review_id": "rev_01", "rating": 5, "text": "Great product!", "author": "Sam", "replied": false }
],
"total": 318
}GET /v1/reviews/testimonials
Cost: Free
Public testimonials feed.
Auth: Bearer
_No parameters._
Request
curl https://api.ai92.ai/v1/reviews/testimonials \
-H "Authorization: Bearer ai92_test_51a9c0de…"Response 200 OK
{
"testimonials": [ { "id": "t_1", "quote": "Transformed our outreach.", "author": "Acme Corp" } ]
}POST /v1/reviews/reply
Cost: 1 credit
Generate and post an AI reply to a review.
Auth: Bearer
| Field | Type | Required | Description |
|---|---|---|---|
review_id | string | Yes | The review to reply to. |
reply_text | string | Yes | The reply content. |
Request
curl https://api.ai92.ai/v1/reviews/reply \
-H "Authorization: Bearer ai92_test_51a9c0de…" \
-H "Content-Type: application/json" \
-d '{"review_id": "rev_01", "reply_text": "Thanks so much, Sam — glad it is working for you!"}'Response 200 OK
{ "review_id": "rev_01", "reply_id": "rpl_44", "status": "posted" }Errors
| Status | Code | When |
|---|---|---|
402 | INSUFFICIENT_CREDITS | Balance below 1 credit. |
POST /v1/reviews/request
Cost: 2 credits
Send a review request to a customer for a location.
Auth: Bearer
| Field | Type | Required | Description |
|---|---|---|---|
location_id | string | Yes | The GBP location id. |
customer_email | string | Yes | Customer email to request a review from. |
Request
curl https://api.ai92.ai/v1/reviews/request \
-H "Authorization: Bearer ai92_test_51a9c0de…" \
-H "Content-Type: application/json" \
-d '{"location_id": "loc_7", "customer_email": "[email protected]"}'Response 200 OK
{ "request_id": "rq_88", "status": "sent" }Errors
| Status | Code | When |
|---|---|---|
402 | INSUFFICIENT_CREDITS | Balance below 2 credits. |
GET /v1/reviews/analytics
Cost: Free
Reputation pulse for a brand: rating distribution, 30-day trend, low-rating and unreplied counts, and a 0–100 score.
Auth: Bearer
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
platform_brand_id | query | string | Yes | The brand. Verified against the account. |
Request
curl "https://api.ai92.ai/v1/reviews/analytics?platform_brand_id=acme" \
-H "Authorization: Bearer ai92_test_51a9c0de…"Response 200 OK
{
"platform_brand_id": "acme",
"reputation_score": 82,
"avg_rating": 4.6,
"distribution": { "5": 210, "4": 70, "3": 20, "2": 10, "1": 8 },
"unreplied_count": 14,
"low_rating_count": 18,
"trend_30d": 0.05
}Google Business Profile (GBP)
GET /v1/gbp/locations
Cost: Free
List the brand's connected Google Business locations.
Auth: Bearer
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
platform_brand_id | query | string | Yes | The brand. Verified against the account. |
Request
curl "https://api.ai92.ai/v1/gbp/locations?platform_brand_id=acme" \
-H "Authorization: Bearer ai92_test_51a9c0de…"Response 200 OK
{
"locations": [ { "location_id": "loc_7", "name": "Acme HQ", "address": "1 Market St, SF" } ]
}GET /v1/gbp/posts
Cost: Free
List the brand's GBP posts, optionally filtered by location and status.
Auth: Bearer
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
platform_brand_id | query | string | Yes | The brand. Verified against the account. |
location_id | query | string / null | No | Filter by location. |
status | query | string / null | No | Filter by post status. |
Request
curl "https://api.ai92.ai/v1/gbp/posts?platform_brand_id=acme&location_id=loc_7" \
-H "Authorization: Bearer ai92_test_51a9c0de…"Response 200 OK
{
"posts": [ { "post_id": "gp_3", "summary": "Spring sale now on", "status": "published" } ]
}POST /v1/gbp/posts/preview
Cost: Free
Render a preview of a GBP post without publishing. The body is permissive (extra fields are forwarded to module-BDE-M), but platform_brand_id is required for ownership verification.
Requires an active GBP OAuth connection. For any brand that has not completed the Google Business Profile OAuth flow,
previewreturns409 GBP_NOT_CONNECTED. There is no simulated GBP connection in the sandbox, sopreviewis not testable on a sandbox brand — connect a real GBP property (viaPOST /v1/gbp/connect) first. The only GBP write that is fully simulatable in sandbox without a real connection isPOST /v1/gbp/posts/publish-with-media, which returns{ "status": "published", "sandbox": true }.
Auth: Bearer
| Field | Type | Required | Description |
|---|---|---|---|
platform_brand_id | string | Yes | The brand. Verified against the account. |
location_id | string / null | No | Target location. |
summary | string / null | No | Post copy. |
| _(additional fields)_ | any | No | Forwarded to the backend (which validates). |
Request
curl https://api.ai92.ai/v1/gbp/posts/preview \
-H "Authorization: Bearer ai92_test_51a9c0de…" \
-H "Content-Type: application/json" \
-d '{"platform_brand_id": "acme", "location_id": "loc_7", "summary": "Spring sale now on"}'Response 200 OK
{ "preview": { "summary": "Spring sale now on", "media": null }, "valid": true }POST /v1/gbp/posts/publish-with-media
Cost: 50 credits
Publish a GBP post with media (the "GBP Posting" catalog product). Charged on success; a backend failure returns 4xx/503 and nothing is charged.
Auth: Bearer
| Field | Type | Required | Description |
|---|---|---|---|
platform_brand_id | string | Yes | The brand. Verified against the account. |
location_id | string / null | No | Target location. |
summary | string / null | No | Post copy. |
| _(additional fields, e.g. media URL)_ | any | No | Forwarded to the backend (which validates). |
Request
curl https://api.ai92.ai/v1/gbp/posts/publish-with-media \
-H "Authorization: Bearer ai92_test_51a9c0de…" \
-H "Content-Type: application/json" \
-d '{"platform_brand_id": "acme", "location_id": "loc_7", "summary": "Spring sale now on", "media_url": "https://cdn.ai92.ai/ast_99.png"}'Response 200 OK
{ "post_id": "gp_4", "status": "published", "url": "https://business.google.com/posts/gp_4" }Errors
| Status | Code | When |
|---|---|---|
402 | INSUFFICIENT_CREDITS | Balance below 50 credits. |
503 | (backend error) | module-BDE-M failed; nothing charged. |
GET /v1/gbp/connection
Cost: Free
Whether the brand has a connected Google Business profile, plus its account/location.
Auth: Bearer
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
brand_id | query | string | Yes | The brand. Verified against the account. |
Request
curl "https://api.ai92.ai/v1/gbp/connection?brand_id=acme" \
-H "Authorization: Bearer ai92_test_51a9c0de…"Response 200 OK
{ "brand_id": "acme", "connected": true, "google_account": "acme@business", "location_count": 3 }