curl --request GET \
--url https://app.reputably.net/api/entities/Review \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.reputably.net/api/entities/Review"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.reputably.net/api/entities/Review', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.reputably.net/api/entities/Review",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.reputably.net/api/entities/Review"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.reputably.net/api/entities/Review")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.reputably.net/api/entities/Review")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"id": "<string>",
"location_id": "<string>",
"google_review_id": "<string>",
"source": "google",
"source_id": "<string>",
"source_metadata": {},
"reviewer_name": "<string>",
"reviewer_photo_url": "<string>",
"reviewer_is_local_guide": true,
"star_rating": 123,
"review_text": "<string>",
"review_language": "<string>",
"review_created_at": "<string>",
"review_updated_at": "<string>",
"reply_text": "<string>",
"reply_created_at": "<string>",
"reply_updated_by": "<string>",
"sentiment": "positive",
"sentiment_score": 123,
"key_topics": [
"<string>"
],
"emotion": "joy",
"is_flagged": true,
"flag_reason": "<string>",
"is_read": true,
"needs_response": true,
"priority": "urgent",
"ai_suggested_response": "<string>",
"notes": "<string>",
"synced_at": "<string>",
"gbp_api_synced_at": "<string>",
"removed_at_source_at": "<string>",
"auto_response_status": "pending",
"auto_response_scheduled_at": "<string>",
"auto_response_error": "<string>"
}
]List reviews
Reads reviews in the selected workspace. Filter with q, a JSON object of field matches. Reads only: writes through this route are refused for every entity and every credential.
curl --request GET \
--url https://app.reputably.net/api/entities/Review \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.reputably.net/api/entities/Review"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.reputably.net/api/entities/Review', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.reputably.net/api/entities/Review",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.reputably.net/api/entities/Review"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.reputably.net/api/entities/Review")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.reputably.net/api/entities/Review")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"id": "<string>",
"location_id": "<string>",
"google_review_id": "<string>",
"source": "google",
"source_id": "<string>",
"source_metadata": {},
"reviewer_name": "<string>",
"reviewer_photo_url": "<string>",
"reviewer_is_local_guide": true,
"star_rating": 123,
"review_text": "<string>",
"review_language": "<string>",
"review_created_at": "<string>",
"review_updated_at": "<string>",
"reply_text": "<string>",
"reply_created_at": "<string>",
"reply_updated_by": "<string>",
"sentiment": "positive",
"sentiment_score": 123,
"key_topics": [
"<string>"
],
"emotion": "joy",
"is_flagged": true,
"flag_reason": "<string>",
"is_read": true,
"needs_response": true,
"priority": "urgent",
"ai_suggested_response": "<string>",
"notes": "<string>",
"synced_at": "<string>",
"gbp_api_synced_at": "<string>",
"removed_at_source_at": "<string>",
"auto_response_status": "pending",
"auto_response_scheduled_at": "<string>",
"auto_response_error": "<string>"
}
]Authorizations
An agent key (rpk_...) created in Settings → API & MCP, sent as Authorization: Bearer rpk_.... Bearer only: a cookie session can never drive this API. An OAuth 2.1 access token obtained from the same host works identically and lands on the same ceiling.
Headers
Which workspace to read. Omit it and you get the account’s home workspace, which on an agency account is often not where the live businesses are. A workspace this credential cannot read is refused with 403 rather than quietly answered from the default.
Query Parameters
JSON filter object, for example {"needs_response":true}.
Field to sort on.
Maximum rows to return.
Rows to skip, for paging.
Response
Matching reviews.
Unique id.
Which platform this review came from. Drives the reply dispatcher and source-aware UI.
google, facebook Platform-native identifier for this review. For GBP: matches google_review_id. For Facebook: the open_graph_story.id we comment on when replying.
Free-form platform-specific extras (e.g. Facebook recommendation_type, reply_comment_id). Generic code should not read from this.
Null for sources without a 1-5 rating (Facebook recommendations). Charts that aggregate on rating should exclude null rows.
positive, neutral, negative, mixed joy, anger, sadness, fear, surprise, disgust, neutral urgent, high, medium, low Last time the Google Business Profile API returned this review. Absent on reviews imported another way.
Set when a VERIFIED-COMPLETE fetch of the source listing did not return this review — i.e. the reviewer deleted it, or the platform moderated it away. A soft flag rather than a delete so reply history and past analytics survive and a source-side glitch is recoverable: the row is cleared back to null the moment the source returns the review again. Rows carrying it are excluded from the response queue, the review lists, and every analytics denominator (server/lib/reviewVisibility.js + src/lib/reviewVisibility.js). Only ever written off a complete pass — see server/lib/reviewPruning.js.
Lifecycle of the auto-response worker for this review. 'pending' = scheduled, awaiting fire time. 'sent' = AI reply was generated and posted to the source. 'skipped' = the rating wasn't in the agency's filter, or auto-response was disabled at sync time, or the review already had a reply. 'failed' = a fire attempt errored (see auto_response_error). Null/absent on review rows that pre-date the feature.
pending, sent, skipped, failed ISO timestamp the worker will fire at. Picked once at review-insert time as a uniform random value in [now+min_delay, now+max_delay] from the agency's auto_response_settings. Surviving process restarts is the whole point of stamping it on the row.
Last error message when auto_response_status='failed'. Used to surface the failure on the review card without a separate audit table.