GET/api/v4/locations/{locationId}/posts

Fetch posts for a location

Returns a page of social post campaigns (announcements, events, offers) that target a single location.

Requires an API key. See Authentication for header format and key rotation.

Parameters

Path

NameTypeRequiredDescription
locationIdstringrequiredNumeric location ID (e.g. 1800289).

Query

NameTypeRequiredDescriptionDefault
tagstringrequiredSegment/tag to pull posts from. Pass `all` to fetch every post for the location. Omitting this returns an error, not an empty list.
pageintegeroptional1-based page number for offset pagination.1
perPageintegeroptionalNumber of records per page.
filtersstringoptionalJSON-encoded SocialPostFiltersInput (e.g. by `type`, `status`, `creationDateRange`, `siteUrls`).
sortFieldsstringoptionalJSON-encoded sort object `{ "field": "created_at", "order": "Descending" }`. `field` is one of name, type, status, created_at, schedule_start_date, schedule_end_date, client_name, clicks, views, shares.
locationIdsstringoptionalJSON-encoded array of location IDs to include alongside the path location.
componentIdentifierstringoptionalFilter to posts created by a specific component/integration.

Responses

200A page of post campaigns for the location. `records` is empty when the location has no posts yet.
{
  "data": {
    "rollupSocialPosts": {
      "records": [
        {
          "id": "U29jaWFsUG9zdDo0NDEyMg==",
          "name": "Summer Hours Update",
          "status": "SUCCESS",
          "type": "ANNOUNCEMENT",
          "createdAt": "2026-06-28",
          "scheduledStartDate": "2026-06-28",
          "scheduledEndDate": "2026-07-28",
          "views": 128,
          "clicks": 14,
          "shares": 0,
          "reactions": 3,
          "comments": 1,
          "sites": ["GOOGLE"],
          "message": [
            { "site": "GOOGLE", "message": "We have extended our summer hours! Open until 9pm on weekdays." }
          ],
          "cta": [
            { "type": { "value": "LEARN_MORE", "label": "Learn more" }, "url": "https://jennyhome.example/hours", "site": "GOOGLE", "tinyUrl": "https://tiny.cc/jh-hours" }
          ],
          "contextInfo": null,
          "mediaUrl": [
            { "url": "https://cdn.listingsapi.com/posts/44122/summer.jpg", "site": "GOOGLE", "type": "IMAGE" }
          ],
          "publishDetails": [
            { "site": "GOOGLE", "status": "PUBLISHED", "createdDate": "2026-06-28", "publishedDate": "2026-06-28", "submissionError": null }
          ],
          "postLinks": [
            { "site": "GOOGLE", "link": "https://www.google.com/maps/place/?post=44122" }
          ],
          "locationIds": [1800289],
          "clientName": "Jenny Home"
        }
      ],
      "locationDetails": [
        {
          "id": "TG9jYXRpb246MTgwMDI4OQ==",
          "name": "Jenny Home",
          "street": "19 east, 5th B cross road, Trinity Enclave Main Rd, Banjara Layout",
          "city": "Bengaluru",
          "postalCode": "560043",
          "countryIso": "IN",
          "stateIso": "KA",
          "stateName": "Karnataka",
          "storeId": null
        }
      ],
      "pageInfo": {
        "totalPages": 1,
        "hasNextPage": false,
        "hasPreviousPage": false,
        "totalRecords": 1
      }
    }
  }
}
401Unauthenticated — missing or invalid API key.
429Rate limit exceeded. Retry after the `Retry-After` header value.

Use this endpoint to pull the post history for a single storefront — every announcement, event, and offer campaign that includes the location, with its lifecycle status and per-post engagement counters (views, clicks, reactions).

Use case — pre-campaign audit. Before scheduling a new Google post for Jenny Home, call GET /locations/1800289/posts?tag=all to see what is already live, which posts are still SCHEDULED, and how the last announcement performed. Filter to a single kind with filters={"type":"OFFER"} (URL-encoded) to review only running offers.

Gotchas.

  • tag is effectively required. A request with no tag returns {"data":null,"errors":[{"message":"An error occurred processing your request."}]} rather than an empty result set. Pass tag=all to fetch across every segment.
  • Pagination is offset-based: use page and perPage, and read pageInfo.totalPages / pageInfo.totalRecords to know when to stop. The default sort is newest-first; override with sortFields.
  • sortFields takes a single object, not an array — sending an array raises a GraphQL validation error (HTTP 400).
  • Sustained polling can hit the account rate limit (HTTP 429); honor the Retry-After header.

The records array in the sample above is representative. The live seed location (Jenny Home) currently has no social posts, so a real call returns records: [] with pageInfo.totalRecords: 0.

Related: create posts with POST /posts, fetch one campaign with GET /posts/{postId}, or list bulk (multi-location) campaigns with GET /locations/{locationId}/bulk-posts.

curl -X GET 'https://listingsapi.com/api/v4/locations/<locationId>/posts?tag=<tag>' \
  -H "Authorization: API $LISTINGSAPI_KEY"