Google Maps Business Posts Scraper: GBP Updates, Offers, Events
Pricing
$1.00 / 1,000 post delivereds
Google Maps Business Posts Scraper: GBP Updates, Offers, Events
Scrape the posts a business publishes on its Google Business Profile (GBP, GMB): updates, offers with coupon codes and terms, events with dates, photos, videos and buttons. By Maps link, place id, CID, name, or a search like "dentist in Austin". No login. Export to JSON, CSV or Excel, or via API.
Pricing
$1.00 / 1,000 post delivereds
Rating
0.0
(0)
Developer
Steady Scrape
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Security
Limited permissionsShare
Google Maps Business Posts Scraper (Google Business Profile posts, GMB posts)
Scrape the posts a business publishes on its Google Business Profile, the "Updates" Google Maps shows on the business's page: what's new updates, offers with their coupon code, terms and redeem link, events with their start and end, photos, videos, hashtags, links and the post's button ("Call now", "Book", "Order online", "Learn more"). Newest first, as far back as Google keeps them (years).
Give the businesses by Google Maps link, place id, CID or "name, city", or give a search term such as
dentist with a location, and the posts of the businesses Google Maps lists first are read. No login, no browser, no
Google API key. Export the posts to JSON, CSV or Excel, or read them through the API.
What you can do with Google Business posts
- Competitor monitoring for local SEO: see what the competitors around a client post, how often, which offers they
run and which buttons they use. The
ACTIVITYrecord ranks every business read by how recently and how often it posts. - Find businesses that stopped posting (an agency's sales list): a search for
roofer in DenverwithdaysSinceLatestPosttells who has not posted in months, and ano_postsrow who never did. - Collect local offers and events:
postTypes: ["offer"]returns only offers, with the coupon code, terms and dates;["event"]only events. - Archive a client's own posts: every post with its text, images and public post link, for reports or a migration.
- Content research: what dentists, gyms or restaurants actually post, with the hashtags and links they use.
Input
| field | what it does |
|---|---|
businesses | One per line: a Google Maps link (also maps.app.goo.gl share links), a place id (ChIJ…), a CID, or "name, city". Up to 500. |
searchTerms | Searches typed as in Google Maps (dentist, coffee shop in Portland). Up to 50. |
location | Written after each search term: dentist + Austin, TX is searched as dentist in Austin, TX. |
maxBusinessesPerSearch | How many of the businesses Google Maps lists first per search are read (1–20, default 10). |
maxPostsPerBusiness | The newest posts delivered per business (1–1,000, default 10). |
postedWithinDays | Only posts published in the last N days; 0 for any date. |
postTypes | Only these kinds: update, event, offer, alert. Empty for every kind. |
language, country | Language of labels such as "5 hours ago", and the country Google answers for (default en, us). |
Input example
{"businesses": ["https://www.google.com/maps/place/Swish+Dental+Downtown/data=!4m2!3m1!1s0x8644b5b434046875:0x644e6eb422388b7a","15910258412779129905","Franklin Barbecue, Austin TX"],"searchTerms": ["dentist"],"location": "Austin, TX","maxBusinessesPerSearch": 3,"maxPostsPerBusiness": 20,"postedWithinDays": 90}
Output: one row per Google Business post
{"rowType": "post","businessName": "Seven Grand","primaryCategory": "Bar","address": "405 E 7th St, Austin, TX 78701","website": "http://sevengrandaustin.com/","rating": 4.7,"reviewCount": 729,"cid": "15910258412779129905","placeId": "ChIJvYIs_6a1RIYRMcxe8rqXzNw","mapsUrl": "https://www.google.com/maps?cid=15910258412779129905","positionInBusiness": 1,"postId": "2569776269900488028","postType": "offer","title": "Join Friends of the Bar: 350 Points + $10 Off","text": "Friends of the Bar is our free loyalty program. Sign up and we'll drop 350 bonus points on your account…","publishedAt": "2026-08-10T20:24:16.000Z","postedLabel": "Aug 10, 2026","startsAt": "2026-08-10T05:00:00.000Z","endsAt": "2026-11-09T05:59:59.000Z","scheduleLabel": "Valid Aug 10 - Nov 8","offerCouponCode": null,"offerRedeemUrl": "https://www.toasttab.com/seven-grand-austin/rewardsSignup?utm_source=google&utm_medium=offer_post&utm_campaign=fotb_signup_2026q2","offerTerms": "New members only. 350 bonus points (about $5 in reward value) awarded after loyalty signup…","buttonType": "view_offer","buttonLabel": "View Offer","imageUrls": ["https://lh3.googleusercontent.com/geougc/AF1QipMz5vR5I3S9-Mpa3UWnwHmpczTVAnZ62K6NDlRz=h400-no"],"videos": [],"postUrl": "https://search.google.com/local/posts?q=Seven+Grand&ludocid=15910258412779129905&lpsid=CIHM0ogKEN6S--bj_q6hkgE&source=sh/x/loc/post&lsig=AB86z5UX894jlxgZsmwcQr-BT-is","source": "business","input": "15910258412779129905","searchQuery": null,"searchRank": null}
A business that delivered no post gets one free row saying why:
{"rowType": "business","status": "no_posts","reason": "the business has published no posts on Google Maps","businessName": "Jays Home Auto Repair","cid": "13537352006029681092","latestPostAt": null}
Post fields
| field | meaning |
|---|---|
rowType | post for a post; business or search for a free row (see below) |
postId | Google's id of the post |
postType | update (what's new), event, offer, alert (the COVID-19 notices of 2020–2021); null for a kind Google adds later |
title | The title of an event or an offer (updates have none) |
text | The post's text, with its line breaks |
links, hashtags | Links written in the text, and hashtags without the # |
publishedAt, postedLabel | When it was published (ISO, UTC) and how Google shows it ("5 hours ago", "Aug 10, 2026") |
expiresAt | Until when Google shows it: an event's or offer's end, or six months after an update |
startsAt, endsAt, scheduleLabel | An event's or offer's dates, and as Google writes them ("Valid Aug 10 - Nov 8") |
offerCouponCode, offerRedeemUrl, offerTerms | An offer's code, redeem link and terms and conditions |
buttonType, buttonLabel, buttonUrl, buttonPhone | The post's button: book, order_online, buy, learn_more, sign_up, view_offer or call, with its link or phone number |
imageUrls, videos | Photos (400 px high; change =h400 in the link for another size) and videos (thumbnail and video link) |
postUrl | The post's own public page |
businessName, primaryCategory, address, phone, website, rating, reviewCount, cid, placeId, mapsUrl | The business |
source, input, inputIndex, searchQuery, searchRank, positionInBusiness | Where the business came from (the input as typed and its position in its list), and the post's place among its posts |
scrapedAt | When the run read it (ISO, UTC) |
Free rows
status | when |
|---|---|
no_posts | The business has never posted (or deleted every post) |
no_matching_posts | It has posts, but none of the kinds or dates asked; latestPostAt says when it last posted |
business_not_found | The link, id or name leads to no Google Maps place; a name that matches several places is not guessed |
invalid | Not a Google Maps link, id or name (a Yelp link, a Maps search link) |
blocked | Google refused every IP the run could ask from before the business's posts were read |
spending_limit | The run's spending limit was reached before this business |
no_results (search row) | A search term Google Maps lists no business for |
The ACTIVITY record
The run's key-value store also holds ACTIVITY: one entry per business read, most active first, with latestPostAt,
daysSinceLatestPost, postsLast30Days, postsLast90Days, postsRead and allPostsRead. The counts come from every post
read, at least the newest 100 per business even when you ask fewer, so a run of 10 posts per business still tells who
posts weekly. SUMMARY holds the run's counts.
Pricing
US$0.001 per post delivered (US$1 per 1,000 posts). Free rows (no posts, not found, blocked, spending limit) are never charged, and the run stops at your spending limit. A business found by a search costs only its posts: the search itself is free.
How it reads Google Maps, and when Google asks for verification
It asks Google Maps the same questions its own web page asks when you open a business's "Updates" tab, at a person's
pace, over HTTP: 100 posts per request, so a business with 139 posts takes two. If Google asks an IP for
verification — its "unusual traffic" page, a CAPTCHA, a JavaScript check, or any answer that is not Google Maps'
normal data — that IP is done for the run: nothing more is sent from it, and the run goes on from another IP of
Apify's datacenter proxy. It never solves, bypasses or replays a challenge. Plain overloads (HTTP 429 or 5xx without a
challenge) take the same way. When every IP the run can use has been refused, the posts already read are delivered,
the businesses left get a free blocked row that says so, and the run ends successfully with a message to try again
later.
Limits
- Up to 500 businesses and 50 search terms per run; up to 20 businesses per search (Google Maps' first page of results).
- Up to 1,000 posts per business, newest first.
- A name is accepted only when the place Google finds carries that name; give the Maps link when a name is ambiguous.
- Posts the business deleted cannot be read; expired offers and past events are still listed and are delivered.
- Photos come as Google's image links; the Actor does not download files.
Is it legal?
It reads posts businesses publish for anyone to see on Google Maps, without logging in, at a pace a person browsing the map could produce. Posts are business content, not personal data. Use the data in line with Google's terms and the laws that apply to you.
This Actor is not affiliated with, endorsed by or sponsored by Google. Google, Google Maps and Google Business Profile are trademarks of Google LLC.