Google Business

Google Business posts

Publish updates, events and offers to a Google Business Profile location, add a call-to-action button, post to many locations at once and edit published posts.

Posts on a Google listing show up in Search and Maps next to the business, not in a feed. They are a good place for this week's special, an event or a discount code. You publish them with the same POST /v1/posts call as every other platform, with platform: "googlebusiness" and a few Google-only settings in platformSpecificData.

#Post types

topicType Use it for Needs
STANDARD (default) News, updates, a new product Nothing extra
EVENT Anything with dates: an opening, a workshop, live music An event with title and schedule
OFFER Promotions and discounts An offer; an event is optional and sets the offer's validity period

Any type can add a callToAction button.

#Publish an update

curl -X POST https://api.pozy.ai/v1/posts \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Pumpkin and walnut loaves are back for the autumn. Baked fresh every morning from 7:30.",
    "mediaItems": [{ "type": "image", "url": "https://pozy.ai/media/autumn-loaf.jpg" }],
    "platforms": [{
      "platform": "googlebusiness",
      "accountId": "6713b0e5d1f4c69a2b8e3f75",
      "platformSpecificData": {
        "callToAction": { "type": "ORDER", "url": "https://example.com/order" }
      }
    }],
    "publishNow": true
  }'

To schedule it, replace publishNow with scheduledFor and a timezone (Scheduling). Leave out mediaItems for a text-only post, though posts with an image or a button get more attention.

#Call-to-action buttons

callToAction.type Button
LEARN_MORE Links to more information
BOOK Booking or reservation page
ORDER Online ordering
SHOP Online shop
SIGN_UP Registration or newsletter
CALL Calls the business

url must be a working HTTPS link. Avoid link shorteners; Google may not follow them.

#Publish an event

Set topicType: "EVENT" and an event with a title and a schedule. Dates are { year, month, day } objects and times are { hours, minutes } in 24-hour time. Times are optional. Pozy also accepts ISO 8601 strings for all four and converts them.

platforms entry
{
  "platform": "googlebusiness",
  "accountId": "6713b0e5d1f4c69a2b8e3f75",
  "platformSpecificData": {
    "topicType": "EVENT",
    "event": {
      "title": "Sourdough workshop",
      "schedule": {
        "startDate": { "year": 2026, "month": 11, "day": 14 },
        "startTime": { "hours": 10, "minutes": 0 },
        "endDate": { "year": 2026, "month": 11, "day": 14 },
        "endTime": { "hours": 13, "minutes": 0 }
      }
    },
    "callToAction": { "type": "SIGN_UP", "url": "https://example.com/workshop" }
  }
}

Google shows the title and dates as the heading of the post.

#Publish an offer

Set topicType: "OFFER" and an offer with any of couponCode, redeemOnlineUrl and termsConditions. All three are optional, but an offer with none of them gives people nothing to act on. Add an event to give the offer a heading and an end date.

platforms entry
{
  "platform": "googlebusiness",
  "accountId": "6713b0e5d1f4c69a2b8e3f75",
  "platformSpecificData": {
    "topicType": "OFFER",
    "event": {
      "title": "10% off all cakes",
      "schedule": {
        "startDate": { "year": 2026, "month": 12, "day": 1 },
        "endDate": { "year": 2026, "month": 12, "day": 23 }
      }
    },
    "offer": {
      "couponCode": "XMAS10",
      "redeemOnlineUrl": "https://example.com/cakes",
      "termsConditions": "Orders placed by 23 December. One code per order."
    }
  }
}

#Post to several locations

If one Google login manages several locations, you can post to all of them in one request. Repeat the platforms entry with the same accountId and a different locationId (locations/ followed by the location id from GET .../gmb-locations). An entry without locationId goes to the account's selected location.

Request body
{
  "content": "Both shops are open on the holiday Monday, 8:00 to 14:00.",
  "platforms": [
    { "platform": "googlebusiness", "accountId": "6713b0e5d1f4c69a2b8e3f75",
      "platformSpecificData": { "locationId": "locations/4821930576104832190" } },
    { "platform": "googlebusiness", "accountId": "6713b0e5d1f4c69a2b8e3f75",
      "platformSpecificData": { "locationId": "locations/5930184726391058277" } }
  ],
  "publishNow": true
}

The response has one platforms entry per location, each with its own status and link.

#Edit a published post

POST /v1/posts/{postId}/edit with platform: "googlebusiness" and the new content changes the text of a live post. There is no edit window and no limit on edits, and the post keeps its id. Only the text changes: the image, button, event and offer details stay as published. To change those, publish a new post.

cURL
curl -X POST https://api.pozy.ai/v1/posts/6718a5d0c6e9b14f7a3d8e2a/edit \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "googlebusiness",
    "content": "Pumpkin and walnut loaves are back. Baked fresh every morning from 7:30, while they last."
  }'

If the post went to two accounts, add accountId to pick one. A post sent to several locations from one account always edits that account's first entry. A 404 means the post no longer exists on Google: it was deleted on Google, or it is an event or offer whose end date has passed.

#Limits

Property Limit
Text 1,500 characters
Images 1 per post
Video Not supported
Image format JPEG or PNG. WebP is converted for you. GIF is rejected.
Image size Up to 5 MB. Larger images are compressed before sending.
Image dimensions At least 400 x 300 px. 1200 x 900 px (4:3) crops best.
languageCode Optional BCP 47 code. It labels the post and does not translate it.

Image URLs must be public HTTPS links that return the file itself. Upload media to get one.

Google does not offer per-post analytics. Use location-level metrics from Platform insights instead.

#Common errors

Error Cause Fix
207 with post.status: "failed" The post was saved but Google rejected it. The reason is in platforms[].errorMessage. Fix and create a new post. A failed post is not retried.
"Request contains an invalid argument" on an event topicType: "EVENT" without an event, or a schedule missing a date Add event.title, startDate and endDate
"Image too small" Under 400 x 300 px Use a larger image
"Invalid image format" Not JPEG or PNG, or a corrupt file Re-export as JPEG or PNG
Post published but not visible Google is reviewing it, or the location is not verified Allow up to 48 hours and check verification
207 counts as success in most HTTP clients

207 is a 2xx status, so fetch(...).ok is true. Check the status code and post.status before you report success.

#Endpoints

Endpoint What it does
POST /v1/posts Create post
POST /v1/posts/{postId}/edit Edit published post
GET /v1/posts/{postId} Get post
GET /v1/accounts/{accountId}/gmb-locations List Google Business Profile locations

#Webhook events

Event When it fires
post.published Post published.
post.failed Post failed.
post.partial Post partial.
post.platform.published Post platform published.
post.platform.failed Post platform failed.
post.platform.deleted Post platform deleted.