Updated Oct 2026
Export Google reviews to Google Sheets: three ways that actually work
Google Business Profile has no review export and no sync to Sheets. What works is the API, and there are three ways to use it: an Apps Script against the Business Profile API (every review of your own listings, free, after Google’s approval), the Places API (5 public reviews of any place, no approval), or a unified reviews API that also brings the other platforms into the same sheet. Pick by what you need; the scripts are below, ready to paste.
Option 1: Apps Script with the Business Profile API (all your reviews)
Prerequisites: you are an owner or manager of the listing, and the Apps Script is linked to a Google Cloud project with the Business Profile APIs enabled and API access approved. Until approval the quota is 0 and the script will fail with a 429.
- In the sheet: Extensions → Apps Script. Replace the code with the script below.
- Project settings → Show manifest, then in
appsscript.jsonadd"oauthScopes": ["https://www.googleapis.com/auth/business.manage", "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/script.external_request"]. - Project settings → Change project → paste the Cloud project number that has the approval.
- Run
importReviewsonce (it asks for authorisation), then Triggers → Add trigger, time-driven, daily.
const ACCOUNT = "accounts/1234567890"; // from GET https://mybusinessaccountmanagement.googleapis.com/v1/accounts
const LOCATION = "locations/9876543210"; // from GET …/v1/{account}/locations?readMask=name,title
const STARS = { ONE: 1, TWO: 2, THREE: 3, FOUR: 4, FIVE: 5 };
function importReviews() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Reviews") || SpreadsheetApp.getActiveSpreadsheet().insertSheet("Reviews");
if (sheet.getLastRow() === 0) sheet.appendRow(["id", "date", "rating", "author", "text", "reply", "updated"]);
const known = new Set(sheet.getRange(2, 1, Math.max(sheet.getLastRow() - 1, 1), 1).getValues().flat());
const headers = { Authorization: "Bearer " + ScriptApp.getOAuthToken() };
let pageToken = "", rows = [];
do {
const url = `https://mybusiness.googleapis.com/v4/${ACCOUNT}/${LOCATION}/reviews?pageSize=50` + (pageToken ? `&pageToken=${pageToken}` : "");
const res = UrlFetchApp.fetch(url, { headers, muteHttpExceptions: true });
if (res.getResponseCode() !== 200) throw new Error(res.getContentText());
const data = JSON.parse(res.getContentText());
for (const r of data.reviews || []) {
if (known.has(r.reviewId)) continue;
rows.push([r.reviewId, r.createTime, STARS[r.starRating], r.reviewer.displayName, r.comment || "", (r.reviewReply || {}).comment || "", r.updateTime]);
}
pageToken = data.nextPageToken || "";
} while (pageToken);
if (rows.length) sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length).setValues(rows);
}Multiple locations: list them with the Business Information API and loop. Ratings arrive as the enum ONE…FIVE; the script maps them. Edited reviews are not updated by this version (it skips known ids); compare updateTime if you need that.
Option 2: Places API (5 reviews, any place, no approval)
If a snapshot of the top 5 public reviews is enough, a Places API key (how to get one) and this script work in a minute, with no OAuth and no approval:
const PLACE_ID = "ChIJN1t_tDeuEmsRUsoyG83frY4";
const KEY = PropertiesService.getScriptProperties().getProperty("GOOGLE_MAPS_API_KEY");
function importTop5() {
const res = UrlFetchApp.fetch(`https://places.googleapis.com/v1/places/${PLACE_ID}`, { headers: { "X-Goog-Api-Key": KEY, "X-Goog-FieldMask": "displayName,rating,userRatingCount,reviews" } });
const p = JSON.parse(res.getContentText());
const sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
sheet.appendRow([p.displayName.text, p.rating, p.userRatingCount]);
for (const r of p.reviews || []) sheet.appendRow([r.publishTime, r.rating, r.authorAttribution.displayName, (r.text || {}).text || ""]);
}Store the key in Script properties, not in the code. You get at most 5 reviews, no replies, billed per request.
Option 3: one key, Google plus Tripadvisor, App Store, Trustpilot and more
Prisma reads the reviews of the locations you connect, on 50+ platforms, and returns them in one JSON, so one script fills one sheet with every platform. Google locations connect with a Google sign-in through Prisma’s own project; other platforms with a key or the listing URL.
const PRISMA_KEY = PropertiesService.getScriptProperties().getProperty("PRISMA_API_KEY");
function importAllPlatforms() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Reviews") || ss.insertSheet("Reviews");
if (sheet.getLastRow() === 0) sheet.appendRow(["id", "platform", "location", "date", "rating", "author", "text", "reply", "url"]);
const known = new Set(sheet.getRange(2, 1, Math.max(sheet.getLastRow() - 1, 1), 1).getValues().flat());
const headers = { Authorization: "Bearer " + PRISMA_KEY };
const locs = {};
for (const l of JSON.parse(UrlFetchApp.fetch("https://api.prismareviews.com/v1/locations", { headers }).getContentText()).data) locs[l.id] = l.name;
let cursor = "", rows = [];
do {
const res = UrlFetchApp.fetch("https://api.prismareviews.com/v1/reviews?limit=100" + (cursor ? "&cursor=" + cursor : ""), { headers });
const data = JSON.parse(res.getContentText());
for (const r of data.data) {
if (known.has(r.id)) continue;
rows.push([r.id, r.platform, locs[r.location_id] || r.location_id, r.created_at, r.rating, r.author || "", r.text || "", r.reply ? r.reply.text : "", r.url || ""]);
}
cursor = data.next_cursor || "";
} while (cursor);
if (rows.length) sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length).setValues(rows);
}Schedule it daily, or skip polling and let Prisma push: register a webhook with POST /v1/webhooks pointing at a Zapier or Make hook that appends the row (setup), or use the n8n node. A test key (pk_test_…) fills the sheet with sample reviews from every platform, so you can build the sheet before connecting anything.
What’s true today: Prisma reads Google reviews from the Google Maps listing (public, read-only) while Google reviews Prisma’s Business Profile API application. For the full history of your own Google listing right now, Option 1 is the route, if your project is approved.
Which option
| You want | Use |
|---|---|
| Every review of listings you own, Google only, free, and you have (or can get) API approval | Option 1 |
| A quick top-5 of any place, no approval | Option 2 |
| Google plus the other platforms in one sheet, no approval on your side | Option 3 |
FAQ
Can I export all Google reviews to a spreadsheet for free?
Yes, if you own the listing and have Business Profile API access approved for a Cloud project: the Apps Script in this guide pulls every review with no cost. Without that approval, the Places API gives only 5 reviews, and Google Business Profile’s own export is manual.
Does Google Business Profile have a built-in review export?
No automatic export. You can read reviews in the Business Profile dashboard and copy them, but there is no CSV download and no sync; the API is the only automated route.
Can the same sheet hold Tripadvisor, App Store or Trustpilot reviews?
With a unified API, yes: the third script in this guide writes every platform’s reviews in the same columns, because they come back in one JSON shape.
Every platform's reviews in one sheet.
2 locations free. Test keys fill the sheet with sample reviews today.