Standard posts, events, and offers
One payload picks the format — standard updates, date-bound events, or promotional offers with coupon codes and redeem URLs.
Publish local posts, events, and offers to Google Business Profile locations via one API. Manage hours, attributes, menus, and photos, reply to reviews, and read location analytics from the same integration.
One request reaches every location your profile manages — alongside every other network you publish to.
Free plan No credit card Live in under 5 minutes
One payload picks the format — standard updates, date-bound events, or promotional offers with coupon codes and redeem URLs.
Attach LEARN_MORE, BOOK, ORDER, SHOP, SIGN_UP, or CALL buttons to any post via cta_action_type and cta_url.
A single connected profile manages multiple accounts and locations. Target any location by passing its location_id from the placements endpoint.
Use the Profile Comments API to read incoming Google reviews and post replies. Reviews sync hourly; replies post on demand.
Read and update regular, special, and named extra hour sets like kitchen hours — patch only the fields that changed.
Set attributes like payments and accessibility, and manage each location's service list through the profile management endpoints.
Publish and update food menus and manage the location's photo gallery — same location_id you use for posting.
Set "Order online", "Book a table", and other place action links that appear directly on the listing in Search and Maps.
Per-location performance through profile stats: Search and Maps impressions, website clicks, call clicks, direction requests, bookings, and food orders.
$ curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": {
"body": "We are now open on Sundays from 10am to 4pm — come visit!"
},
"profiles": ["google_business"],
"platforms": {
"google_business": {
"format": "standard",
"location_id": "accounts/123456789/locations/987654321",
"cta_action_type": "LEARN_MORE",
"cta_url": "https://acme.example.com/hours"
}
}
}' {
"id": "gb_abc123",
"body": "We are now open on Sundays from 10am to 4pm — come visit!",
"status": "scheduled",
"draft": false,
"source": "postproxy",
"scheduled_at": "2026-05-04T20:00:00.000Z",
"queue_id": null,
"created_at": "2026-05-04T20:00:00.100Z",
"media": [],
"platforms": [
{
"platform": "google_business",
"status": "pending",
"permalink": null,
"error": null,
"params": {
"format": "standard",
"location_id": "accounts/123456789/locations/987654321",
"cta_action_type": "LEARN_MORE",
"cta_url": "https://acme.example.com/hours"
},
"attempted_at": null
}
]
} $ curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": {
"body": "Join us for our 5-year anniversary party — live music, free coffee, prizes."
},
"profiles": ["google_business"],
"media": ["https://example.com/event.jpg"],
"platforms": {
"google_business": {
"format": "event",
"location_id": "accounts/123456789/locations/987654321",
"event_title": "Acme Coffee 5-Year Anniversary",
"event_start_date": "2026-06-15",
"event_start_time": "18:00",
"event_end_date": "2026-06-15",
"event_end_time": "22:00",
"cta_action_type": "LEARN_MORE",
"cta_url": "https://acme.example.com/anniversary"
}
}
}' {
"id": "gb_def456",
"body": "Join us for our 5-year anniversary party — live music, free coffee, prizes.",
"status": "scheduled",
"draft": false,
"source": "postproxy",
"scheduled_at": "2026-05-04T20:02:00.000Z",
"queue_id": null,
"created_at": "2026-05-04T20:02:00.140Z",
"media": [
{
"id": "gb_m1",
"status": "pending",
"error_message": null,
"content_type": "image/jpeg",
"source_url": "https://example.com/event.jpg",
"url": null
}
],
"platforms": [
{
"platform": "google_business",
"status": "pending",
"permalink": null,
"error": null,
"params": {
"format": "event",
"location_id": "accounts/123456789/locations/987654321",
"event_title": "Acme Coffee 5-Year Anniversary",
"event_start_date": "2026-06-15",
"event_start_time": "18:00",
"event_end_date": "2026-06-15",
"event_end_time": "22:00",
"cta_action_type": "LEARN_MORE",
"cta_url": "https://acme.example.com/anniversary"
},
"attempted_at": null
}
]
} $ curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": {
"body": "20% off all whole-bean coffee through the end of the month."
},
"profiles": ["google_business"],
"platforms": {
"google_business": {
"format": "offer",
"location_id": "accounts/123456789/locations/987654321",
"event_start_date": "2026-06-01",
"event_end_date": "2026-06-30",
"offer_coupon_code": "BEANS20",
"offer_redeem_url": "https://acme.example.com/shop",
"offer_terms": "One per customer. Cannot be combined with other offers."
}
}
}' {
"id": "gb_ghi789",
"body": "20% off all whole-bean coffee through the end of the month.",
"status": "scheduled",
"draft": false,
"source": "postproxy",
"scheduled_at": "2026-05-04T20:04:00.000Z",
"queue_id": null,
"created_at": "2026-05-04T20:04:00.180Z",
"media": [],
"platforms": [
{
"platform": "google_business",
"status": "pending",
"permalink": null,
"error": null,
"params": {
"format": "offer",
"location_id": "accounts/123456789/locations/987654321",
"event_start_date": "2026-06-01",
"event_end_date": "2026-06-30",
"offer_coupon_code": "BEANS20",
"offer_redeem_url": "https://acme.example.com/shop",
"offer_terms": "One per customer. Cannot be combined with other offers."
},
"attempted_at": null
}
]
} View full documentation for all platform-specific features for Google Business
View documentationOne test post against a sandbox account is the easy part. Production Google Business publishing means app verification, OAuth across many accounts, media pipelines, dozens of edge cases, and a permanent on-call rotation for "why didn't this one go through this time?"
Social media integration is not a one-off job — it's a constant commitment. Platforms change their APIs, scopes, limits, and policies on their own schedule. Every change becomes your problem unless someone else is absorbing it.
That's exactly what Postproxy does for Google Business — and every other platform we support — so your team ships features instead of chasing failed publishes.
Free plan includes the Google Business API. No credit card.
Postproxy handles OAuth, account/location discovery, and the local-posts endpoint shape. You send a body and a location_id — we make the right calls.
Publish the same post body to Google Business alongside Instagram, LinkedIn, Bluesky, and the rest in one /api/posts call.
The Profile Comments API surfaces reviews on every connected location and lets you reply via POST. Webhooks fire as new reviews arrive.
Automatic retries, clear status, and HMAC-signed webhooks for every Google Business outcome — including deletions.
standard (default), event, offer, and photo — and each accepts only its relevant fields. Local-post bodies carry up to 1,500 characters; you can attach one image (5 MB, jpg or png, minimum 400×300, recommended 4:3 at 1200×900). The photo format skips the text wrapper and uploads a single image straight to the location's media gallery. Video attachments are not part of the Google Business APIs and will be rejected.event_title, event_start_date and event_end_date (YYYY-MM-DD), plus optional event_start_time and event_end_time in 24-hour format. Offers require the same date window and accept offer_coupon_code, offer_redeem_url, and offer_terms — Google renders the coupon code prominently on the listing and surfaces the redeem URL as the CTA. Same body, same media rules; only the format changes.cta_action_type: LEARN_MORE, BOOK, ORDER, SHOP, SIGN_UP, or CALL. Every type except CALL requires cta_url to point the button at an HTTPS endpoint. The button shows on the local-post card in search and Maps results.GET /api/profiles/:profile_id/comments lists incoming reviews; POST with the review's external ID as parent_id publishes a reply. Reviews sync hourly, replies post on demand. Unlike the Places API — which returns at most 5 relevance-sorted reviews for any place and cannot reply — you get the location's full review history, newest-first and paginated. You can't post top-level reviews via the API — only customers create those — and you can delete your own replies, not the originals. Webhook events fire as new reviews arrive./api/profiles/:profile_id/google_business/ and takes the same location_id you use for posting. Updates follow Google's field-mask model — read the resource, edit it, patch back only what changed. Guides: hours, attributes, photos, menus and services, action links.location_id as placement_id. Snapshots are trailing 30-day totals: Search and Maps impressions (desktop and mobile, summed into views), website clicks, call clicks, direction requests, conversations, bookings, and food orders. Google Business has no follower count, and Google exposes no per-post analytics for local posts. Guide: pull location insights via API.POST /api/profile_groups/:id/initialize_connection with platform: google_business. Postproxy stores the refresh token and lists every account and location the user authorised. List them with GET /api/profiles/:id/placements — each location returns its resource path (accounts/X/locations/Y), which you pass as location_id on the post. One profile can manage multiple accounts and any number of locations.Ask your favorite LLM what it thinks about us, then decide.
Common questions about Google Business integration
Initiate the OAuth flow via /api/profile_groups/:id/initialize_connection with platform: google_business. Postproxy stores the refresh token and lists every account and location the user authorised.
1,500 characters per post summary. Same limit applies to standard posts, events, and offers.
No. Google Business local posts accept up to one image (jpg or png, 5 MB, minimum 400×300). Video attachments are not supported by the local-posts API.
LEARN_MORE, BOOK, ORDER, SHOP, SIGN_UP, and CALL. Every type except CALL requires a cta_url to point the button at.
POST to /api/profiles/:profile_id/comments with the review's external ID as parent_id. The Profile Comments API syncs reviews hourly; replies post on demand.
List placements via /api/profiles/:id/placements — each location is returned with its resource path (accounts/X/locations/Y). Pass that path as platforms.google_business.location_id on the post.
Three Google APIs share the name and only one can reply. The Business Profile API returns a managed location's full review history and is the only one that can post an owner reply. The Places API returns at most 5 reviews for any place, sorted by relevance, with no reply access. The Play In-App Review API only shows a rating prompt inside an Android app — it reads nothing. Whether you manage the locations is the question that picks the path.
Five, sorted by relevance, with no pagination and no way to reply. Postproxy returns a managed location's full review history instead, newest-first and paginated.
No. Reviews are user-generated and no API accepts one on a reviewer's behalf. You can read every review on a location you manage and reply to it.
Start with our free plan and scale as your needs grow. No credit card required.