Build in Public · LF-05
Google Maps Reviews API: Selecting the Right Entry Point and Recording Location Reviews
Distinguish between Business Profile, Places API, and EveryInfra location review retrieval, verify location identity, language, and time filters, preserve changes to ratings and merchant replies, and clarify sample, storage, and display boundaries.
The phrase "I want to get Google Maps reviews" can refer to three distinct tasks: managing reviews for your own storefronts, displaying location details in a product, or researching user feedback across a group of locations. While all three involve reviews, they do not share the same permissions, endpoints, or retention rules. Choosing the wrong entry point cannot be fixed later by increasing request volume or changing the parsing method.
This guide first helps you choose a workflow, then uses google_maps_reviews.reviews from EveryInfra to explain how to verify locations, construct small requests, handle ratings and merchant replies, and organize ongoing observation. The focus is ensuring each data record maps back to the correct location and explaining sample gaps rather than promising to export every historical review for any location.
The index and implementation check date is 2026-09-04. Paid requests mentioned in the text were not executed in this round; synthetic records in the code are used solely to demonstrate field change verification. Use the template for production only after confirming authorization for the specific data retrieval, processing, storage, and display use cases.
Choosing an Entry Point: Merchant Management, Location Display, and Research Retrieval
To manage storefronts you are authorized to operate, review the Google Business Profile API first. Official review guides organize read and merchant reply operations by account and location, requiring app registration and OAuth credentials for integration. When replying to user reviews, perform the action under the appropriate management permissions rather than sending a generic write request to an arbitrary map link.
The deleteReply function in the official guides deletes merchant replies, not original user reviews. This distinction matters for operational workflows: if the task is retracting an incorrect reply you wrote versus handling an inappropriate user review, follow their respective processes rather than misusing a DELETE example.
To display location details in a product, consult the Place Details endpoint of the Google Places API. It queries by location ID and uses FieldMask to select required fields; this location display path cannot be used directly as a batch export interface for all historical reviews. Using Places content also requires compliance with caching, storage, and attribution display requirements.
EveryInfra provides a separate retrieval contract: platform is google_maps_reviews, action is reviews, and the input is a location URL. The following sections explain only this retrieval path, do not demonstrate modifying storefront profiles, replying, or deleting, and do not refer to it as an official Google API.
Choosing a third-party interface does not remove data use restrictions. Google Maps additional terms include limits on copying, redistribution, and bulk downloading; the Places API also has its own content rules. Simply because a single request returns data does not mean you are permitted to stockpile it long-term, bulk resell it, or redisplay it arbitrarily. If your planned use falls outside permitted scopes, adjust your plan rather than using technology to bypass licensing judgments.
When specific parameters for the official merchant management path are needed, check reviews.list directly: it targets by account and location, providing a review list, overall average rating, total review count, and a next-page token. This structure explains why "how many items this page retrieved" and "how many total reviews the location has" must be kept separate; do not port its fields or pagination rules into guarantees for EveryInfra.
Step 1: Confirm Location Identity, Not Just Store Name
Storefront names are not stable unique identifiers. The same brand may operate multiple branches, and the same commercial district may feature similar store names. When a store renames, old records do not necessarily become the new store. Confirm location references, addresses, and business ownership in your business objective checklist before initiating review requests.
Retain the complete location URL used for your request along with a reliably obtained place_id. Merge data only for confirmed identities; do not concatenate reviews for two stores based solely on geographic proximity, identical names, or string similarity. Unconfirmed targets enter a review checklist to prevent subsequent analyses from treating misidentified store data as complaint trends.
The current retrieval implementation utilizes identifiable location information from URLs, but not every map address format is equally suitable for targeting. Links containing only store names and map viewport coordinates should not be treated independently as confirmed location IDs. Prioritize retaining verified complete source links over assembling placeholder addresses that resemble map pages.
An interface boundary also applies here: the implementation internally recognizes certain location details, but public requests do not allow adding arbitrary placeId or place_id parameters. The current required parameter for reviews is url, and clients must pass parameters according to the public contract.
Step 2: Check Language, Sorting, and Time Conditions
curl -fsS --max-time 30 \
'https://api.everyinfra.com/api/v1/social/catalog?platform=google_maps_reviews' \
| jq -e '.capabilities[] | select(.action == "reviews") | {
platform, action, required_params, optional_params, param_meanings,
mode, returns_list, default_limit, max_limit, response_fields
}'This directory requires url, uses synchronous list returns with a default item count of 20 and an upper limit of 100, and supports optional parameters including lang, language, since, and sort. The accurate platform identifier is google_maps_reviews; do not abbreviate it to another platform based on article titles.
newest and relevance correspond to different sorting intentions: the former targets recent content, while the latter targets relevance samples. They are not interchangeable page data sets. Maintain consistent selection criteria when comparing storefronts and save the actual review IDs retrieved; switching sort orders may change sample membership.
Language fields do not filter by author nationality or residence. Permitted values for lang follow interface enumerations—current options include en, zhcn, and zhtw—and should not be filled with arbitrary language codes based on generalized descriptions. Avoid populating lang and language blindly together; in the current mapping, lang overrides language settings, and initial implementations should select a single explicitly supported option.
since expresses the lower bound for review publication dates, and the directory recommends using YYYY-MM-DD. It is not a business opening date, an update timestamp for reviews, or a reliable cursor indicating processing progress. Use it as a filtering condition when needed, and independently verify boundary dates against actual results.
Step 3: Test a Small Sample of Results from a Authorized Location
Assume you have configured EVERYINFRA_API_KEY and a confirmed EVERYINFRA_MAPS_PLACE_URL on your server. Submit examples only once, and place limit inside params; placing it at the request root level does not control item counts.
: "${EVERYINFRA_API_KEY:?set the API Key first}"
: "${EVERYINFRA_MAPS_PLACE_URL:?set the authorized full place URL first}"
jq -cn --arg url "${EVERYINFRA_MAPS_PLACE_URL}" '{
platform: "google_maps_reviews",
action: "reviews",
params: {url: $url, sort: "newest", limit: 3}
}' | curl --silent --show-error --include --max-time 180 \
'https://api.everyinfra.com/api/v1/social' \
-H "Authorization: Bearer ${EVERYINFRA_API_KEY}" \
-H 'Content-Type: application/json' --data-binary @-limit: 3 is a small sample setting intended for testing, and does not guarantee exactly three items are returned nor imply the location only has three reviews. 180 seconds serves as an example client wait budget, not a service guarantee. Check HTTP status and errors first, then verify whether results match the expected list and correspond to the target location.
Empty arrays cannot be directly labeled as "this store has no reviews." This outcome may stem from retrieval failure during the current call, or targets, filters, and accessibility requiring verification. Maintain an unknown status when the real reason is unclear; if a client times out, do not automatically retry POST requests while assuming the previous attempt failed to execute or incur charges.
Step 4: Separate Location Ratings, Individual Ratings, and Replies
Current record fields include id, text, rating, rating_scale, posted_at, place_id, place_name, owner_response, and owner_response_at. Average ratings in location details and individual review ratings are distinct objects; do not copy storefront average scores onto every review to fill empty values.
curl -fsS --max-time 30 \
'https://api.everyinfra.com/api/v1/social/fields?platform=google_maps_reviews&action=reviews' \
| jq '{fields, undocumented}'Ratings and main text must also be processed separately. A record containing only a rating and no text may be useful for rating samples, but cannot be fed directly into text topic classification. Retain unknown states when rating is missing; evaluate rating_scale together with ratings during cross-platform comparisons and avoid averaging numbers across different scales.
detailed_rating, if returned, carries sub-dimension scores, but one should not assume every location or review features identical dimensions. is_local_guide and historical review counts should not be treated directly as "real user" authentication or credibility scores. They represent platform-provided attributes rather than verifications of factual accuracy for any given review.
Store replies are saved separately. The absence of owner_response indicates only that this value was not retrieved in the current run, and does not prove the merchant never replied; subsequently acquiring a reply does not imply the user's original review was newly published. Treating both as new reviews generates meaningless monitoring alerts for additions.
Step 5: Create Separate Records for Identity, Observation, and Changes
- Location identity: Confirmed place_id, source references, and business ownership. Check duplicate stores by identity first rather than merging them roughly by name.
- Review identity: Combination of location ID and review ID; process records lacking reliable IDs separately without using reviewer nicknames as unique keys.
- Observation logs: Request ID, actual collection timestamp, sorting and language/date conditions, retrieved fields, and missing elements.
- Change logs: Observable differences in content, ratings, or merchant replies for the same review, without interpreting unknown fields as deletions.
Save fields required for comparisons only within permitted scopes and timeframes. If text cannot be saved, adjust records to the minimum authorized state and do not use "ease of auditing" as a justification for indefinite retention. The following section uses fictional locations, reviews, and text to demonstrate how to distinguish value changes, initially acquired fields, and unacquired data.
function compareReview(before, after) {
const identity = row => {
if (typeof row.place_id !== "string" || !row.place_id
|| typeof row.id !== "string" || !row.id) {
throw new Error("place and review ids required");
}
return JSON.stringify([row.place_id, row.id]);
};
if (identity(before) !== identity(after)) throw new Error("different review");
const t0 = Date.parse(before.observed_at);
const t1 = Date.parse(after.observed_at);
if (!Number.isFinite(t0) || !Number.isFinite(t1) || t1 <= t0) {
throw new Error("observations must have increasing times");
}
const changed = [], firstObserved = [], notObserved = [];
for (const field of ["text", "rating", "owner_response", "owner_response_at"]) {
if (!Object.hasOwn(after, field) || after[field] == null) {
notObserved.push(field);
} else if (!Object.hasOwn(before, field) || before[field] == null) {
firstObserved.push(field);
} else if (before[field] !== after[field]) {
changed.push(field);
}
}
return {changed, firstObserved, notObserved};
}
console.log(compareReview(
{place_id: "synthetic-place", id: "synthetic-review",
text: "synthetic review", rating: 3, observed_at: "2026-09-01T00:00:00Z"},
{place_id: "synthetic-place", id: "synthetic-review",
text: "synthetic review", rating: 3, owner_response: "synthetic reply",
observed_at: "2026-09-02T00:00:00Z"}
));This example records owner_response as firstObserved rather than a new review; if reply times are missing, it logs notObserved. Even if text appears in changed, it indicates only that text retrieved across two fetches differed and may involve translation or representation changes; never assert that a user edited the original text without supporting evidence.
Chronological checks prevent older observation logs from overwriting newer observations, but do not prove real-time server data freshness. Your recorded observed_at reflects the moment you saw the response, not the update timestamp for platform fields.
When saving observation records across time zones, use RFC 3339 offset-inclusive time formats while preserving original source values separately. Uniform formatting facilitates point-in-time comparisons without turning observation times into review update times or increasing coverage for the current retrieval.
Step 6: Explain Coverage in Incremental Observations Rather Than Simply Advancing Dates
Continuous monitoring permits repeatedly observing fixed sets of locations under permitted conditions, retaining appropriate overlapping ranges for date filters, and deduplicating by review identity. Overlap window lengths depend on observed delayed records and task frequency; no universal number of days can be derived directly from small samples.
However, overlap windows do not resolve all omissions: single results have quantity limits, older reviews may later acquire merchant replies, and sorting changes returned samples. Most importantly, do not assume since captures all updated older reviews; it filters publication times rather than serving as a complete change stream.
Record planned checked locations, locations with available records, failed or unknown locations, and return item counts per location for every execution. Coverage discussions require knowing collection scopes, sorting, and truncation conditions; dividing a return count by an unknown total volume to manufacture seemingly precise coverage rates is invalid.
Storefront comparisons require similar restraint. Average scores from small numbers of recent reviews do not equal total map location ratings, and score drops cannot be confirmed via changing sample sets alone. To compare issue types, define classification criteria first before displaying sample timings and missing elements for each store.
Step 7: Analysis, Internal Processing, and Public Display Involve Different Permissions
Language selection may affect content representation without guaranteeing that every returned review represents original source text in that language. Translated and original texts do not constitute two independent user opinions; analysis results must document applied language conditions and retain manual reviews for cross-language variations.
When using the Places API for public display, handle requirements for content attribution, author details, and source entry points according to current policies rather than copying text to your own pages. If data originates from another path, determine applicable licenses beforehand and avoid automatically applying or waiving Places requirements. In-memory examples in this document do not grant storage or redistribution authorization.
For internal analysis, prioritize processing only task-critical fields while restricting visitors and retention periods; model classifications and urgency levels should be labeled as derived judgments. Systems may organize human review queues, but low ratings should not trigger automated replies, public contacts with authors, or changes to store operational statuses.
Verify One Location Completely Before Scaling Workflows
Upon completing your first integration round, you should be able to explain: why you have authorization to process this data set, which store was targeted, what sorting and language options were chosen, which fields are substantiated, how reply changes are identified, and what elements were missing in this run. You should also be able to trace issues back to request IDs and verify actual billing rather than leaving behind an anonymous review file.
Once these questions are answered, expand your location lists or schedule regular runs. A sustainable review workflow not only reads data successfully, but also keeps location identities, use cases, sample scopes, and change records consistently clear.