Google ve Facebook'ta gönderi yayımlayın
Duyuru, etkinlik ve teklif yayımlayın; çok konumlu gönderi planlayın, her sitede yayını doğrulayın, konum gönderilerini yönetin ve webhook'ları yanıtlayın.
Gönderi, bir konumun Google Business Profile veya Facebook Sayfasında yer alan tarihli bir karttır: duyuru, etkinlik veya teklif olabilir. Bir çağrı gönderiyi oluşturur, yayımlama arka planda yürütülür ve ikinci bir çağrı her sitenin gönderiyi kabul edip etmediğini bildirir.
Üç gönderi türü de gövde input içine sarılmış olarak POST /posts kullanır. Sarmalanmamış bir gövde 400 ile reddedilir. SDK'lar sarmalayıcıyı oluşturur ve göndermeden önce veri yükünü doğrular.
1. Bir duyuru yayımlayın
Bir duyuru bir mesaj, isteğe bağlı bir düğme ve isteğe bağlı bir görsel alır.
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://acmekitchen.example.com/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] } } }}socialPost.id değerini saklayın. status başlangıçta INPROGRESS değerindedir ve bir site gönderiyi kabul edene kadar postLinks boş kalır; 5. adımda her ikisi de geri okunur.
2. Bir etkinlik yayımlayın
Bir etkinlik, title, startDay, endDay ve isteğe bağlı görüntüleme saatlerini içeren postContextInfo ekler. Google, başlığı olmayan bir etkinliği reddeder ve başlık eksikse SDK'lar göndermeden önce ValidationError hatası üretir.
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, giveaways, and up to 40% off in store." } ] }}'Yanıt, 1. adımdakiyle aynı yapıdadır; type: "EVENT" içerir ve tarihler socialPost.contextInfo altında döndürülür. postContextInfo etkinliğin kendi tarihlerini tutar; postScheduledDates (4. adım), gönderinin ne zaman yayımlanacağını ve yayından kaldırılacağını belirler.
3. Bir teklif yayımlayın
Bir teklifin postContextInfo alanı title, couponCode, discount, redeemUrl, termsConditions ve geçerlilik aralığını belirleyen startDay ile endDay alanlarını taşır. Bunu Facebook'ta bir GET_OFFER düğmesiyle veya Google'da ORDER düğmesiyle eşleştirin; REDEEM türü yoktur.
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "postName": "Summer 25% Off", "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="], "postType": "OFFER", "postSites": ["GOOGLE"], "postContextInfo": { "title": "25% off storewide", "couponCode": "SUMMER25", "discount": "25%", "redeemUrl": "https://acmekitchen.example.com/summer", "termsConditions": "Valid in store only through July 6. Cannot be combined with other offers.", "startDay": "2026-06-22", "endDay": "2026-07-06" }, "postMessage": [ { "site": "GOOGLE", "message": "Celebrate with us: 25% off everything in store this week." } ] }}'Yanıt, teklif alanlarını socialPost.contextInfo altında döndürür ve scheduledStartDate ile scheduledEndDate değerlerini geçerlilik aralığına göre ayarlar.
4. Tek bir gönderiyi zamanlayarak birden çok konuma gönderin
POST /bulk-posts aynı input değerini alır ve tek bir kampanyayı locationIds içindeki her id değerine gönderir. Daha sonra yayımlamak ve otomatik olarak yayından kaldırmak için ISO-8601 biçimindeki startDatetime ve endDatetime değerlerini içeren postScheduledDates ekleyin; gönderi bu durumda SCHEDULED olarak oluşturulur. Üslup farklı olduğunda her site için ayrı bir mesaj yazın.
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" } }}'Toplu işlem uç noktası POST /posts ile aynı yapıyı döndürür; bu nedenle yanıtın anahtarı da createSocialPost olur ve yanıt status: "SCHEDULED" ile locationIds içinde her iki id değerini içerir. Bir doğrulama sorunu oluştuğunda success: false ve içi doldurulmuş bir errors dizisiyle birlikte 200 döndürülür; SDK'lar bunun için ValidationError hatası üretir. Toplu kampanyayı, konum başına durum bilgisi ekleyen GET /bulk-posts/{postId} ile geri okuyun.
5. Yayımlama durumunu kontrol edin ve gönderi bağlantılarını toplayın
GET /posts/{postId}, kampanyayı socialPostView altında döndürür. Oluşturma işleminden sonra socialPostInfo.status, INPROGRESS durumundan çıkana kadar düzenli aralıklarla sorgulayın; ardından her sitenin sonucu için publishDetails[] ve yayındaki URL'ler için postLinks[] alanını okuyun. Sorgulamalar arasında onlarca saniye bırakın; 429 ile birlikte Retry-After gelir.
curl https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "socialPostView": { "socialPostInfo": { "id": "U29jaWFsUG9zdDo0NDEyMg==", "status": "SUCCESS", "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" } ] }, "socialPostAnalyticsBySite": [ { "site": "GOOGLE", "views": 128, "clicks": 14, "reactions": 3, "shares": 0, "comments": 1 } ] } }}views, clicks, reactions, shares ve comments aynı kayıtta birikir ve socialPostAnalyticsBySite içinde site bazında ayrılır. SDK'lar doğrudan socialPostInfo döndürür; bu nedenle örnekler post.status alanını okur.
6. Bir konumun gönderilerini listeleyin ve birini silin
GET /locations/{locationId}/posts, konumu içeren tüm kampanyaların postsByLocation altında records[] ve pageInfo.totalRecords ile sunulduğu, ofset tabanlı bir sayfadır (page, en fazla 50 olacak şekilde perPage). base64 id değerini değiştirmeden iletin; URL kodlaması uygulamayın. Tür filtresi yoktur; bu nedenle teklifleri veya etkinlikleri kendi kodunuzda type içinden seçin. 4. adımdaki çok konumlu kampanyalar GET /locations/{locationId}/bulk-posts tarafından ayrı olarak listelenir.
DELETE /posts/{postId}, kampanyayı buradan kaldırır ve ulaştığı tüm sitelerden yayından kaldırır. Geri alma olanağı yoktur; bu nedenle önce listedeki id değerini doğrulayın.
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/posts?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY" curl -X DELETE https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"Silme işlemi, success: true ve kaldırdığı socialPostId ile birlikte data.deleteSocialPost yanıtını döndürür. Zaten silinmiş bir id değerini silmek ise data: null içeren bir errors yanıtı döndürür; böylece ikinci bir silme işlemi kolayca tespit edilebilir.
7. Gönderi webhook'larına tepki verin
/dashboard/webhooks üzerinde bir webhook URL'si ayarlandığında, tamamı standart veri yükünde yer alan dört olay gönderinin yaşam döngüsünü kapsar. Bu olaylar kampanya başına değil, konum başına tetiklenir: 20 konuma yapılan toplu gönderi, ortak bir post_id ile 20 post_item_id değeri üretir.
function handle(payload: { event: string; location_id: string; data: Record<string, unknown> }) {if (!payload.event.startsWith('local_post.')) return; const key = String(payload.data.post_item_id); // one row per locationswitch (payload.event) { case 'local_post.published': markLive(key, payload.location_id, payload.data.post_external_id); break; case 'local_post.rejected': markRejected(key, payload.location_id, payload.data.rejection_reason); break; case 'local_post.deleted': markDeleted(key); break;}}published_url genellikle bulunmaz; bu nedenle tıklanabilir bir bağlantıya ihtiyacınız varsa postLinks için 5. adımdaki sorgulamayı tekrarlamaya devam edin. 5 saniye içinde 200 yanıtını döndürün; yeniden deneme yapılmaz. Alıcı ve imza denetimi Webhook'larla olaylara tepki verin bölümündedir.
Sonraki adımlar
- Google'ı bağlayın ve konumları içe aktarın ve Facebook Sayfalarını bağlayın: her site için ön koşul.
- Profil analizlerini alın: buradaki gönderi başına sayaçların yanı sıra profil düzeyindeki görüntülemeler ve işlemler.
- Webhook'larla olaylara tepki verin: bu olayların ulaştığı alıcı.
- Referans: Duyuru gönderisi oluşturun, Etkinlik gönderisi oluşturun, Teklif gönderisi oluşturun, Toplu gönderi oluşturun, Bir gönderiyi alın, Bir konumun gönderilerini alın, Bir gönderiyi silin.