Beiträge

Alle Beitragsendpunkte: cURL/Python/Node-Beispiele, Ankündigungen, Veranstaltungen, Angebote, Planung, Standort-/Massenkampagnen, Statusabfragen, Löschen.

Ein Beitrag ist eine kurze Mitteilung, die im Google Business Profile oder auf der Facebook-Seite eines Standorts veröffentlicht wird: eine Ankündigung, eine Veranstaltung mit Datum oder ein Angebot mit Gutschein. Eine Kampagne kann gleichzeitig viele Standorte und beide Plattformen ansprechen. Die Veröffentlichung erfolgt asynchron, sodass jeder Aufruf zum Erstellen sofort zurückkehrt und Sie das Ergebnis durch wiederholte Abfragen abrufen. Die drei GET-Endpunkte funktionieren mit einem Schlüssel mit Read (Lesezugriff); zum Erstellen und Löschen ist ein Schlüssel mit Write (Schreibzugriff) erforderlich.

Endpunkte im Überblick

MethodePfadFunktionReferenz
POST/postsVeröffentlichen Sie eine Ankündigung, eine einfache Nachricht mit optionaler Schaltfläche und optionalem Bild.Ankündigungsbeitrag erstellen
POST/postsVeröffentlichen Sie eine Veranstaltung mit einem Titel sowie einem Start- und Endzeitpunkt.Veranstaltungsbeitrag erstellen
POST/postsVeröffentlichen Sie ein Angebot mit Gutscheincode, Rabatt und Bedingungen.Angebotsbeitrag erstellen
GET/posts/{postId}Eine Kampagne mit Veröffentlichungsstatus und Interaktionszahlen pro Plattform.Beitrag abrufen
GET/locations/{locationId}/postsEine Ergebnisseite mit Kampagnen, die auf einen Standort ausgerichtet sind.Beiträge für einen Standort abrufen
DELETE/posts/{postId}Löschen Sie eine Kampagne dauerhaft und nehmen Sie ihre Veröffentlichung überall zurück.Beitrag löschen
POST/bulk-postsEine Kampagne, die auf viele Standorte verteilt wird.Massenbeitrag erstellen
GET/bulk-posts/{postId}Eine Massenkampagne mit einer Aufschlüsselung der Analysedaten pro Standort.Massenbeitrag anhand der ID abrufen
GET/locations/{locationId}/bulk-postsMassenkampagnen, die einen Standort einschließen, mit Filtern und Sortierung.Massenbeiträge für einen Standort abrufen

Werte, die Sie überall verwenden

Alle vier folgenden Enums werden von jedem Endpunkt zum Erstellen gemeinsam verwendet.

FeldZulässige Werte
postTypeANNOUNCEMENT, EVENT, OFFER, COVID19, PRODUCT
postSites und jedes siteGOOGLE, FACEBOOK
postCta[].typeBOOK, ORDER, SHOP, LEARN_MORE, SIGN_UP, GET_OFFER
postMediaUrl[].typeIMAGE, VIDEO

Eine Ankündigung veröffentlichen

POST /posts

Eine Ankündigung enthält eine Nachricht und optional eine Schaltfläche und ein Bild pro Plattform. Geben Sie für jede in postSites aufgeführte Plattform einen postMessage-Eintrag an. Die Antwort gibt die neue Kampagne zurück, wobei status auf INPROGRESS gesetzt ist, da die Veröffentlichung im Hintergrund erfolgt.

Parameter

NameInErforderlichHinweise
input.postNamebodyJaInterner Kampagnenname, der Kunden nie angezeigt wird.
input.locationIdsbodyJaArray von base64-Standort-IDs.
input.postTypebodyJaHier ANNOUNCEMENT.
input.postSitesbodyJaArray aus GOOGLE und FACEBOOK.
input.postMessagebodyNeinArray von Objekten mit site und message.
input.postCtabodyNeinArray von Objekten mit site, type, url.
input.postMediaUrlbodyNeinArray von Objekten mit site, url, type.
input.clientMutationIdbodyNeinWird zur Zuordnung unverändert zurückgegeben.
Announcement
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "postName": "Grand Opening Announcement",    "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="],    "postType": "ANNOUNCEMENT",    "postSites": ["GOOGLE"],    "postMessage": [      { "site": "GOOGLE", "message": "We are now open! Visit us this week for our grand opening." }    ],    "postCta": [      { "site": "GOOGLE", "type": "LEARN_MORE", "url": "https://jennyhome.example/opening" }    ],    "postMediaUrl": [      { "site": "GOOGLE", "url": "https://cdn.example.com/opening.jpg", "type": "IMAGE" }    ]  }}'
JSON
{  "data": {    "createSocialPost": {      "success": true,      "errors": [],      "socialPost": {        "id": "U29jaWFsUG9zdDo0NDEyMg==",        "name": "Grand Opening Announcement",        "status": "INPROGRESS",        "type": "ANNOUNCEMENT",        "sites": ["GOOGLE"],        "publishDetails": [          { "site": "GOOGLE", "status": "PUBLISHING", "createdDate": "2026-06-28", "submissionError": null }        ],        "postLinks": [],        "locationIds": [1800289]      }    }  }}

Bewahren Sie socialPost.id auf. Dies ist die base64-Beitrags-ID, die jeder andere hier aufgeführte Endpunkt benötigt. Beide SDK-Hilfsfunktionen nehmen eine einzelne message-Zeichenfolge entgegen und erweitern sie zu einem Eintrag pro Plattform, sodass Sie das postMessage-Array nur in cURL von Hand erstellen.

Eine Veranstaltung veröffentlichen

POST /posts

Eine Veranstaltung wird als Karte mit Datum angezeigt. Der Zeitplan der Veranstaltung selbst steht in postContextInfo. Das separate postScheduledDates-Objekt steuert, wann der Beitrag selbst erscheint und abläuft, was üblicherweise dem Zeitraum vor der Veranstaltung entspricht. Google lehnt eine Veranstaltung ohne Titel ab, und beide SDKs lösen vor dem Senden einen Validierungsfehler aus, wenn title fehlt.

Parameter

NameInErforderlichHinweise
input.postTypebodyJaHier EVENT.
input.postContextInfo.titlebodyIn der Praxis jaTitel der Veranstaltung. Google lehnt Veranstaltungen ohne Titel ab.
input.postContextInfo.startDay, endDaybodyNeinDatumsangaben, YYYY-MM-DD.
input.postContextInfo.startTime, endTimebodyNeinZeichenfolgen zur Anzeige wie 10:00am.
input.postScheduledDatesbodyNeinObjekt mit startDatetime, endDatetime, removalSites.

Alle Angaben aus der Tabelle für Ankündigungen gelten ebenfalls.

Event
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "postName": "Summer Sale Kickoff Event",    "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="],    "postType": "EVENT",    "postSites": ["GOOGLE"],    "postContextInfo": {      "title": "Summer Sale Kickoff",      "startDay": "2026-07-15",      "startTime": "10:00am",      "endDay": "2026-07-15",      "endTime": "06:00pm"    },    "postMessage": [      { "site": "GOOGLE", "message": "Join us for the Summer Sale kickoff, refreshments and up to 40 percent off in store." }    ]  }}'
JSON
{  "data": {    "createSocialPost": {      "success": true,      "socialPost": {        "id": "U29jaWFsUG9zdDo0NDEyMw==",        "status": "INPROGRESS",        "type": "EVENT",        "scheduledStartDate": "2026-07-15",        "scheduledEndDate": "2026-07-15",        "contextInfo": {          "title": "Summer Sale Kickoff",          "startDay": "2026-07-15",          "startTime": "10:00am",          "endDay": "2026-07-15",          "endTime": "06:00pm"        }      }    }  }}

Der zurückgegebene Wert contextInfo ist der Veranstaltungszeitraum. scheduledStartDate und scheduledEndDate beschreiben den Zeitplan des Beitrags selbst, der hier mit den Veranstaltungsdaten übereinstimmt, da kein postScheduledDates gesendet wurde.

Ein Angebot veröffentlichen

POST /posts

Ein Angebot ist eine Aktionskarte mit einem Gutscheincode, einem Rabatt, einem Link zum Einlösen und Bedingungen. All das gehört in postContextInfo, und startDay und endDay begrenzen die Gültigkeit des Angebots statt die des Beitrags.

Parameter

NameInErforderlichHinweise
input.postTypebodyJaHier OFFER.
input.postContextInfo.titlebodyIn der Praxis jaBezeichnet das Angebot. Beide SDKs erfordern diese Angabe.
input.postContextInfo.couponCodebodyNeinCode, den der Kunde einlöst.
input.postContextInfo.discountbodyNeinFreitext wie 25%.
input.postContextInfo.redeemUrlbodyNeinWo das Angebot eingelöst wird.
input.postContextInfo.termsConditionsbodyNeinKleingedrucktes.
input.postContextInfo.startDay, endDaybodyNeinGültigkeitszeitraum, YYYY-MM-DD.
Offer
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "postName": "Festive 25 Percent Off",    "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="],    "postType": "OFFER",    "postSites": ["GOOGLE"],    "postContextInfo": {      "title": "25% off storewide",      "couponCode": "FESTIVE25",      "discount": "25%",      "redeemUrl": "https://jennyhome.example/festive",      "termsConditions": "Valid in-store only through July 6.",      "startDay": "2026-06-22",      "endDay": "2026-07-06"    },    "postMessage": [      { "site": "GOOGLE", "message": "Celebrate with us, 25 percent off everything in store this week." }    ],    "postCta": [      { "site": "GOOGLE", "type": "GET_OFFER", "url": "https://jennyhome.example/festive" }    ]  }}'
JSON
{  "data": {    "createSocialPost": {      "success": true,      "socialPost": {        "id": "U29jaWFsUG9zdDo0NDEyNA==",        "status": "INPROGRESS",        "type": "OFFER",        "contextInfo": {          "title": "25% off storewide",          "couponCode": "FESTIVE25",          "discount": "25%",          "startDay": "2026-06-22",          "endDay": "2026-07-06"        }      }    }  }}

Google akzeptiert ORDER und Facebook akzeptiert GET_OFFER für Angebotsschaltflächen. Wenn eine Aktion vorzeitig endet, löschen Sie die Kampagne, statt sie zu bearbeiten.

Einen Beitrag und seinen Status abrufen

GET /posts/{postId}

Gibt das veröffentlichte Ergebnis einer angenommenen Kampagne zurück. Die Antwort enthält unter data.socialPostView den Kampagneninhalt, einen publishDetails-Eintrag pro Website, Interaktionszähler und nach erfolgreicher Veröffentlichung die Links zu den veröffentlichten Beiträgen.

Parameter

NameInErforderlichHinweise
postIdpathJaBase64-ID des Beitrags aus der Antwort auf die Erstellung oder aus einer Liste.
Get a post
curl https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "socialPostView": {      "socialPostId": "U29jaWFsUG9zdDo0NDEyMg==",      "socialPostInfo": {        "status": "SUCCESS",        "type": "ANNOUNCEMENT",        "views": 128,        "clicks": 14,        "publishDetails": [          { "site": "GOOGLE", "status": "PUBLISHED", "publishedDate": "2026-06-28", "submissionError": null }        ],        "postLinks": [          { "site": "GOOGLE", "link": "https://www.google.com/maps/place/?post=44122" }        ]      },      "publishedLocationsCount": 1,      "socialPostAnalyticsBySite": [        { "site": "GOOGLE", "views": 128, "clicks": 14, "reactions": 3, "shares": 0, "comments": 1 }      ]    }  }}

Zwei Statusfelder sind relevant, und sie beantworten unterschiedliche Fragen.

FeldWertBedeutung
socialPostInfo.statusINPROGRESSAngenommen, die Veröffentlichung läuft noch.
SUCCESSVeröffentlichung abgeschlossen. Lesen Sie publishDetails, um das Ergebnis für jede Website zu erhalten.
SCHEDULEDWartet auf den Beginn des Zeitfensters postScheduledDates.
EXPIREDDas geplante Zeitfenster ist abgelaufen und der Beitrag ist nicht mehr online.
publishDetails[].statusPUBLISHINGDiese Website hat noch nicht geantwortet.
PUBLISHEDAuf dieser Website online. Die URL finden Sie in postLinks.
ERRORDiese Website hat den Beitrag abgelehnt. submissionError gibt den Grund an.

Eine Kampagne kann den Status SUCCESS haben, während eine darin enthaltene Website den Status ERROR aufweist. Prüfen Sie daher immer publishDetails, statt sich allein auf den Status auf oberster Ebene zu verlassen.

Die Beiträge eines Standorts auflisten

GET /locations/{locationId}/posts

Ein per Offset paginierter Verlauf aller Kampagnen, die einen bestimmten Standort einschließen, unter data.postsByLocation. Prüfen Sie damit, was bereits online ist, bevor Sie etwas Neues planen.

Parameter

NameInErforderlichHinweise
locationIdpathJaBase64-ID, unverändert übergeben.
pagequeryNeinSeitennummer, beginnend bei 1, Standardwert 1.
perPagequeryNeinStandardwert 10, darf 50 nicht überschreiten.
Posts on a location
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/posts?page=1&perPage=10" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "postsByLocation": {      "records": [        {          "id": "U29jaWFsUG9zdDo0NDEyMg==",          "name": "Summer Hours Update",          "status": "SUCCESS",          "type": "ANNOUNCEMENT",          "createdAt": "2026-06-28",          "views": 128,          "clicks": 14,          "sites": ["GOOGLE"]        }      ],      "pageInfo": { "totalPages": 1, "hasNextPage": false, "totalRecords": 1 }    }  }}

Diese Route bietet keinen serverseitigen Filter. Sie akzeptiert nur page und perPage und ignoriert alles andere. Lesen Sie daher type und status in jedem Datensatz und filtern Sie in Ihrem eigenen Code. Verwenden Sie stattdessen den unten beschriebenen Endpunkt zur Massenauflistung, um serverseitig zu sortieren und zu filtern.

Einen Beitrag löschen

DELETE /posts/{postId}

Die Löschung ist endgültig und entfernt den Beitrag von jeder Website, auf der er veröffentlicht wurde. Es gibt weder eine Möglichkeit zum Rückgängigmachen noch einen Endpunkt zum Bearbeiten. Um einen veröffentlichten Beitrag zu korrigieren, müssen Sie ihn daher löschen und einen Ersatz veröffentlichen.

Parameter

NameInErforderlichHinweise
postIdpathJaBase64-ID des Beitrags.
clientMutationIdbodyNeinOptional, wird zur Zuordnung unverändert zurückgegeben.
Delete
curl -X DELETE https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "clientMutationId": "delete-44122-req-1" }'
JSON
{  "data": {    "deleteSocialPost": {      "success": true,      "socialPostId": "U29jaWFsUG9zdDo0NDEyMg=="    }  }}

Beim Löschen eines unbekannten oder bereits gelöschten Beitrags wird eine Fehlerantwort zurückgegeben, in der data auf null statt auf success: false gesetzt ist.

Eine Kampagne für viele Standorte veröffentlichen

POST /bulk-posts

Dieselben Schnittstellenvorgaben wie bei POST /posts, ausgelegt auf große Standortbestände: Listen Sie jeden Standort in locationIds auf, und eine Kampagne deckt sie alle ab. Die Antwort steht unter dem Schlüssel createSocialPost, genau wie bei POST /posts.

Parameter

NameInErforderlichHinweise
input.postNamebodyJaInterner Kampagnenname.
input.locationIdsbodyJaAlle Base64-IDs der Standorte, für die veröffentlicht werden soll.
input.postTypebodyJaEVENT, OFFER und PRODUCT benötigen außerdem postContextInfo oder products.
input.postSitesbodyJaGOOGLE, FACEBOOK oder beide.
input.postScheduledDatesbodyNeinstartDatetime und endDatetime im Format ISO 8601. Erstellt den Beitrag als SCHEDULED.
input.componentIdentifierbodyNeinIhre eigene Referenz, später als Filter nützlich.
Bulk publish
curl -X POST https://listingsapi.com/api/v4/bulk-posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "postName": "July Reopening Announcement",    "locationIds": ["TG9jYXRpb246MTgwMDI4OQ==", "TG9jYXRpb246MTgwMDI5MA=="],    "postType": "ANNOUNCEMENT",    "postSites": ["GOOGLE", "FACEBOOK"],    "postMessage": [      { "site": "GOOGLE", "message": "We are back. Visit us this week for our summer menu." },      { "site": "FACEBOOK", "message": "We are back. Swing by for the new summer menu." }    ],    "postScheduledDates": {      "startDatetime": "2026-07-10T09:00:00Z",      "endDatetime": "2026-07-24T23:59:00Z"    }  }}'
JSON
{  "data": {    "createSocialPost": {      "success": true,      "errors": null,      "socialPost": {        "id": "U29jaWFsUG9zdDo5OTIwMQ==",        "name": "July Reopening Announcement",        "status": "SCHEDULED",        "type": "ANNOUNCEMENT",        "scheduledStartDate": "2026-07-10",        "scheduledEndDate": "2026-07-24",        "sites": ["GOOGLE", "FACEBOOK"],        "locationIds": [1800289, 1800290]      }    }  }}

Beide SDK-Hilfsfunktionen setzen sites standardmäßig auf Google und Facebook, lösen für Sie eine Zuordnung von Nachrichten zu Websites auf und kodieren numerische Standort-IDs, sodass eine Massenveröffentlichung in beiden SDKs meist mit dem kürzesten Aufruf möglich ist.

Eine Sammelkampagne abrufen

GET /bulk-posts/{postId}

Das Gegenstück zu GET /posts/{postId} für Sammelkampagnen. Es gibt dieselbe Struktur zurück, wobei publishedLocationsCount größer als 1 ist und socialPostAnalyticsByLocationId eine Aufschlüsselung der Analysedaten pro Filiale enthält.

Parameter

NameInErforderlichHinweise
postIdpathJaBase64-ID des Sammelbeitrags, keine unkodierte Ganzzahl.
Get a bulk post
curl https://listingsapi.com/api/v4/bulk-posts/U29jaWFsUG9zdDo1MTA4OA== \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "socialPostView": {      "socialPostId": "U29jaWFsUG9zdDo1MTA4OA==",      "socialPostInfo": {        "name": "Festive Offer - All Stores",        "status": "SUCCESS",        "type": "OFFER",        "views": 4210,        "clicks": 318,        "sites": ["GOOGLE", "FACEBOOK"]      },      "socialPostAnalyticsByLocationId": [        {          "locationId": 1800289,          "siteStats": [            { "site": "GOOGLE", "status": "PUBLISHED", "views": 1040, "clicks": 80 },            { "site": "FACEBOOK", "status": "PUBLISHED", "views": 360, "clicks": 26 }          ]        }      ]    }  }}

socialPostAnalyticsBySite summiert die Kampagnenwerte über alle Filialen, während socialPostAnalyticsByLocationId dieselben Zahlen pro Filiale aufschlüsselt. Prüfen Sie die status-Werte pro Filiale, um alle Standorte zu finden, bei denen ein Fehler auf einer Website aufgetreten ist.

Sammelkampagnen an einem Standort auflisten

GET /locations/{locationId}/bulk-posts

Unter data.rollupSocialPosts mit Offset-Paginierung. Im Gegensatz zur Liste pro Standort unterstützt diese Route Filter und Sortierung und ist damit der passende Endpunkt für ein Kampagnen-Dashboard.

Parameter

NameInErforderlichHinweise
locationIdpathJaBase64-ID, unverändert übergeben.
page, perPagequeryNeinOffset-Paginierung.
filtersqueryNeinJSON-kodiert, nach type, status, creationDateRange oder siteUrls.
sortFieldsqueryNeinJSON-kodiert, beispielsweise Feld created_at mit Sortierreihenfolge Descending.
locationIdsqueryNeinJSON-kodiertes Array zusätzlicher Standort-IDs, die einbezogen werden sollen.
componentIdentifierqueryNeinBeschränkt die Ergebnisse auf Kampagnen, die Ihre Integration erstellt hat.

Sortierbare Felder sind name, type, status, created_at, schedule_start_date, schedule_end_date, client_name, clicks, views und shares.

Bulk posts on a location
curl -G https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/bulk-posts \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'page=1' \--data-urlencode 'perPage=10' \--data-urlencode 'sortFields={"field":"created_at","order":"Descending"}'
JSON
{  "data": {    "rollupSocialPosts": {      "records": [        {          "id": "U29jaWFsUG9zdDo1MTA4OA==",          "name": "Festive Offer - All Stores",          "status": "SUCCESS",          "type": "OFFER",          "createdAt": "2026-06-20",          "views": 4210,          "clicks": 318        }      ],      "pageInfo": { "totalPages": 1, "hasNextPage": false, "totalRecords": 1 }    }  }}

Beide SDKs übernehmen die JSON-Kodierung der Objekte filters und sortFields für Sie. Übergeben Sie diese daher als native Dictionaries oder Objekte.

Fehler, die auftreten können

Code oder StatusBedeutungBehebung
400: Variable $input fehltDer Body wurde nicht in input eingebettet.Verschachteln Sie alle Felder unter einem einzigen Schlüssel input.
SY90016 als HTTP 400Für einen Erstellungs- oder Löschvorgang wurde ein Read-Schlüssel verwendet.Verwenden Sie einen Write-Schlüssel.
401Fehlender oder ungültiger Schlüssel.Senden Sie Authorization: API <YOUR_API_KEY>.
429 mit Retry-AfterZu viele Aufrufe, häufig durch wiederholtes Abfragen des Status eines Beitrags.Warten Sie die angegebene Anzahl an Sekunden. Siehe Ratenbegrenzungen.
200 mit success: falseValidierung fehlgeschlagen.Lesen Sie errors in data.createSocialPost.
per_page must not exceed 50perPage überschreitet die Obergrenze für die Standortliste.Fordern Sie höchstens 50 an.
tag is not a supported parameter for this querytag wurde an die Route für Beiträge pro Standort gesendet.Senden Sie nur page und perPage.

Die vollständige Liste finden Sie unter Fehlercodes.

Nächste Schritte