Avis
Endpoints avis : exemples cURL, Python et Node ; sources, paramètres, liste, agrégation, détails, réponse, édition, archivage, expressions et analyses.
Les avis sont les notes en étoiles et les commentaires que les clients laissent sur Google, Facebook et Yelp. L’API en stocke une copie, vous permet d’y répondre et calcule des statistiques sur les avis. Les chemins REST utilisent reviews ; les clés de réponse et les titres des pages de référence utilisent interactions, l’ancien nom interne du même objet. Ce guide utilise le terme avis partout. Les opérations de lecture nécessitent une clé Read (lecture). Les réponses, les modifications, l’archivage et les changements de paramètres nécessitent une clé Write (écriture) ; une opération d’écriture effectuée avec une clé Read renvoie 400 avec SY90016.
Vue d’ensemble des endpoints
Lister les sources d’avis autorisées par votre offre
GET /reviews/site-config renvoie le catalogue des plateformes d’avis auxquelles le compte a droit. Cet endpoint ne prend aucun paramètre et s’applique à l’ensemble du compte ; mettez donc son résultat en cache plutôt que de l’appeler pour chaque établissement. Les valeurs de siteUrl sont les noms d’hôte acceptés par tous les autres filtres de cette ressource.
curl https://listingsapi.com/api/v4/reviews/site-config \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "interactionSiteConfig": [ { "site": "Google", "siteUrl": "maps.google.com" }, { "site": "Facebook", "siteUrl": "facebook.com" }, { "site": "Yelp", "siteUrl": "yelp.com" } ] }}Consultez data.interactionSiteConfig[]. L’exemple correspond à un compte avec l’offre Launch ; l’ensemble exact dépend de l’offre et du secteur d’activité. Utilisez siteUrl pour le filtre siteUrls des endpoints de liste et pour siteUrls[].name lors de la modification des paramètres.
Lister les sources configurées pour un établissement
GET /locations/{locationId}/reviews/settings renvoie une entrée par plateforme prise en charge par l’offre, avec l’URL depuis laquelle les avis sont récupérés. Cet endpoint est le pendant en lecture de l’endpoint de modification ci-dessous. Le chemin accepte l’identifiant encodé en base64 ou le nombre brut.
curl https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/reviews/settings \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "interactionsSetting": { "siteSettings": [ { "name": "maps.google.com", "url": null }, { "name": "facebook.com", "url": null }, { "name": "yelp.com", "url": null } ] } }}Consultez data.interactionsSetting.siteSettings[]. Une valeur non nulle de url signifie que la plateforme est connectée et que les avis sont récupérés depuis cette page. Une valeur null pour url signifie que la plateforme est disponible, mais non configurée. Les entrées Google et Facebook se remplissent automatiquement lorsque vous connectez ces comptes via OAuth et ne peuvent pas être remplacées par l’endpoint de modification. Yelp doit être indiqué explicitement.
Modifier les paramètres des avis d’un établissement
POST /locations/reviews/settings/edit définit les sources sur lesquelles les avis d’un établissement sont suivis et la note en étoiles à partir de laquelle un avis est considéré comme positif. Les champs sont placés directement dans le corps de la requête, et non dans un objet englobant input. L’ajout d’une source met une extraction en file d’attente ; les avis du nouveau site arrivent donc plus tard, et non dans cette réponse.
curl -X POST https://listingsapi.com/api/v4/locations/reviews/settings/edit \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "positiveInteractionThreshold": 4, "siteUrls": [ { "name": "maps.google.com", "url": null }, { "name": "yelp.com", "url": "https://www.yelp.com/biz/blue-bottle-coffee-oakland" } ]}'{ "data": { "editInteractionsSetting": { "errors": null, "interactionSetting": { "locationId": "1800289", "positiveInteractionThreshold": 4, "siteSettings": [ { "name": "maps.google.com", "url": null, "monitored": true, "canRespond": true }, { "name": "yelp.com", "url": "https://www.yelp.com/biz/blue-bottle-coffee-oakland", "monitored": true, "canRespond": false } ] } } }}Consultez data.editInteractionsSetting.interactionSetting.siteSettings[] pour connaître la sélection enregistrée. monitored indique que la source est active ; canRespond indique si des réponses du propriétaire peuvent y être publiées via l’API. Une source rejetée lors de la validation, par exemple à cause d’une URL inaccessible ou d’un site non inclus dans l’offre, est renvoyée dans errors sans modification du paramètre ; vérifiez donc errors lorsque vous recevez 200. Les SDK lèvent ValidationError dans ce cas.
Lister les avis d'un établissement
GET /locations/{locationId}/reviews est une connexion à curseur accessible à data.interactions, avec les avis les plus récents en premier. first vaut 20 par défaut ; un seul appel ne renvoie donc jamais l'historique complet. Les filtres sous forme de tableaux sont des chaînes JSON dans la chaîne de requête et doivent être encodés pour les URL ; l'exemple cURL utilise -G avec --data-urlencode à cet effet.
S'ajoutent les paramètres facultatifs category, categories et ratingFilter, ce dernier n'acceptant qu'une seule valeur, répertoriés sur la page de référence.
curl -G "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/reviews" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'ratingFilters=[1,2]' \--data-urlencode 'responseStatus=["PENDING"]' \--data-urlencode 'sortOrder=["NEWEST_FIRST"]' \--data-urlencode 'first=25'{ "data": { "interactions": { "pageInfo": { "hasNextPage": true, "endCursor": "SW50ZXJhY3Rpb246MV8xNTU0..." }, "edges": [ { "node": { "id": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841", "source": "maps.google.com", "content": "nice place for family together", "authorName": "vaibhav nakate", "rating": 5, "date": "2019-04-02T22:11:13.036997+00:00", "type": "Review", "responded": false, "responseCount": 0, "canRespond": true, "permalink": "https://maps.google.com/maps?cid=..." }, "cursor": "SW50ZXJhY3Rpb246MV8xNTU0..." } ], "totalCount": 425 } }}Lisez edges[].node. Vous transmettez id lorsque vous répondez, et canRespond indique si cette source accepte les réponses du propriétaire. totalCount correspond au nombre de correspondances dans l'ensemble des résultats, et non sur cette page. Arrêtez la pagination lorsque hasNextPage vaut false ou qu'une page renvoie un edges vide ; lorsqu'une limite de page tombe sur l'avis le plus ancien, une page vide suit.
Parcourir tous les établissements avec la vue agrégée
GET /rollup_interactions est la même connexion à curseur, accessible à data.rollupInteractions, couvrant tous les établissements auxquels la clé donne accès, avec un locationId numérique sur chaque nœud. Elle accepte les mêmes filtres que la liste par établissement. Il n'existe aucun filtre par établissement ; un argument locationIds est ignoré, et non rejeté. Aucun des deux SDK ne prend encore en charge ce point de terminaison ; les exemples utilisent donc requests et fetch.
curl -G "https://listingsapi.com/api/v4/rollup_interactions" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'responseStatus=["PENDING"]' \--data-urlencode 'sortOrder=["NEWEST_FIRST"]' \--data-urlencode 'first=50'{ "data": { "rollupInteractions": { "pageInfo": { "hasNextPage": true, "hasPreviousPage": false }, "edges": [ { "node": { "id": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841", "source": "maps.google.com", "content": "Excellent service, highly recommend.", "rating": 5, "responded": false, "canRespond": true, "locationId": 1800289 }, "cursor": "SW50ZXJhY3Rpb246OWUyNmQyYTg=" } ], "totalCount": 1284 } }}Regroupez les nœuds par locationId, le databaseId du magasin. Le pageInfo de la vue agrégée peut omettre endCursor ; utilisez donc le cursor de la dernière arête comme valeur de after ; les deux valeurs sont équivalentes. Délimitez les exécutions planifiées avec startDate et endDate plutôt que de relire l'historique, et respectez Retry-After lors d'un 429.
Récupérer les avis par identifiant
GET /reviewDetails renvoie des copies à jour des avis stockés, sans pagination. La réponse est un simple tableau à data.interactionDetails.interactions, sans edges ni pageInfo, et chaque avis inclut son responses. Utilisez ce point de terminaison pour réhydrater une liste de suivi et trouver le responseId nécessaire à la modification ou à l'archivage.
curl -G "https://listingsapi.com/api/v4/reviewDetails" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'interactionIds=["b2fa765e-c62b-4e0b-b1d6-1c67c855f5e0"]'{ "data": { "interactionDetails": { "interactions": [ { "id": "b2fa765e-c62b-4e0b-b1d6-1c67c855f5e0", "source": "maps.google.com", "content": "Great place for dessert!", "rating": 5, "responded": true, "responseCount": 1, "canRespond": true, "responses": [ { "id": "2090753a-ece6-4837-8336-8494ad308523", "content": "Thank you so much for the kind words!", "interactionStatus": "CONFIRMED", "editedResponse": false } ] } ] } }}responses[].id est le responseId pour les points de terminaison de modification et d'archivage. Une requête utilisant un identifiant d'un autre compte renvoie 200 avec interactionDetails: null et une erreur SY90001 ; vérifiez donc la présence de null avant d'accéder à un élément par son indice.
Champs des avis et des réponses
La référence des attributs est une page purement documentaire qui répertorie tous les champs de l'objet avis et de l'objet réponse. Les champs que vous utiliserez le plus :
Chaque réponse dans responses[] contient id, content, authorName, date, interactionStatus, editedResponse, respondedWith (identifiant du modèle) et remarks (détail de l'échec). interactionStatus passe par les états suivants :
Publier une réponse du propriétaire
POST /locations/reviews/respond publie une réponse publique sur la plateforme source. Les champs sont placés directement dans le corps de la requête. La réponse est acceptée immédiatement et transmise de manière asynchrone, donc interactionStatus commence à CREATED. Vérifiez d'abord canRespond sur l'avis.
curl -X POST https://listingsapi.com/api/v4/locations/reviews/respond \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "interactionId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841", "responseContent": "Thank you for visiting Jenny Home: we are glad you enjoyed your experience!"}'{ "data": { "respondToInteraction": { "interaction": { "id": "2090753a-ece6-4837-8336-8494ad308523", "interactionId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841", "content": "Thank you for visiting Jenny Home: we are glad you enjoyed your experience!", "interactionStatus": "CREATED", "editedResponse": false }, "errors": null } }}Conservez interaction.id : il s'agit du responseId utilisé pour la modification et l'archivage. Une réponse rejetée est renvoyée sous la forme 200 avec errors renseigné dans data.respondToInteraction, donc lisez le corps ; les SDK lèvent ValidationError. Récupérez à nouveau l'avis par son identifiant après une courte attente pour vérifier que la réponse atteint COMPLETED ou CONFIRMED.
Modifier une réponse
POST /locations/reviews/respond/edit modifie le texte d'une réponse existante. La modification est soumise à nouveau à la plateforme, donc interactionStatus revient à CREATED et editedResponse devient true une fois la modification appliquée. Privilégiez cette opération plutôt que l'archivage suivi d'une nouvelle publication sur les plateformes qui autorisent une seule réponse.
curl -X POST https://listingsapi.com/api/v4/locations/reviews/respond/edit \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "reviewId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841", "responseId": "2090753a-ece6-4837-8336-8494ad308523", "responseContent": "Thank you again: we have updated our reply to include our new store hours."}'{ "data": { "editResponse": { "status": "true", "reviewId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841", "responseId": "2090753a-ece6-4837-8336-8494ad308523" } }}status est la chaîne "true" lorsque la modification est acceptée. Confirmez le nouveau texte avec un appel de récupération des détails et vérifiez le interactionStatus de la réponse.
Archiver une réponse
POST /locations/reviews/respond/archive retire une réponse du responses de l'avis suivi de notre côté. Il s'agit d'une suppression logique : une réponse déjà publiée sur Google, Yelp ou Facebook y reste. Utilisez cette opération pour supprimer un brouillon dont la publication a échoué ou qui a été remplacé ; utilisez la modification pour toute réponse publiée.
curl -X POST https://listingsapi.com/api/v4/locations/reviews/respond/archive \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "responseId": "2090753a-ece6-4837-8336-8494ad308523" }'{ "data": { "archiveResponse": { "status": "true" } }}Après l'archivage, le responseCount de l'avis diminue et responded reflète les réponses restantes.
Lister les expressions que les clients répètent
GET /review-phrases renvoie un simple tableau dans data.newReviewPhrases, avec une entrée par expression récurrente, chacune accompagnée de statistiques calculées uniquement sur les avis qui la contiennent. Il n'est pas paginé ; limitez sa taille avec phraseCount. Tous les filtres sont facultatifs et se combinent, donc ratingFilters=[1,2] avec un startDate donne les plaintes du trimestre dernier.
Ainsi que le paramètre facultatif categories et les paramètres obsolètes à valeur unique category et ratingFilter répertoriés sur la page de référence.
curl -G "https://listingsapi.com/api/v4/review-phrases" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'locationIds=[1800289]' \--data-urlencode 'ratingFilters=[1,2]' \--data-urlencode 'startDate=2026-06-01' \--data-urlencode 'endDate=2026-08-31' \--data-urlencode 'phraseCount=10'{ "data": { "newReviewPhrases": [ { "reviewPhrase": "friendly staff", "phraseStats": { "stats": [ { "name": "total-reviews", "value": 46, "delta": 12.5, "abs": 5 }, { "name": "overall-rating", "value": 4.7, "delta": 1.1, "abs": 0.05 } ] } }, { "reviewPhrase": "long wait", "phraseStats": { "stats": [ { "name": "total-reviews", "value": 11, "delta": 37.5, "abs": 3 }, { "name": "overall-rating", "value": 2.9, "delta": -8.4, "abs": -0.27 } ] } } ] }}total-reviews indique la fréquence d'apparition de l'expression, overall-rating est la note moyenne de ces avis, delta est la variation en pourcentage par rapport à la période précédente et abs est la variation absolue. Un 403 avec SY90003 signifie que la clé ne donne pas accès en lecture à l'un des établissements demandés.
Consulter les indicateurs clés des avis d'un établissement
GET /locations/{locationId}/review-analytics-overview renvoie 4 statistiques dans data.interactionsAnalyticsStats.stats. La plage de dates est facultative ; elle restreint la période sur laquelle les valeurs et leurs variations sont calculées. Chaque delta représente la variation en pourcentage par rapport à la période précédente de même durée.
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-overview?startDate=2026-08-01&endDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "interactionsAnalyticsStats": { "stats": [ { "name": "total-reviews", "value": 128, "delta": 6.67 }, { "name": "new-reviews", "value": 9, "delta": -25 }, { "name": "overall-rating", "value": 4.43, "delta": 2.31 }, { "name": "review-response-rate", "value": 62.5, "delta": 12.5 } ] } }}Un nouveau compte sans période antérieure affiche un delta de 100, donc n'interprétez pas les variations du premier mois comme une croissance.
Récupérer la chronologie quotidienne des avis
GET /locations/{locationId}/review-analytics-timeline renvoie une entrée par jour dans data.interactionsChartData.data. Fournissez startDate et endDate chaque fois que la période du graphique importe ; si vous les omettez, le service choisit sa propre période. Ajoutez site pour représenter une seule source.
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-timeline?startDate=2026-08-01&endDate=2026-08-31&site=maps.google.com" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "interactionsChartData": { "data": [ { "date": "2026-08-01", "interactionCount": 4, "averageRating": 4.5 }, { "date": "2026-08-02", "interactionCount": 0, "averageRating": null }, { "date": "2026-08-03", "interactionCount": 7, "averageRating": 4.285714285714286 } ] } }}Représentez interactionCount par des barres et averageRating par une courbe. La moyenne porte uniquement sur le jour concerné, ce n'est pas une moyenne cumulative, et elle vaut null les jours sans avis ; laissez donc un espace vide plutôt que de représenter un zéro.
Ventiler les analyses des avis par source
GET /locations/{locationId}/review-analytics-sites-stats renvoie une entrée par source d'avis dans data.interactionsSitesStats.stats. Utilisez-le pour déterminer quelle plateforme a fait évoluer la moyenne.
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-sites-stats?startDate=2026-08-01&endDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "interactionsSitesStats": { "stats": [ { "key": "google", "siteUrl": "maps.google.com", "averageRating": { "value": 4.6, "delta": 2.2 }, "totalInteractions": { "value": 412, "delta": 6.1 }, "newInteractions": { "value": 24, "delta": 33.3 }, "recency": "2026-09-06T14:12:00Z", "baseRating": 4.5, "baseInteractions": 388, "humanizedRecency": "3 days ago" }, { "key": "facebook", "siteUrl": "facebook.com", "averageRating": { "value": 4.1, "delta": -1.4 }, "newInteractions": { "value": 0, "delta": -100 }, "recency": null, "humanizedRecency": null } ] } }}averageRating, totalInteractions et newInteractions contiennent chacun un value et un delta ; baseRating et baseInteractions sont les valeurs au début de la période à partir de laquelle l'écart est mesuré. recency correspond à l'horodatage de l'avis le plus récent et vaut null lorsque la source n'en a jamais renvoyé. Un newInteractions de 0 avec un recency datant de plusieurs mois signifie généralement que la connexion à la source est devenue inactive ; vérifiez donc les sources de l'établissement.
Erreurs que vous rencontrerez
Les opérations d'écriture peuvent également renvoyer 200 avec errors renseigné dans data.<op> ; lisez donc le corps de la réponse de chaque opération d'écriture. La liste complète figure dans Codes d'erreur.
Étapes suivantes
- Récupérer les avis : créez une file d'attente des avis à traiter et recevez des notifications par webhook.
- Répondre aux avis : répondez, confirmez, modifiez, archivez.
- Analyses des avis : tableau de synthèse, graphique, panneau des réclamations, instantanés quotidiens.
- Analyses : métriques des profils Google, Facebook et Bing du même établissement.
- Page d'accueil de la référence : Avis. SDK : Avis Python, Avis Node.