/api/v4/bulk-postsCreate a bulk post
Creates one social post and publishes it across many locations in a single request.
Parameters
Body
| Name | Type | Required | Description |
|---|---|---|---|
| postName | string | required | Internal name for the campaign (not shown publicly). |
| locationIds | array of strings | required | Base64-encoded location Relay IDs to publish to. |
| postType | string | required | One of `EVENT`, `OFFER`, `ANNOUNCEMENT`, `COVID19`, `PRODUCT`. |
| postSites | array of strings | required | Target publishers: `GOOGLE` and/or `FACEBOOK`. |
| postMessage | array of objects | optional | Per-site post body. Each entry: `site` and `message`. |
| postMessage[].site | string | required | Publisher for this message: `GOOGLE` or `FACEBOOK`. |
| postMessage[].message | string | required | Post body text for that site. |
| postMediaUrl | array of objects | optional | Per-site media. Each entry: `site`, `url`, and `type` (`IMAGE` or `VIDEO`). |
| postMediaUrl[].site | string | required | Publisher for this media asset. |
| postMediaUrl[].url | string | required | Publicly accessible media URL. |
| postMediaUrl[].type | string | optional | `IMAGE` or `VIDEO`. |
| postCta | array of objects | optional | Per-site call-to-action button. Each entry: `site`, `type`, `url`. |
| postScheduledDates | object | optional | Scheduling window: `startDatetime`, `endDatetime`, and optional `removalSites`. |
| postScheduledDates.startDatetime | string | required | ISO-8601 datetime the post goes live. |
| postScheduledDates.endDatetime | string | required | ISO-8601 datetime the post is removed. |
| postContextInfo | object | optional | Type-specific details (offer coupon/redeem/terms, or event title/times). Required by `OFFER`, `EVENT`, and `PRODUCT` posts. |
| products | array of objects | optional | Product entries for `PRODUCT` posts (name, price, photo, cta). |
| componentIdentifier | string | optional | Optional client component reference for tracking. |
| componentType | string | optional | Optional client component type for tracking. |
Sample request
Ready-to-paste body. Replace placeholder IDs and values with yours.
{
"postName": "July Reopening Announcement",
"locationIds": [
"TG9jYXRpb246MTgwMDI4OQ==",
"TG9jYXRpb246MTgwMDI5MA=="
],
"postType": "ANNOUNCEMENT",
"postSites": ["GOOGLE", "FACEBOOK"],
"postMessage": [
{ "site": "GOOGLE", "message": "We're back! Visit us this week for our summer menu." },
{ "site": "FACEBOOK", "message": "We're back! Swing by for the new summer menu." }
],
"postMediaUrl": [
{ "site": "GOOGLE", "url": "https://cdn.example.com/summer.jpg", "type": "IMAGE" }
],
"postScheduledDates": {
"startDatetime": "2026-07-10T09:00:00Z",
"endDatetime": "2026-07-24T23:59:00Z"
}
}Responses
200Bulk post accepted. `success` is true and the created campaign is returned.
{
"data": {
"createBulkSocialPost": {
"clientMutationId": null,
"success": true,
"errors": null,
"socialPost": {
"id": "U29jaWFsUG9zdDo5OTIwMQ==",
"name": "July Reopening Announcement",
"status": "SCHEDULED",
"type": "ANNOUNCEMENT",
"createdAt": "2026-07-08",
"scheduledStartDate": "2026-07-10",
"scheduledEndDate": "2026-07-24",
"sites": ["GOOGLE", "FACEBOOK"],
"locationIds": [1800289, 1800290]
}
}
}
}401Unauthenticated — missing or invalid API key.
Creates a single post campaign and fans it out to every location in locationIds, publishing to the selected postSites. Unlike the per-location create, one call targets your whole fleet, which is the efficient way to run a company-wide announcement, offer, or event.
Use case — company-wide announcement (shown above). Set postType: "ANNOUNCEMENT", list the location IDs, and provide one postMessage per site. Add postScheduledDates to run the post over a fixed window; omit it to publish immediately.
Use case — a limited-time offer across all stores. Switch postType to OFFER and supply the coupon in postContextInfo:
{
"postName": "Summer 20% Off",
"locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="],
"postType": "OFFER",
"postSites": ["GOOGLE"],
"postMessage": [{ "site": "GOOGLE", "message": "20% off through July!" }],
"postContextInfo": {
"title": "Summer Sale",
"couponCode": "SUMMER20",
"redeemUrl": "https://example.com/offer",
"termsConditions": "Valid through July 31",
"startDay": "2026-07-10",
"startTime": "09:00",
"endDay": "2026-07-31",
"endTime": "23:59"
}
}
Gotchas.
postType,postSites,postName, andlocationIdsare required;EVENT,OFFER, andPRODUCTtypes additionally require the matchingpostContextInfo(orproducts) fields.postSitesaccepts onlyGOOGLEandFACEBOOK; the target locations must have the corresponding channel connected or that site is skipped.- The response returns HTTP 200 with
success: falseand a populatederrorsarray on partial or full validation failure — checksuccess, then track live delivery per location with the fetch bulk post endpoint.
curl -X POST 'https://listingsapi.com/api/v4/bulk-posts' \
-H "Authorization: API $LISTINGSAPI_KEY" \
-H 'Content-Type: application/json' \
-d '{
"postName": "<postName>",
"locationIds": "<locationIds>",
"postType": "<postType>",
"postSites": "<postSites>",
"postMessage": "<postMessage>",
"postMessage[].site": "<postMessage[].site>",
"postMessage[].message": "<postMessage[].message>",
"postMediaUrl": "<postMediaUrl>",
"postMediaUrl[].site": "<postMediaUrl[].site>",
"postMediaUrl[].url": "<postMediaUrl[].url>",
"postMediaUrl[].type": "<postMediaUrl[].type>",
"postCta": "<postCta>",
"postScheduledDates": "<postScheduledDates>",
"postScheduledDates.startDatetime": "<postScheduledDates.startDatetime>",
"postScheduledDates.endDatetime": "<postScheduledDates.endDatetime>",
"postContextInfo": "<postContextInfo>",
"products": "<products>",
"componentIdentifier": "<componentIdentifier>",
"componentType": "<componentType>"
}'