Measure review performance

Read a location's review KPIs, chart the daily timeline, compare sources, mine common phrases, and receive daily and weekly snapshots by webhook.

Three sibling endpoints describe a location's reviews as numbers: an overview of KPIs, a daily timeline, and a per-source breakdown. A fourth lists the phrases customers repeat. Together they are enough for a scorecard tile, a trend chart and a complaints panel.

1. Read the KPIs for a location

GET /locations/{locationId}/review-analytics-overview returns four stats at data.interactionsAnalyticsStats.stats. The date range is optional here; it narrows the window the values and deltas are computed over.

Overview
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-overview?startDate=2026-08-01&endDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "interactionsAnalyticsStats": {      "stats": [        { "name": "total-reviews", "value": 128, "delta": 6.67 },        { "name": "new-reviews", "value": 9, "delta": -25 },        { "name": "overall-rating", "value": 4.43, "delta": 2.31 },        { "name": "review-response-rate", "value": 62.5, "delta": 12.5 }      ]    }  }}
namevalueRead it as
total-reviewscountAll reviews for the location.
new-reviewscountReviews received in the period.
overall-rating1 to 5Average star rating.
review-response-ratepercentShare of reviews with an owner reply.

A fresh account with no prior period reports a delta of 100, so do not read the first month's deltas as growth.

2. Pull the daily timeline for a chart

GET .../review-analytics-timeline returns one entry per day at data.interactionsChartData.data. Always pass startDate and endDate, or the service picks its own window. Add site (a hostname such as maps.google.com) to draw one source on its own.

Timeline
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-timeline?startDate=2026-08-01&endDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "interactionsChartData": {      "data": [        { "date": "2026-08-01", "interactionCount": 4, "averageRating": 4.5 },        { "date": "2026-08-02", "interactionCount": 0, "averageRating": null },        { "date": "2026-08-03", "interactionCount": 7, "averageRating": 4.285714285714286 }      ]    }  }}

Plot interactionCount as bars and averageRating as a line. averageRating is that day's average, not a running one, and it is null on a day with no reviews, so leave a gap rather than drawing zero.

3. Break it down by source

GET .../review-analytics-sites-stats returns one entry per review source at data.interactionsSitesStats.stats. Use it to see which platform moved the average.

By source
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-sites-stats?startDate=2026-08-01&endDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "interactionsSitesStats": {      "stats": [        {          "key": "google",          "siteUrl": "maps.google.com",          "averageRating": { "value": 4.6, "delta": 2.2 },          "totalInteractions": { "value": 412, "delta": 6.1 },          "newInteractions": { "value": 24, "delta": 33.3 },          "recency": "2026-09-06T14:12:00Z",          "humanizedRecency": "3 days ago"        },        {          "key": "facebook",          "siteUrl": "facebook.com",          "averageRating": { "value": 4.1, "delta": -1.4 },          "newInteractions": { "value": 0, "delta": -100 },          "recency": null,          "humanizedRecency": null        }      ]    }  }}

averageRating, totalInteractions and newInteractions each carry a value and a delta. One negative averageRating.delta beside flat siblings points at a platform; all negative points at the store. newInteractions of 0 with a recency months old usually means the source connection went stale, so check List review sources for a location and re-add the source with Edit review settings if it is gone.

4. Find the phrases customers use

GET /review-phrases returns a plain array at data.newReviewPhrases, one entry per recurring phrase with the same stat shape as the overview, computed over only the reviews containing it. Add ratingFilters=[1,2] for a complaints panel. locationIds and ratingFilters are JSON arrays on the query string, so they must be URL-encoded; the SDKs do that for you.

Phrases
curl -G "https://listingsapi.com/api/v4/review-phrases" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'locationIds=[1800289]' \--data-urlencode 'ratingFilters=[1,2]' \--data-urlencode 'startDate=2026-06-01' \--data-urlencode 'endDate=2026-08-31' \--data-urlencode 'phraseCount=10'
JSON
{  "data": {    "newReviewPhrases": [      {        "reviewPhrase": "long wait",        "phraseStats": {          "stats": [            { "name": "total-reviews", "value": 11, "delta": 37.5, "abs": 3 },            { "name": "overall-rating", "value": 2.9, "delta": -8.4, "abs": -0.27 }          ]        }      }    ]  }}

total-reviews says how often the phrase appears, overall-rating says whether those reviews are happy, and delta says whether it is getting worse. abs is the absolute change alongside the percentage. The SDK phrase methods do not expose ratingFilters or phraseCount, so use the REST call when you need them.

5. Receive daily and weekly snapshots by webhook

With a webhooks URL configured, review_analytics.daily_snapshot and review_analytics.weekly_snapshot fire once per location per period. Read each as the overview endpoint computed for a fixed period: total_reviews is total-reviews, new_reviews_in_period is new-reviews, and average_rating is overall-rating for that period, with previous_average_rating for the one before. The response rate, timeline and per-source breakdown are not in the payload; call the endpoints above when the event arrives if you need them.

JSON
{  "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  }}

This family scales with your location count: 400 locations means 400 daily events in a burst, and events over your plan's per-minute cap are dropped, not queued. A missing snapshot is therefore ambiguous. Never record a zero for it; re-read the overview for that period instead. Setup is in React to events with webhooks.

Next steps