Post
Ogni endpoint post: esempi cURL, Python e Node, annunci, eventi, offerte, pianificazione, campagne per sede e massive, polling dello stato ed eliminazione.
Un post è un breve aggiornamento pubblicato sul Google Business Profile o sulla pagina Facebook di una sede: un annuncio, un evento con date definite o un'offerta con un coupon. Una campagna può rivolgersi a molte sedi e a entrambi i siti contemporaneamente. La pubblicazione è asincrona, quindi ogni chiamata di creazione restituisce subito una risposta e devi effettuare il polling per ottenere il risultato. I tre endpoint GET funzionano con una chiave Read (lettura); per creare ed eliminare serve una chiave Write (scrittura).
Panoramica degli endpoint
Valori che userai ovunque
Tutte e quattro le enumerazioni seguenti sono condivise da tutti gli endpoint di creazione.
Pubblica un annuncio
POST /posts
Un annuncio accetta un messaggio e, facoltativamente, un pulsante e un'immagine per sito. Fornisci una voce postMessage per ogni sito elencato in postSites. La risposta restituisce la nuova campagna con status impostato su INPROGRESS, perché la pubblicazione avviene in background.
Parametri
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" } ] }}'{ "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] } } }}Conserva socialPost.id. È l'id del post in base64 richiesto da tutti gli altri endpoint descritti qui. Entrambe le funzioni di supporto degli SDK accettano una singola stringa message e la espandono in una voce per sito, quindi devi costruire manualmente l'array postMessage solo in cURL.
Pubblica un evento
POST /posts
Un evento viene visualizzato come un riquadro con date. La pianificazione dell'evento stesso si trova in postContextInfo. L'oggetto separato postScheduledDates controlla quando il post stesso appare e scade, un intervallo che di solito corrisponde al periodo che precede l'evento. Google rifiuta un evento senza titolo ed entrambi gli SDK generano un errore di validazione prima dell'invio se manca title.
Parametri
Si applica anche tutto quanto riportato nella tabella dell'annuncio.
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." } ] }}'{ "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" } } } }}Il valore contextInfo restituito è l'intervallo temporale dell'evento. scheduledStartDate e scheduledEndDate descrivono la pianificazione del post stesso, che in questo caso coincide con le date dell'evento perché non è stato inviato alcun postScheduledDates.
Pubblica un'offerta
POST /posts
Un'offerta è una scheda promozionale che contiene un codice coupon, uno sconto, un link per usufruirne e le condizioni. Tutto questo va in postContextInfo, mentre startDay e endDay delimitano la validità dell'offerta anziché quella del post.
Parametri
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" } ] }}'{ "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 accetta ORDER e Facebook accetta GET_OFFER per i pulsanti delle offerte. Se una promozione termina in anticipo, elimina la campagna anziché modificarla.
Leggi un post e il suo stato
GET /posts/{postId}
Restituisce il risultato della pubblicazione di una campagna accettata. La risposta contiene, sotto data.socialPostView, il contenuto della campagna, una voce publishDetails per ogni sito, i contatori delle interazioni e i link ai post online una volta completata la pubblicazione.
Parametri
curl https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"{ "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 } ] } }}Due campi di stato sono rilevanti e rispondono a domande diverse.
Una campagna può riportare SUCCESS mentre uno dei siti al suo interno presenta ERROR, quindi controlla sempre publishDetails anziché soltanto lo stato di primo livello.
Elenca i post di una sede
GET /locations/{locationId}/posts
Una cronologia con paginazione basata su offset di tutte le campagne che includono una sede, sotto data.postsByLocation. Usala per verificare cosa è già online prima di programmare qualcosa di nuovo.
Parametri
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/posts?page=1&perPage=10" \-H "Authorization: API $LISTINGSAPI_KEY"{ "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 } } }}Questa route non dispone di filtri lato server. Accetta solo page e perPage e ignora qualsiasi altro parametro, quindi leggi type e status in ogni record e applica i filtri nel tuo codice. Per ordinare e filtrare lato server, usa invece l'endpoint per l'elenco in blocco riportato di seguito.
Elimina un post
DELETE /posts/{postId}
L'eliminazione è permanente e rimuove il post da ogni sito su cui è stato pubblicato. Non è possibile annullarla e non esiste un endpoint di modifica, quindi per correggere un post online devi eliminarlo e pubblicarne uno sostitutivo.
Parametri
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" }'{ "data": { "deleteSocialPost": { "success": true, "socialPostId": "U29jaWFsUG9zdDo0NDEyMg==" } }}L'eliminazione di un post sconosciuto o già eliminato restituisce una risposta di errore con data impostato su null anziché su success: false.
Pubblica una campagna su più sedi
POST /bulk-posts
Lo stesso contratto di POST /posts, pensato per gruppi di sedi: elenca tutte le sedi in locationIds e una sola campagna le coprirà tutte. La risposta usa la chiave createSocialPost, come POST /posts.
Parametri
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" } }}'{ "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] } } }}Le funzioni di supporto di entrambi gli SDK impostano Google e Facebook come valore predefinito di sites, espandono per te una mappa dei messaggi per sito e codificano gli ID numerici delle sedi, quindi una pubblicazione in blocco è di solito la chiamata più breve in entrambi gli SDK.
Leggere una singola campagna in blocco
GET /bulk-posts/{postId}
La controparte per le operazioni in blocco di GET /posts/{postId}. Restituisce la stessa struttura, con publishedLocationsCount maggiore di uno e un dettaglio delle analisi per punto vendita in socialPostAnalyticsByLocationId.
Parametri
curl https://listingsapi.com/api/v4/bulk-posts/U29jaWFsUG9zdDo1MTA4OA== \-H "Authorization: API $LISTINGSAPI_KEY"{ "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 riporta i totali della campagna per tutti i punti vendita, mentre socialPostAnalyticsByLocationId suddivide gli stessi numeri per punto vendita. Esamina i valori di status per punto vendita per trovare le sedi in cui si è verificato un errore su un sito.
Elencare le campagne in blocco di una sede
GET /locations/{locationId}/bulk-posts
Paginazione tramite offset sotto data.rollupSocialPosts. A differenza dell'elenco per sede, questa route accetta filtri e ordinamento, il che la rende l'endpoint adatto per una dashboard delle campagne.
Parametri
I campi utilizzabili per l'ordinamento sono name, type, status, created_at, schedule_start_date, schedule_end_date, client_name, clicks, views e shares.
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"}'{ "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 } } }}Entrambi gli SDK codificano automaticamente in JSON gli oggetti filters e sortFields, quindi passali come dizionari o oggetti nativi.
Errori che incontrerai
Elenco completo in Codici di errore.
Passaggi successivi
- Pubblicare post: la versione operativa di questa pagina, con una campagna programmata illustrata dall'inizio alla fine.
- Verificare lo stato delle schede e i link pubblici: verifica che una sede sia pubblicata su Google prima di pubblicarvi un post.
- Collegare Google e importare sedi: una sede deve avere un account collegato prima che qualsiasi sito accetti un post.
- Reagire agli eventi con i webhook: gli eventi
local_postsostituiscono il polling per ottenere gli esiti della pubblicazione. - Riferimento dei post per l'elenco completo dei campi di ciascun endpoint indicato sopra.