Lokasi
Semua endpoint lokasi sesuai urutan penggunaan dengan contoh cURL, Python, Node: daftar, cari, ambil via id/kode toko, buat, perbarui, arsipkan, foto.
Profil bisnis, ulasan, postingan, dan analitik semuanya menggunakan ID lokasi sebagai kunci. Resource Locations memiliki 13 endpoint: 4 endpoint baca untuk menemukan lokasi, 4 endpoint tulis untuk membuat, mengubah, dan mengarsipkan lokasi, serta 5 endpoint untuk mengelola foto. Kunci Read (baca) mencakup operasi baca. Setiap POST memerlukan kunci Write (tulis); penggunaan kunci Read untuk operasi tulis mengembalikan HTTP 400 dengan SY90016.
Setiap id dalam panduan ini adalah id Relay dalam format base64, misalnya TG9jYXRpb246MTgwMDI4OQ== (yang jika didekodekan menjadi Location:1800289). Kedua SDK juga menerima databaseId numerik dan mengodekannya untuk Anda.
Ringkasan endpoint
Daftar semua lokasi
GET /locations menelusuri semua lokasi dalam akun halaman demi halaman, dimulai dari yang terbaru. Endpoint ini menggunakan koneksi berbasis cursor: edges[].node memuat setiap record, dan pageInfo.endCursor menjadi nilai parameter after untuk halaman berikutnya. Gunakan endpoint ini untuk menyinkronkan seluruh akun ke sistem Anda sendiri.
Parameter
curl "https://listingsapi.com/api/v4/locations?first=50" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "allLocations": { "edges": [ { "cursor": "TG9jYXRpb246MTgwMDI4OQ==", "node": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "name": "Jenny Home", "storeId": null, "approved": "APPROVED", "archived": false, "archivalScheduledAt": null, "city": "Austin", "stateIso": "TX", "countryIso": "US", "subCategoryId": 1432, "planName": "Launch", "placeActionLinks": [], "discoveredPlaceActionLinks": [] } } ], "pageInfo": { "hasNextPage": false, "hasPreviousPage": false, "endCursor": "TG9jYXRpb246MTgwMDI4OQ==", "total": 1 } } }}Baca pageInfo.hasNextPage dan berhenti ketika nilainya false. Jumlah pada tingkat halaman adalah pageInfo.total. id pada node adalah pengenal yang diharapkan oleh semua endpoint lainnya.
Cari lokasi
GET /locations/search mencocokkan kata kunci dengan nama lokasi, alamat jalan, kota, dan id toko. Endpoint ini menggunakan koneksi berbasis cursor dengan struktur edges[].node dan pageInfo.endCursor yang sama seperti endpoint daftar. Gunakan endpoint ini untuk komponen pemilih yang menampilkan saran saat Anda mengetik, atau untuk memastikan toko sudah ada sebelum Anda membuatnya.
Parameter
Kedua SDK juga menerima daftar fields untuk membatasi pencocokan pada field tertentu, misalnya hanya name.
curl "https://listingsapi.com/api/v4/locations/search?query=Jenny&first=10" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "searchLocations": { "edges": [ { "cursor": "TG9jYXRpb246MTgwMDI4OQ==", "node": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "name": "Jenny Home", "storeId": null, "street": "600 Congress Ave, Suite 200", "city": "Austin", "approved": "APPROVED", "archived": false } } ], "pageInfo": { "endCursor": "TG9jYXRpb246MTgwMDI4OQ==", "hasNextPage": false, "hasPreviousPage": false, "total": 1 } } }}Array edges yang kosong berarti tidak ada yang cocok. Node memuat alamat lengkap, kategori, dan status approved, sehingga satu baris hasil tidak memerlukan pengambilan data kedua.
Dapatkan lokasi berdasarkan ID
GET /locations-by-ids mengembalikan record lengkap untuk sekumpulan ID base64 dalam satu panggilan, sehingga menggunakan lebih sedikit permintaan dibandingkan satu panggilan per lokasi. Lokasi aktif maupun yang diarsipkan dapat ditemukan. Hasilnya berupa array biasa, bukan connection. Gunakan untuk mengambil record lengkap berdasarkan ID dari payload webhook atau penyimpanan Anda sendiri.
Parameter
curl -G https://listingsapi.com/api/v4/locations-by-ids \--data-urlencode 'ids=["TG9jYXRpb246MTgwMDI4OQ==","TG9jYXRpb246MTgwMDI5MA=="]' \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "getLocationsByIds": [ { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "storeId": null, "name": "Jenny Home", "archived": false, "archivedAt": null, "city": "Austin", "stateIso": "TX", "countryIso": "US", "subCategoryId": 1432, "businessHours": [], "locationPhotos": [], "placeActionLinks": [], "discoveredPlaceActionLinks": [] } ] }}ID yang tidak ada dalam akun Anda diabaikan tanpa pemberitahuan dan tanpa menghasilkan error. Bandingkan jumlah yang dikembalikan dengan jumlah yang Anda kirim untuk mendeteksi ID yang sudah tidak berlaku.
Dapatkan lokasi berdasarkan kode toko
GET /locations-by-store-codes melakukan pencarian terbalik: kode toko Anda sendiri digunakan untuk menemukan record lengkap. Hasilnya berupa array biasa. Gunakan ketika POS atau daftar waralaba Anda menggunakan kode toko sebagai kunci lokasi dan Anda tidak pernah menyimpan ID kami.
Parameter
curl -G https://listingsapi.com/api/v4/locations-by-store-codes \--data-urlencode 'storeCodes=["ACME01","ACME02"]' \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "getLocationsByStoreCodes": [ { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "storeId": "ACME01", "name": "Jenny Home", "archived": false, "city": "Austin", "countryIso": "US", "planName": "Launch" } ] }}Cocokkan storeId dari setiap objek dengan daftar Anda. Kode yang tidak memiliki kecocokan tidak disertakan. Lokasi hanya memiliki kode toko jika storeId ditetapkan saat pembuatan atau pembaruan.
Buat lokasi
POST /locations membuat lokasi dan memasukkannya ke antrean pengiriman ke setiap platform publikasi dalam paket Anda, atau hanya ke enabledSiteIds jika Anda menyertakan field tersebut. Setiap field ditempatkan di dalam input. Ada 10 field wajib; sisanya opsional, dan field yang Anda abaikan akan ditampilkan sebagai kosong oleh platform publikasi.
Parameter
Ditambah field opsional yang tercantum di halaman referensi: kategori GCID Google, URL media sosial, koordinat, kontak pemilik, metode pembayaran, area layanan, dan lainnya.
curl -X POST https://listingsapi.com/api/v4/locations \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "name": "Acme Kitchen", "description": "Acme Kitchen is a family-owned neighborhood restaurant in downtown New York serving wood-fired pizza, hand-rolled pasta, and a short seasonal menu built around produce from nearby growers. Our dining room seats forty, takeout and delivery run until close, and the bar pours regional wine and beer on tap.", "storeId": "ACME01", "street": "123 Jump Street", "city": "New York", "stateIso": "NY", "postalCode": "10013", "countryIso": "US", "phone": "6443859313", "bizUrl": "https://acmekitchen.example.com", "subCategoryId": 1432, "businessHours": [ { "day": "MONDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "TUESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "WEDNESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "THURSDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "FRIDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "SATURDAY", "type": "OPEN", "slots": [{ "start": "10:00am", "end": "02:00pm" }] }, { "day": "SUNDAY", "type": "CLOSED", "slots": [] } ], "placeActionLinks": [ { "placeActionType": "FOOD_ORDERING", "uri": "https://order.acmekitchen.example.com", "isPreferred": true } ] }}'{ "data": { "createLocation": { "clientMutationId": null, "success": true, "errors": null, "location": { "id": "TG9jYXRpb246MTgwMDI5MA==", "databaseId": 1800290, "storeId": "ACME01", "name": "Acme Kitchen", "city": "New York", "countryIso": "US", "status": "PENDING", "placeActionLinks": [ { "placeActionType": "FOOD_ORDERING", "uri": "https://order.acmekitchen.example.com", "isPreferred": true, "name": null, "submissionStatus": null } ], "discoveredPlaceActionLinks": [] } } }}Simpan kedua ID: id base64 diperlukan untuk setiap penulisan selanjutnya, sedangkan databaseId adalah nomor yang Anda lihat di dasbor dan webhook. status awalnya bernilai PENDING dan berlanjut tanpa panggilan API tambahan. name dan submissionStatus dari tautan tindakan tempat tetap bernilai null hingga tautan tersebut disinkronkan ke Google. locations.add() di Python memvalidasi field wajib secara lokal dan memunculkan ValidationError sebelum panggilan jaringan apa pun; sedangkan locations.create(input) menerima dict camelCase mentah.
Memperbarui lokasi
POST /locations/update adalah pembaruan parsial: input.id adalah satu-satunya field wajib dan hanya field yang Anda kirim yang berubah. Panggilan yang sama dapat memperbaiki nomor telepon atau menulis ulang jadwal mingguan. locations.update() di Python dan updateLocation() di Node sama-sama menerima satu objek camelCase.
Parameter
Ditambah field opsional yang tercantum di halaman referensi.
curl -X POST https://listingsapi.com/api/v4/locations/update \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "phone": "5125550199", "bizUrl": "https://acmekitchen.example.com", "primaryGbpSiteCategoryId": "gcid:restaurant", "businessHours": [ { "day": "MONDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "TUESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "WEDNESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "THURSDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "FRIDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "SATURDAY", "type": "OPEN", "slots": [{ "start": "10:00am", "end": "02:00pm" }] }, { "day": "SUNDAY", "type": "CLOSED", "slots": [] } ] }}'{ "data": { "updateLocation": { "clientMutationId": null, "success": true, "errors": null, "location": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "name": "Jenny Home", "phone": "5125550199", "status": "APPROVED", "placeActionLinks": [ { "placeActionType": "FOOD_ORDERING", "uri": "https://order.example.com", "isPreferred": true, "name": null, "submissionStatus": null } ], "discoveredPlaceActionLinks": [] } } }}Respons mengembalikan lokasi yang telah diperbarui agar Anda dapat memastikan nilai baru telah diterapkan. Setiap pembaruan mengembalikan seluruh kumpulan placeActionLinks lokasi saat ini. Untuk mengubah URL tautan, kirim delete untuk tautan lama dan add untuk tautan baru dalam permintaan yang sama.
Mengarsipkan lokasi
POST /locations/archive menjadwalkan satu atau beberapa lokasi untuk diarsipkan. Pengarsipan tidak langsung dilakukan: setiap lokasi memasuki ARCHIVE_SCHEDULED, tetap aktif dan ditagih hingga siklus penagihan saat ini berakhir, lalu diarsipkan saat faktur berikutnya dibuat. Gunakan ini untuk menonaktifkan cabang yang sudah tutup secara sekaligus.
Parameter
curl -X POST https://listingsapi.com/api/v4/locations/archive \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationIds": ["TG9jYXRpb246MTgwMDI4OQ==", "TG9jYXRpb246MTgwMDI5MA=="] }}'{ "data": { "archiveLocations": { "clientMutationId": null, "bulkEditTaskId": null, "errors": null, "success": null, "result": [ { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "ARCHIVE_SCHEDULED", "success": true, "errors": null }, { "locationId": "TG9jYXRpb246MTgwMDI5MA==", "status": "ARCHIVE_SCHEDULED", "success": true, "errors": null } ] } }}success pada tingkat teratas bernilai null; baca success milik masing-masing entri result[] sebagai gantinya, sehingga satu ID yang bermasalah tidak menghalangi pemrosesan item lain dalam batch.
Selama pengarsipan dijadwalkan, archivalScheduledAt lokasi ditetapkan pada hasil daftar dan pencarian. Lokasi yang telah diarsipkan tidak dapat diperbarui hingga diaktifkan kembali.
Membatalkan pengarsipan terjadwal
POST /locations/cancel_archive mengembalikan lokasi dalam ARCHIVE_SCHEDULED ke ACTIVE, dan penagihan berlanjut. Ini hanya berfungsi selama siklus penagihan masih terbuka; setelah lokasi sepenuhnya diarsipkan, panggilan ini mengembalikan 404 untuk lokasi tersebut.
Parameter
curl -X POST https://listingsapi.com/api/v4/locations/cancel_archive \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="] } }'{ "data": { "cancelLocationsArchive": { "clientMutationId": null, "bulkEditTaskId": null, "errors": null, "success": null, "result": [ { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "ACTIVE", "success": true, "errors": null } ] } }}Setiap entri result[] mengonfirmasi bahwa lokasi telah kembali ke ACTIVE. Kedua SDK memerlukan dua argumen posisional tambahan, yaitu jenis pemilihan dan pengenal changedBy, yang dikirim bersama locationIds; body REST hanya memerlukan ID.
Mengunggah foto ke lokasi
POST /locations/photos melampirkan gambar melalui URL publik: Anda menyediakan gambar di hosting, lalu API mengambil dan menyimpannya. Sebuah lokasi menyimpan satu LOGO, satu COVER, dan foto ADDITIONAL dalam jumlah berapa pun. Mengunggah ulang logo atau sampul akan menggantikan yang sudah ada.
Parameter
curl -X POST https://listingsapi.com/api/v4/locations/photos \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "photos": [ { "photo": "https://cdn.example.com/jenny-home/logo.png", "type": "LOGO" }, { "photo": "https://cdn.example.com/jenny-home/storefront.jpg", "type": "ADDITIONAL" } ] }}'{ "data": { "addLocationPhotos": { "clientMutationId": null, "success": true, "request": {}, "photos": [ { "id": "TWVkaWFGaWxlOjU4Nzg5MzE=", "databaseId": 5878931, "type": "LOGO", "starred": false, "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/f47d62a6.png" }, { "id": "TWVkaWFGaWxlOjU4Nzg5MzI=", "databaseId": 5878932, "type": "ADDITIONAL", "starred": false, "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/ef4ffb12.jpg" } ], "errors": null } }}Simpan id setiap foto; endpoint untuk memberi tanda bintang dan menghapus foto menerimanya. Ini adalah format respons langsung untuk batch kecil. Batch besar dimasukkan ke antrean: photos dikembalikan kosong dan request.requestId ditetapkan, lalu Anda melakukan polling pada endpoint berikutnya menggunakan ID tersebut. Ambang batas ditentukan oleh konfigurasi sisi server, jadi tentukan cabang logika berdasarkan ada tidaknya request.requestId.
Periksa status unggahan foto massal
GET /locations/photos/requests/{requestId} memeriksa unggahan dalam antrean secara berkala hingga mencapai status akhir, lalu melaporkan hasil untuk setiap gambar. Gunakan untuk memperbarui bilah kemajuan dan menampilkan secara tepat file mana yang ditolak beserta alasannya.
Parameter
curl https://listingsapi.com/api/v4/locations/photos/requests/e6c2d9d9-9a18-4015-88cf-9a4e19a6f49a \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "getLocationPhotosUploadStatus": { "requestId": "e6c2d9d9-9a18-4015-88cf-9a4e19a6f49a", "status": "SUCCESS", "photos": [ { "mediaId": "TWVkaWFGaWxlOjkxODI3", "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "SUCCESS", "errorMessage": null }, { "mediaId": null, "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "ERROR", "errorMessage": "Image dimensions below the minimum 250x250." } ] } }}Status tugas hanya menyatakan bahwa pemrosesan telah selesai, bukan bahwa setiap gambar berhasil diunggah. Beri jeda beberapa detik di antara pemeriksaan; perulangan tanpa jeda di sini akan cepat memicu 429.
Dapatkan foto untuk suatu lokasi
GET /locations/{locationId}/photos mengembalikan semua file media pada suatu lokasi sebagai array biasa: logo, sampul, dan gambar tambahan, masing-masing dengan url publik, thumbnailUrl, kategori, flag starred, dan viewsCount sepanjang masa. Panggil sebelum mengunggah untuk melihat slot mana yang belum terisi, serta mengumpulkan id untuk pemanggilan pemberian bintang dan penghapusan.
Parameter
curl https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/photos \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "mediaFilesOfLocation": [ { "id": "TWVkaWFGaWxlOjU4Nzg5MzE=", "categoryName": "Logo", "categoryId": "4", "fileType": "image", "starred": false, "viewsCount": 0, "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/f47d62a6.jpg", "thumbnailUrl": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/thumbnail_f47d62a6.jpg" }, { "id": "TWVkaWFGaWxlOjU4Nzg5MzI=", "categoryName": "Additional", "categoryId": "12", "fileType": "image", "starred": true, "viewsCount": 143, "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/ef4ffb12.jpg", "thumbnailUrl": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/thumbnail_ef4ffb12.jpg" } ] }}categoryName bernilai Logo, Cover, atau Additional. Gunakan thumbnailUrl untuk tampilan kisi dan url untuk tampilan ukuran penuh. Lokasi tanpa media mengembalikan array kosong, bukan kesalahan.
Beri bintang pada foto lokasi
POST /locations/photos/star menandai foto tambahan agar diprioritaskan penempatannya pada platform publikasi yang mendukung gambar unggulan. Hanya foto ADDITIONAL yang dapat diberi bintang, maksimal 4 per lokasi. Penghapusan bintang bekerja dengan cara yang sama: flag starred dalam body menentukan tindakan yang dilakukan.
Parameter
curl -X POST https://listingsapi.com/api/v4/locations/photos/star \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "photoIds": ["TWVkaWFGaWxlOjU4Nzg5MzI="], "starred": true }}'{ "data": { "starUnstarLocationPhotos": { "success": true, "photos": [ { "id": "TWVkaWFGaWxlOjU4Nzg5MzI=", "databaseId": 5878932, "type": "ADDITIONAL", "starred": true } ], "error": null } }}Kunci respons adalah starUnstarLocationPhotos pada kedua path, dan berisi satu error, bukan array errors. Foto berbintang kelima menyebabkan seluruh pemanggilan gagal dengan SY15012; pemeriksaan menghitung foto yang sudah diberi bintang ditambah foto dalam permintaan ini.
Hapus foto dari suatu lokasi
POST /locations/photos/remove melepaskan kaitan foto tambahan berdasarkan id media. Gunakan untuk menyingkirkan gambar tampak depan toko yang sudah tidak relevan atau membatalkan impor massal yang keliru. Hanya foto ADDITIONAL yang dapat dihapus; ganti logo atau sampul dengan mengunggah gambar baru menggunakan type tersebut.
Parameter
curl -X POST https://listingsapi.com/api/v4/locations/photos/remove \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "photoIds": ["TWVkaWFGaWxlOjU4Nzg5MzI="] }}'{ "data": { "removeLocationPhotos": { "clientMutationId": null, "removedCount": 1, "errors": null } }}removedCount melaporkan jumlah file yang kaitannya benar-benar dilepas, sehingga 0 dengan errors: null berarti tidak satu pun id tersebut terkait dengan lokasi ini. Penghapusan melepaskan kaitan file; tindakan ini belum tentu menghapusnya secara permanen dari pustaka media Anda.
Kesalahan yang akan Anda temui
Operasi tulis juga dapat mengembalikan HTTP 200 dengan success: false dan perinciannya dalam data.<operation>.errors. Daftar lengkap tersedia di kode kesalahan.
Langkah berikutnya
- Tambahkan lokasi, Perbarui lokasi, Unggah foto lokasi, dan Temukan dan arsipkan lokasi: panduan tugas yang menggunakan endpoint ini.
- Cari negara dan kategori: nilai
countryIso,stateIso, dansubCategoryIdyang diperlukan untuk operasi pembuatan. - Tautan Tindakan Tempat: model lengkap untuk tombol tindakan Google saat pembuatan dan pembaruan.
- Lokasi: halaman utama sumber daya serta referensi SDK untuk Python dan Node.
- Metode foto memiliki halaman SDK tersendiri: Foto Python dan Foto Node.