Local Business Posts API
Pricing
Pay per usage
Local Business Posts API
Publish announcements, offers and events to Google Business Profiles, Facebook, Instagram and X. Send one post to a single location or fan it out to 240 profiles in one call, then read back the per publisher result.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Local Business Listings Submission API
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
4 days ago
Last modified
Categories
Share
Publish announcements, offers and events to Google Business Profiles, Facebook Pages, Instagram and X, one location at a time or across hundreds of profiles in a single call.
This Actor wraps the posting endpoints of the Listings API. It replaces the usual work of holding four separate publisher integrations, each with its own token refresh and its own post format.
What this Actor does
- Creates an announcement, event or offer post for a location
- Creates a bulk post that fans out to every connected profile you select, up to 240 profiles in one call
- Lists posts already published for a location, with status per publisher
- Fetches a single post or a single bulk post by ID
- Deletes a post
- Lists your connected Google and Facebook accounts, their details and their GMB folders, so you know exactly where a post will land before you send it
Bulk post rows come back with the per profile result, so a partial failure is visible instead of silent.
Who this is for
- Multi location brands running the same weekly promotion across every store
- Agencies scheduling client content without logging into four dashboards
- Franchise systems pushing corporate campaigns to franchisee profiles
- Anyone who wants posting to run from a schedule or a webhook rather than a person
What you need
A Listings API account and an API key. Create one at listingsapi.com.
| Access level | Covers |
|---|---|
| Read | Listing posts, bulk posts and connected accounts |
| Write | Creating posts, creating bulk posts, deleting posts |
At least one connected Google or Facebook account is needed before a post can be published, and each profile has to be matched to a location. Run connectedAccounts here first to confirm what is linked, and use the Create Google Listing API Actor to connect anything that is missing.
Input
| Field | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your Listings API key. Stored as a secret. |
operation | string | Yes | Which endpoint to call. See the operations table. |
pathParams | object | No | Values for placeholders in the path, for example { "postId": "456" }. |
query | object | No | Query string values such as limit, after or a status filter. |
body | object | No | JSON payload for the create operations. |
paginate | boolean | No | Keep requesting pages while pageInfo.hasNextPage is true. Default false. |
maxItems | integer | No | Stop after this many dataset items. 0 means no limit. |
Operations
| Operation | Method and path | Returns |
|---|---|---|
allLocations | GET /locations | Your locations, used to look up location IDs |
searchLocations | GET /locations/search | Locations matching a search term |
postsOfLocation | GET /locations/{locationId}/posts | Posts published for one location |
getPost | GET /posts/{postId} | One post with per publisher status |
bulkPostsOfLocation | GET /locations/{locationId}/bulk-posts | Bulk posts that touched this location |
getBulkPost | GET /bulk-posts/{postId} | One bulk post and its fan out results |
createAnnouncementPost | POST /posts | Publishes a plain update post |
createEventPost | POST /posts | Publishes a post with a start and end date |
createOfferPost | POST /posts | Publishes a post with an offer, coupon or terms |
createBulkPost | POST /bulk-posts | Publishes one post to many profiles |
deletePost | DELETE /posts/{postId} | Removes a published post |
connectedAccounts | GET /connected-accounts | Google and Facebook accounts linked to your account |
connectedAccountDetails | GET /connected-accounts/{connectedAccountId}/details | Detail for one connected account |
gmbFoldersOfConnectedAccount | GET /connected-accounts/{connectedAccountId}/folders | GMB location groups under a connected account |
The three create operations use the same endpoint. The post type is carried in the payload. Payload shapes for each type are at docs.listingsapi.com/docs/posts.
Examples
Check what you can publish to:
{"apiKey": "<your key>","operation": "connectedAccounts"}
Publish an announcement to one location:
{"apiKey": "<your key>","operation": "createAnnouncementPost","body": {"input": {"locationId": "123","summary": "Extended evening hours from September. Open until 9pm Monday to Friday.","callToAction": { "actionType": "LEARN_MORE", "url": "https://example.com/hours" },"mediaUrls": ["https://example.com/img/hours.jpg"]}}}
Publish an offer across every connected profile in a region:
{"apiKey": "<your key>","operation": "createBulkPost","body": {"input": {"locationIds": ["123", "124", "125", "126"],"postType": "OFFER","summary": "20 percent off all servicing booked before 30 September.","couponCode": "SERVICE20","termsAndConditions": "One use per customer. Cannot be combined with other offers.","startDate": "2026-09-01","endDate": "2026-09-30"}}}
Check how a bulk post landed, profile by profile:
{"apiKey": "<your key>","operation": "getBulkPost","pathParams": { "postId": "bulk-9911" }}
Pull the last 200 posts for a location:
{"apiKey": "<your key>","operation": "postsOfLocation","pathParams": { "locationId": "123" },"query": { "limit": 50 },"paginate": true,"maxItems": 200}
Output
Each post becomes one dataset row:
{"id": "post-77219","locationId": "123","postType": "OFFER","summary": "20 percent off all servicing booked before 30 September.","state": "LIVE","publishedAt": "2026-09-01T06:00:00Z","publishers": [{ "site": "GOOGLE", "state": "LIVE", "url": "https://..." },{ "site": "FACEBOOK", "state": "LIVE", "url": "https://..." }]}
Exact fields follow the API response. Download the dataset as JSON, CSV, Excel or XML, or read it from the Apify API.
The run also writes a SUMMARY record to the key value store with the operation, pages fetched and items pushed.
Running it on a schedule
Two patterns work well. Schedule createBulkPost with a fixed payload for a recurring weekly promotion. Or schedule postsOfLocation daily and send the dataset to a webhook that flags any post sitting in a rejected or pending state.
Rate limits and pagination
Requests go out one at a time. The Actor reads pageInfo.hasNextPage before fetching the next page, waits out a 429 using retry_after_seconds, and retries server errors with a backoff. Plan limits are 10 requests per minute on Launch and 50 on Growth. See rate limits.
Errors
A non success response stops the run and logs the status, the URL and the response body including the correlation_id. Codes are listed at docs.listingsapi.com/docs/error-codes.
Publisher rejections are different. A post can be accepted by the API and then rejected by Google or Facebook for content reasons. Those show up in the per publisher state field rather than as a run failure, so check the output rather than only the exit code.
Cost
You pay Apify for platform usage of the run. Publishing is billed by your Listings API plan, which starts at 99 dollars a month with a 14 day trial.
Related Actors
- Create Google Listing API for linking Google and Facebook profiles to your locations, which publishing depends on
- Local Business Listings Submission API for creating and syncing locations
- Create Bulk GBP Listings API for creating Google listings across hundreds of locations in one run
- Local Business Reviews API for reading and replying to reviews
- Local SEO Analytics API for publisher performance and listing coverage
Links
- Documentation: docs.listingsapi.com
- Post endpoints: docs.listingsapi.com/docs/posts
- SDKs: docs.listingsapi.com/sdks
- MCP server: listingsapi.com/mcp
- Support: support@listingsapi.com