Reseñas
Cada endpoint de reseñas con ejemplos cURL, Python y Node: fuentes, ajustes, lista, resumen, detalles, responder, editar, archivar, frases y analítica.
Las reseñas son las valoraciones con estrellas y los comentarios que los clientes dejan en Google, Facebook y Yelp. La API almacena una copia de cada reseña, te permite responder y calcula analíticas de reseñas. Las rutas REST usan reviews; las claves de respuesta y los títulos de las páginas de referencia usan interactions, el antiguo nombre interno del mismo objeto. Esta guía usa el término reseña en todo momento. Las operaciones de lectura necesitan una clave Read (lectura). Responder, editar, archivar y cambiar la configuración requieren una clave Write (escritura); usar una clave Read en una operación de escritura devuelve 400 con SY90016.
Resumen de endpoints
Lista las fuentes de reseñas que permite tu plan
GET /reviews/site-config devuelve el catálogo de plataformas de reseñas al que tiene acceso la cuenta. No acepta parámetros y su alcance es la cuenta, así que almacena el resultado en caché en lugar de llamarlo para cada ubicación. Los valores de siteUrl son los nombres de host que acepta cualquier otro filtro de este recurso.
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" } ] }}Lee data.interactionSiteConfig[]. El ejemplo corresponde a una cuenta con el plan Launch; el conjunto exacto depende del plan y del sector. Usa siteUrl para el filtro siteUrls en los endpoints de listado y para siteUrls[].name al editar la configuración.
Lista las fuentes configuradas para una ubicación
GET /locations/{locationId}/reviews/settings devuelve una entrada por cada plataforma admitida por el plan, con la URL de la que se obtienen las reseñas. Es la contraparte de lectura del endpoint de edición que aparece a continuación. La ruta acepta el id en base64 o el número sin codificar.
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 } ] } }}Lee data.interactionsSetting.siteSettings[]. Un valor de url distinto de null significa que la plataforma está conectada y que se están obteniendo reseñas de esa página. Un valor null en url significa que la plataforma está disponible pero no está configurada. Google y Facebook se rellenan automáticamente cuando conectas esas cuentas mediante OAuth y no se pueden sobrescribir mediante el endpoint de edición. Yelp debe especificarse explícitamente.
Edita la configuración de reseñas de una ubicación
POST /locations/reviews/settings/edit establece en qué fuentes se supervisa una ubicación y la valoración con estrellas que se considera positiva. Los campos van directamente en el cuerpo, no dentro de un contenedor input. Añadir una fuente pone en cola una extracción de datos, por lo que las reseñas del nuevo sitio llegan más tarde, no en esta respuesta.
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 } ] } } }}Lee data.editInteractionsSetting.interactionSetting.siteSettings[] para consultar la selección almacenada. monitored indica que la fuente está activa; canRespond indica si se pueden publicar respuestas del propietario allí mediante la API. Una fuente rechazada por la validación, como una URL inaccesible o un sitio no incluido en el plan, se devuelve en errors sin cambios en la configuración, así que comprueba errors cuando recibas un 200. Los SDK lanzan ValidationError en ese caso.
Listar las reseñas de una ubicación
GET /locations/{locationId}/reviews es una conexión con cursores en data.interactions, ordenada de más reciente a más antigua. first tiene un valor predeterminado de 20, por lo que una sola llamada nunca devuelve el historial completo. Los filtros de tipo array son cadenas JSON en la cadena de consulta y deben codificarse para URL; el ejemplo de cURL usa -G con --data-urlencode para ello.
Además de los parámetros opcionales category, categories y ratingFilter, este último de un solo valor, que se indican en la página de referencia.
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 } }}Lee edges[].node. id es lo que pasas al responder, y canRespond indica si esa fuente acepta respuestas del propietario. totalCount es el número de coincidencias en todo el conjunto de resultados, no en esta página. Deja de paginar cuando hasNextPage sea false o una página devuelva edges vacío; si un límite coincide con la reseña más antigua, le sigue una página vacía.
Recorrer todas las ubicaciones con el agregado
GET /rollup_interactions es la misma conexión con cursores para todas las ubicaciones a las que la clave tiene acceso, en data.rollupInteractions, con un locationId numérico en cada nodo. Acepta los mismos filtros que la lista por ubicación. No hay ningún filtro de ubicación; un argumento locationIds se ignora, no se rechaza. Ninguno de los 2 SDK ofrece todavía un método para este endpoint, así que los ejemplos usan requests y 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 } }}Agrupa los nodos por locationId, el databaseId del establecimiento. El pageInfo del agregado puede omitir endCursor, así que usa el cursor del último elemento edge como after; los 2 valores son equivalentes. Limita las ejecuciones programadas con startDate y endDate en lugar de volver a leer el historial, y respeta Retry-After cuando recibas un 429.
Obtener reseñas por id
GET /reviewDetails devuelve copias actualizadas de las reseñas almacenadas sin paginación. La respuesta es un array simple en data.interactionDetails.interactions, sin edges ni pageInfo, y cada reseña incluye su responses. Úsalo para volver a cargar los datos de una lista de seguimiento y para encontrar el responseId que necesitas para editar o archivar.
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 es el responseId para los endpoints de edición y archivado. Si pasas un id de otra cuenta, el endpoint devuelve 200 con interactionDetails: null y un error SY90001, así que comprueba si hay null antes de acceder por índice.
Campos de reseñas y respuestas
La referencia de atributos es una página exclusivamente de documentación que enumera todos los campos de los objetos de reseña y de respuesta. Los campos que más usarás:
Cada respuesta en responses[] incluye id, content, authorName, date, interactionStatus, editedResponse, respondedWith (id de la plantilla) y remarks (detalle del fallo). interactionStatus pasa por estos estados:
Publicar una respuesta del propietario
POST /locations/reviews/respond publica una respuesta pública en la plataforma de origen. Los campos van directamente en el cuerpo. La respuesta se acepta de inmediato y se entrega de forma asíncrona, por lo que interactionStatus comienza en CREATED. Comprueba primero canRespond en la reseña.
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 } }}Conserva interaction.id: es el responseId para editar y archivar. Una respuesta rechazada se devuelve como 200 con errors rellenado dentro de data.respondToInteraction, así que lee el cuerpo; los SDK lanzan ValidationError. Vuelve a leer la reseña por su id tras una breve espera para ver si la respuesta alcanza COMPLETED o CONFIRMED.
Editar una respuesta
POST /locations/reviews/respond/edit cambia el texto de una respuesta existente. La edición se vuelve a enviar a la plataforma, por lo que interactionStatus vuelve a CREATED y editedResponse pasa a ser true una vez que se aplica. Da preferencia a esta opción frente a archivar y volver a publicar en las plataformas que permiten una sola respuesta.
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 es la cadena "true" cuando se acepta la edición. Confirma el nuevo texto con una llamada de consulta de detalles y comprueba el interactionStatus de la respuesta.
Archivar una respuesta
POST /locations/reviews/respond/archive elimina una respuesta del responses de la reseña que mantenemos en nuestro sistema. Es una eliminación lógica: una respuesta que ya esté publicada en Google, Yelp o Facebook permanece allí. Úsalo para eliminar un borrador que haya fallado o se haya sustituido; usa la edición para cualquier respuesta publicada.
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" } }}Tras archivar, el responseCount de la reseña disminuye y responded refleja las respuestas restantes.
Listar las frases que repiten los clientes
GET /review-phrases devuelve un array simple en data.newReviewPhrases, con una entrada por frase recurrente y estadísticas calculadas únicamente sobre las reseñas que la contienen. No está paginado; limítalo con phraseCount. Todos los filtros son opcionales y se pueden combinar, por lo que ratingFilters=[1,2] con un startDate devuelve las quejas del último trimestre.
Además del parámetro opcional categories y los parámetros obsoletos de un solo valor category y ratingFilter que figuran en la página de referencia.
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 es la frecuencia con la que aparece la frase, overall-rating es la valoración media de esas reseñas, delta es la variación porcentual respecto al período anterior y abs es la variación absoluta. Un 403 con SY90003 significa que la clave no puede leer una de las ubicaciones solicitadas.
Consultar los KPI de reseñas de una ubicación
GET /locations/{locationId}/review-analytics-overview devuelve cuatro estadísticas en data.interactionsAnalyticsStats.stats. El intervalo de fechas es opcional; acota el período sobre el que se calculan los valores y sus variaciones. Cada delta es la variación porcentual respecto al período anterior de la misma duración.
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 } ] } }}Una cuenta nueva sin período anterior muestra un delta de 100, así que no interpretes las variaciones del primer mes como crecimiento.
Obtén la cronología diaria de reseñas
GET /locations/{locationId}/review-analytics-timeline devuelve una entrada por día en data.interactionsChartData.data. Pasa startDate y endDate siempre que el intervalo del gráfico sea importante; si los omites, el servicio elige su propio intervalo. Añade site para representar una sola fuente por separado.
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 } ] } }}Representa interactionCount con barras y averageRating con una línea. La media corresponde únicamente a ese día, no es acumulada, y es null en los días sin reseñas, así que deja un hueco en lugar de representar un cero.
Desglosa las analíticas de reseñas por fuente
GET /locations/{locationId}/review-analytics-sites-stats devuelve una entrada por fuente de reseñas en data.interactionsSitesStats.stats. Úsalo para averiguar qué plataforma hizo variar la media.
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 y newInteractions contienen cada uno un value y un delta; baseRating y baseInteractions son los valores al inicio del período desde el que se mide la variación. recency es la marca de tiempo de la reseña más reciente, y su valor es null cuando la fuente nunca ha devuelto ninguna. Un valor de 0 en newInteractions junto con un recency de hace meses suele indicar que la conexión con la fuente ha quedado desactualizada, así que comprueba las fuentes de la ubicación.
Errores que verás
Las operaciones de escritura también pueden devolver 200 con errors rellenado dentro de data.<op>, así que lee el cuerpo de la respuesta de cada operación de escritura. La lista completa está en Códigos de error.
Siguientes pasos
- Obtén reseñas: crea una cola de pendientes y recibe notificaciones mediante webhook.
- Responde a las reseñas: responde, confirma, edita y archiva.
- Analíticas de reseñas: cuadro de indicadores, gráfico, panel de quejas, instantáneas diarias.
- Analíticas: métricas de los perfiles de Google, Facebook y Bing de la misma ubicación.
- Página principal de referencia: Reseñas. SDK: Reseñas en Python, Reseñas en Node.