# Local Business Posts API (`listingsapi/local-business-posts-api`) Actor

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.

- **URL**: https://apify.com/listingsapi/local-business-posts-api.md
- **Developed by:** [Local Business Listings Submission API](https://apify.com/listingsapi) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Local Business Posts API

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](https://www.listingsapi.com). 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](https://www.listingsapi.com/pricing).

| 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](https://apify.com/listingsapi/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](https://docs.listingsapi.com/docs/posts).

### Examples

Check what you can publish to:

```json
{
  "apiKey": "<your key>",
  "operation": "connectedAccounts"
}
```

Publish an announcement to one location:

```json
{
  "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:

```json
{
  "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:

```json
{
  "apiKey": "<your key>",
  "operation": "getBulkPost",
  "pathParams": { "postId": "bulk-9911" }
}
```

Pull the last 200 posts for a location:

```json
{
  "apiKey": "<your key>",
  "operation": "postsOfLocation",
  "pathParams": { "locationId": "123" },
  "query": { "limit": 50 },
  "paginate": true,
  "maxItems": 200
}
```

### Output

Each post becomes one dataset row:

```json
{
  "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](https://docs.listingsapi.com/docs/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](https://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](https://apify.com/listingsapi/create-google-listing-api) for linking Google and Facebook profiles to your locations, which publishing depends on
- [Local Business Listings Submission API](https://apify.com/listingsapi/local-business-listings-submission-api) for creating and syncing locations
- [Create Bulk GBP Listings API](https://apify.com/listingsapi/create-bulk-gbp-listings-api) for creating Google listings across hundreds of locations in one run
- [Local Business Reviews API](https://apify.com/listingsapi/local-business-reviews-api) for reading and replying to reviews
- [Local SEO Analytics API](https://apify.com/listingsapi/local-seo-analytics-api) for publisher performance and listing coverage

### Links

- Documentation: [docs.listingsapi.com](https://docs.listingsapi.com/docs)
- Post endpoints: [docs.listingsapi.com/docs/posts](https://docs.listingsapi.com/docs/posts)
- SDKs: [docs.listingsapi.com/sdks](https://docs.listingsapi.com/sdks)
- MCP server: [listingsapi.com/mcp](https://www.listingsapi.com/mcp)
- Support: support@listingsapi.com

# Actor input Schema

## `apiKey` (type: `string`):

Your Listings API key. Create one at https://listingsapi.com. Publishing and deleting posts needs a key with Write access.

## `operation` (type: `string`):

Which posting endpoint to call.

## `pathParams` (type: `object`):

Values for placeholders in the endpoint path, for example { "locationId": "123" } or { "postId": "456" }.

## `query` (type: `object`):

Query string values such as limit, after or status filters.

## `body` (type: `object`):

JSON payload for the create operations. Follow the post type payload shown at https://docs.listingsapi.com/docs/posts.

## `paginate` (type: `boolean`):

Keep requesting pages while pageInfo.hasNextPage is true.

## `maxItems` (type: `integer`):

Stop after this many dataset items. Set 0 for no limit.

## Actor input object example

```json
{
  "operation": "postsOfLocation",
  "pathParams": {},
  "query": {},
  "body": {},
  "paginate": false,
  "maxItems": 0
}
```

# Actor output Schema

## `results` (type: `string`):

Every post, bulk post, connected account or location returned by the operation you ran.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("listingsapi/local-business-posts-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("listingsapi/local-business-posts-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call listingsapi/local-business-posts-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,listingsapi/local-business-posts-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tCodmmwr0HGeEntHe/builds/YXbxufokODCZNE2O1/openapi.json
