المراجعات

كل نقاط نهاية التقييمات بأمثلة cURL وPython وNode: المصادر والإعدادات، القائمة، التجميع، التفاصيل، الرد، التعديل، الأرشفة، العبارات، التحليلات.

التقييمات هي التقييمات بالنجوم والتعليقات التي يتركها العملاء على Google وFacebook وYelp. تخزّن API نسخة واحدة من كل تقييم، وتتيح لك الرد عليه، وتحسب تحليلات التقييمات. تستخدم مسارات REST الاسم reviews؛ وتستخدم مفاتيح الاستجابة وعناوين الصفحات المرجعية الاسم interactions، وهو الاسم الداخلي الأقدم للكائن نفسه. يستخدم هذا الدليل مصطلح التقييم في جميع أجزائه. تتطلب عمليات القراءة مفتاح Read (قراءة). يتطلب الرد والتعديل والأرشفة وتغيير الإعدادات مفتاح Write (كتابة)؛ ويؤدي استخدام مفتاح Read في عملية كتابة إلى إرجاع 400 مع SY90016.

نظرة سريعة على نقاط النهاية

الطريقةالمسارالوظيفةالمرجع
GET/reviews/site-configمصادر التقييمات التي تسمح بها خطة الحساب.سرد مصادر التقييمات لحساب
GET/locations/{locationId}/reviews/settingsالمصادر المهيّأة لموقع واحد.سرد مصادر التقييمات لموقع
POST/locations/reviews/settings/editتعيين مصادر موقع والحد الأدنى للتقييم الإيجابي.تعديل إعدادات التقييمات
GET/locations/{locationId}/reviewsقائمة بتقييمات موقع واحد تستخدم مؤشرًا للتنقل بين الصفحات.سرد التقييمات
GET/rollup_interactionsقائمة تشمل جميع المواقع وتستخدم مؤشرًا للتنقل بين الصفحات.جلب التقييمات المجمّعة
GET/reviewDetailsنسخ حديثة من التقييمات حسب المعرّف، مع الردود.جلب التقييمات حسب المعرّفات
مرجع حقول كائنات التقييمات والردود.خصائص التقييم
POST/locations/reviews/respondنشر رد من المالك.الرد على تقييم
POST/locations/reviews/respond/editتغيير نص رد.تعديل رد
POST/locations/reviews/respond/archiveإزالة رد من التتبع.أرشفة رد
GET/review-phrasesالعبارات التي يكررها العملاء، مع إحصاءات.سرد عبارات التقييمات
GET/locations/{locationId}/review-analytics-overview4 مؤشرات أداء رئيسية مع فروق بين الفترات.نظرة عامة على تحليلات التقييمات
GET/locations/{locationId}/review-analytics-timelineالعدد اليومي ومتوسط التقييم.المخطط الزمني لتحليلات التقييمات
GET/locations/{locationId}/review-analytics-sites-statsالتقييم وعدد التقييمات ومدى حداثتها لكل مصدر.تحليلات التقييمات حسب المنصة

سرد مصادر التقييمات التي تسمح بها خطتك

تُرجع GET /reviews/site-config دليل منصات التقييمات التي يحق للحساب استخدامها. لا تقبل أي معاملات ويقتصر نطاقها على الحساب، لذا خزّن نتيجتها مؤقتًا بدلًا من استدعائها لكل موقع. قيم siteUrl هي أسماء المضيفين التي يقبلها كل عامل تصفية آخر في هذا المورد.

الاسمالموضعمطلوبملاحظات
لا يوجدلا توجد معاملات.
Account sources
curl https://listingsapi.com/api/v4/reviews/site-config \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "interactionSiteConfig": [      { "site": "Google", "siteUrl": "maps.google.com" },      { "site": "Facebook", "siteUrl": "facebook.com" },      { "site": "Yelp", "siteUrl": "yelp.com" }    ]  }}

اقرأ data.interactionSiteConfig[]. يعرض المثال حسابًا على خطة Launch؛ وتعتمد المجموعة الدقيقة على الخطة وقطاع النشاط. استخدم siteUrl لعامل التصفية siteUrls في نقاط نهاية القوائم، وللحقل siteUrls[].name عند تعديل الإعدادات.

سرد المصادر المهيّأة لموقع

تُرجع GET /locations/{locationId}/reviews/settings سجلًا واحدًا لكل منصة تدعمها الخطة، مع عنوان URL الذي تُجلب منه التقييمات. وهي جانب القراءة المقابل لنقطة نهاية التعديل أدناه. يقبل المسار المعرّف بترميز base64 أو الرقم العادي.

الاسمالموضعمطلوبملاحظات
locationIdpathنعممعرّف Relay بترميز base64 أو databaseId رقمي.
Location sources
curl https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/reviews/settings \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "interactionsSetting": {      "siteSettings": [        { "name": "maps.google.com", "url": null },        { "name": "facebook.com", "url": null },        { "name": "yelp.com", "url": null }      ]    }  }}

اقرأ data.interactionsSetting.siteSettings[]. تعني قيمة url غير المساوية لـ null أن المنصة متصلة وأن التقييمات تُجلب من تلك الصفحة. عندما تكون قيمة url هي null، فهذا يعني أن المنصة متاحة لكنها غير مهيّأة. تُملأ بيانات Google وFacebook تلقائيًا عند ربط هذين الحسابين عبر OAuth، ولا يمكن الكتابة فوقها باستخدام نقطة نهاية التعديل. يجب تحديد Yelp صراحةً.

تعديل إعدادات التقييمات لموقع

تحدد POST /locations/reviews/settings/edit المصادر التي تُراقَب فيها تقييمات الموقع والتقييم بالنجوم الذي يُعدّ إيجابيًا. توضع الحقول مباشرةً في جسم الطلب، وليس داخل غلاف input. تؤدي إضافة مصدر إلى إدراج عملية استخلاص بيانات في قائمة الانتظار، لذا تصل تقييمات المنصة الجديدة لاحقًا، ولا تظهر في هذه الاستجابة.

الاسمالموضعمطلوبملاحظات
locationIdbodyنعممعرّف Relay بترميز base64 فقط. يؤدي استخدام معرّف رقمي في جسم الطلب إلى الفشل مع SY90002.
siteUrlsbodyلامجموعة المصادر الكاملة، على هيئة أزواج من name وurl. تحل محل الاختيار الحالي.
siteUrls[].namebodyلامفتاح المنصة من siteSettings[].name، مثل maps.google.com أو yelp.com.
siteUrls[].urlbodyلاصفحة الموقع على تلك المنصة. يؤدي تعيين القيمة إلى null أو إغفال الحقل إلى إيقاف مراقبة مصدر يتطلب عنوان URL.
positiveInteractionThresholdbodyلاعدد النجوم الذي يُعدّ التقييم إيجابيًا إذا بلغه أو تجاوزه. عند إرساله وحده، تبقى المصادر دون تغيير.
Edit settings
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" }  ]}'
JSON
{  "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 }        ]      }    }  }}

اقرأ data.editInteractionsSetting.interactionSetting.siteSettings[] للاطلاع على الاختيار المخزّن. يشير monitored إلى أن المصدر نشط؛ ويبيّن canRespond ما إذا كان يمكن نشر ردود المالك فيه عبر API. يُعاد المصدر الذي يرفضه التحقق من الصحة، مثل عنوان URL يتعذر الوصول إليه أو منصة غير مشمولة بالخطة، ضمن errors مع بقاء الإعداد دون تغيير، لذا تحقّق من errors عند تلقي 200. تُطلق حزم SDK الاستثناء ValidationError في هذه الحالة.

سرد التقييمات لموقع

GET /locations/{locationId}/reviews هو اتصال قائم على المؤشرات عند data.interactions، بترتيب الأحدث أولًا. القيمة الافتراضية لـ first هي 20، لذا لا يجلب استدعاء واحد السجل الكامل مطلقًا. تُمرَّر مرشحات المصفوفات كسلاسل JSON في سلسلة الاستعلام، ويجب ترميزها وفق ترميز URL؛ ويستخدم مثال cURL الخيار -G مع --data-urlencode لهذا الغرض.

الاسمالموضعمطلوبملاحظات
locationIdpathنعممعرّف Relay بترميز Base64 أو databaseId رقمي.
first, afterqueryلاالتنقل إلى الصفحات التالية. مرّر pageInfo.endCursor بوصفه after.
last, beforequeryلاالتنقل إلى الصفحات السابقة. لا يحتوي pageInfo على startCursor، لذا مرّر cursor الخاص بأول عنصر edge.
siteUrlsqueryلامصفوفة JSON من أسماء المضيفين، مثل ["maps.google.com"].
ratingFiltersqueryلامصفوفة JSON من التقييمات بالنجوم، مثل [1,2].
responseStatusqueryلامصفوفة JSON: ["PENDING"] أو ["RESPONDED"].
sortOrderqueryلامصفوفة JSON: ["NEWEST_FIRST"] أو ["OLDEST_FIRST"] أو ["LAST_RESPONDED"].
startDate, endDatequeryلاYYYY-MM-DD، سلاسل نصية عادية.
searchStringqueryلابحث نصي كامل في متن التقييم.

بالإضافة إلى المعاملات الاختيارية category وcategories وratingFilter ذي القيمة الواحدة، المدرجة في الصفحة المرجعية.

List reviews
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'
JSON
{  "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    }  }}

اقرأ edges[].node. تمرّر id عند الرد، ويبيّن canRespond ما إذا كان ذلك المصدر يقبل ردود المالك. يمثّل totalCount عدد النتائج المطابقة في مجموعة النتائج بأكملها، وليس في هذه الصفحة. توقّف عن التنقل بين الصفحات عندما تكون قيمة hasNextPage هي false أو عندما تُرجع صفحةٌ edges فارغًا؛ فإذا وقع حدّ الصفحة عند أقدم تقييم، تتبعه صفحة فارغة واحدة.

المرشحالقيم
responseStatusRESPONDED, PENDING
sortOrderNEWEST_FIRST, OLDEST_FIRST, LAST_RESPONDED
categoryREVIEW، بالإضافة إلى فئات أخرى متاحة لكل حساب

فحص جميع المواقع باستخدام التجميع

GET /rollup_interactions هو الاتصال نفسه القائم على المؤشرات عبر جميع المواقع التي يمكن للمفتاح الوصول إليها، عند data.rollupInteractions، مع locationId رقمي في كل عقدة. يقبل المرشحات نفسها التي تقبلها القائمة الخاصة بكل موقع. لا يوجد مرشح للموقع؛ ويُتجاهل المعامل locationIds ولا يُرفض. لا توفّر أيٌّ من حزمتي SDK دالةً تغلّف نقطة النهاية هذه حتى الآن، لذا تستخدم الأمثلة requests وfetch.

الاسمالموضعمطلوبملاحظات
tagqueryلاوسم الموقع الذي يُحصر النطاق به. القيمة الافتراضية هي all. احذفه ما لم تكن تستخدم وسومًا للمواقع.
first, after, last, beforequeryلاالتنقل بين الصفحات باستخدام المؤشرات، كما في نقطة نهاية القائمة.
siteUrls, ratingFilters, responseStatus, sortOrderqueryلامصفوفات JSON مرمّزة وفق ترميز URL، بالقيم نفسها المستخدمة في نقطة نهاية القائمة.
startDate, endDate, searchStringqueryلاكما في نقطة نهاية القائمة.
Account rollup
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'
JSON
{  "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    }  }}

جمّع العقد حسب locationId، وهو databaseId الخاص بالمتجر. قد لا يتضمن pageInfo الخاص بالتجميع الحقل endCursor، لذا استخدم cursor الخاص بآخر عنصر edge بوصفه after؛ فالقيمتان متكافئتان. حدّد نطاق عمليات التشغيل المجدولة باستخدام startDate وendDate بدلًا من إعادة قراءة السجل، والتزم بـ Retry-After عند تلقي 429.

جلب التقييمات حسب id

يُرجع GET /reviewDetails نسخًا محدّثة من التقييمات المخزّنة دون تقسيمها إلى صفحات. الاستجابة مصفوفة عادية عند data.interactionDetails.interactions، دون edges أو pageInfo، ويتضمن كل تقييم responses الخاص به. استخدمه لإعادة جلب البيانات الحالية لقائمة متابعة وللعثور على responseId الذي تحتاج إليه للتعديل أو الأرشفة.

الاسمالموضعمطلوبملاحظات
interactionIdsqueryنعممصفوفة JSON من معرّفات UUID للتقييمات، مرمّزة وفق ترميز URL. عند حذفها، تُرجع نقطة النهاية SY90006.
Details by id
curl -G "https://listingsapi.com/api/v4/reviewDetails" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'interactionIds=["b2fa765e-c62b-4e0b-b1d6-1c67c855f5e0"]'
JSON
{  "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 هو responseId لنقطتي نهاية التعديل والأرشفة. عند تمرير id من حساب آخر، تُرجع نقطة النهاية 200 مع interactionDetails: null وخطأ SY90001، لذا تحقّق من null قبل الوصول إلى العناصر باستخدام الفهرس.

حقول التقييم والرد

مرجع السمات صفحة توثيق فقط تسرد جميع الحقول في كائن التقييم وكائن الرد. الحقول التي ستستخدمها أكثر من غيرها:

الحقلالنوعالمعنى
id, interactionIdstringمعرّف UUID نفسه؛ مرّره بوصفه interactionId عند الرد.
sourcestringاسم مضيف الموقع، مثل maps.google.com.
content, authorName, rating, datemixedنص التقييم، وكاتب التقييم، وتقييم من 1 إلى 5 نجوم، وطابع زمني بتنسيق ISO 8601.
typestringReview أو Question أو Comment أو Recommendation أو Post أو Photo أو Message أو Response.
categorystringفئة عامة، Review أو Social.
responded, responseCount, responsesmixedما إذا كانت هناك ردود من المالك، وعددها، وكائنات الردود.
canRespondbooleanما إذا كان يمكن نشر رد على هذا المصدر عبر API.
permalinkstringرابط التقييم على موقع المصدر.
locationIdintegerdatabaseId الرقمي للموقع.

يتضمن كل رد في responses[] الحقول id وcontent وauthorName وdate وinteractionStatus وeditedResponse وrespondedWith (معرّف القالب) وremarks (تفاصيل الفشل). ينتقل interactionStatus بين الحالات التالية:

الحالةالمعنى
CREATEDقُبل الرد وأُضيف إلى قائمة الانتظار لإرساله إلى منصة النشر.
COMPLETEDنُشر الرد على منصة النشر. تتوقف بعض المنصات عند هذه المرحلة.
CONFIRMEDنُشر الرد وأكّدت منصة النشر نشره.
FAILEDرفضته منصة النشر. يوضّح remarks السبب.

نشر رد من المالك

ينشر POST /locations/reviews/respond ردًا عامًا على المنصة المصدر. تُوضع الحقول مباشرةً في جسم الطلب. يُقبل الرد فورًا ويُسلَّم بصورة غير متزامنة، لذا يبدأ interactionStatus بالقيمة CREATED. تحقّق أولًا من canRespond في التقييم.

الاسمالموضعمطلوبملاحظات
interactionIdbodyنعمid الخاص بالتقييم.
responseContentbodyنعمنص الرد.
respondedWithbodyلامعرّف قالب الرد، إذا كان الرد مأخوذًا من قالب.
Respond
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!"}'
JSON
{  "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    }  }}

احتفظ بـ interaction.id: فهو responseId المستخدم للتعديل والأرشفة. يُعاد الرد المرفوض بصيغة 200 مع تعبئة errors داخل data.respondToInteraction، لذا اقرأ جسم الاستجابة؛ وتُطلق حزم SDK الاستثناء ValidationError. أعد قراءة التقييم باستخدام معرّفه بعد انتظار قصير لرؤية الرد يصل إلى COMPLETED أو CONFIRMED.

تعديل رد

يغيّر POST /locations/reviews/respond/edit نص رد موجود. يُعاد إرسال التعديل إلى المنصة، لذا يعود interactionStatus إلى CREATED ويصبح editedResponse بالقيمة true بمجرد وصول التعديل إليها. يُفضَّل استخدام هذا الإجراء على الأرشفة وإعادة النشر في المنصات التي تسمح برد واحد.

الاسمالموضعمطلوبملاحظات
reviewIdbodyنعمid الخاص بالتقييم.
responseIdbodyنعمid الخاص بالرد من responses[].
responseContentbodyنعمنص الرد الجديد.
templateIdbodyلامعرّف قالب الرد المراد إعادة إسناد الرد إليه.
Edit reply
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."}'
JSON
{  "data": {    "editResponse": {      "status": "true",      "reviewId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",      "responseId": "2090753a-ece6-4837-8336-8494ad308523"    }  }}

تكون قيمة status هي السلسلة النصية "true" عند قبول التعديل. تأكّد من الصياغة الجديدة باستدعاء جلب التفاصيل وتحقّق من interactionStatus الخاص بالرد.

أرشفة رد

يزيل POST /locations/reviews/respond/archive ردًا من responses الذي نتتبّعه للتقييم من جانبنا. هذا حذف منطقي: فالرد المنشور بالفعل على Google أو Yelp أو Facebook يبقى هناك. استخدمه لإزالة مسودة فشلت أو حلّت محلها مسودة أخرى؛ واستخدم التعديل لأي رد منشور.

الاسمالموضعمطلوبملاحظات
responseIdbodyنعمid الخاص بالرد من responses[].
Archive reply
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" }'
JSON
{  "data": {    "archiveResponse": {      "status": "true"    }  }}

بعد الأرشفة، ينخفض responseCount الخاص بالتقييم ويعكس responded الردود المتبقية.

عرض العبارات التي يكررها العملاء

يُرجع GET /review-phrases مصفوفة بسيطة في data.newReviewPhrases، تضم عنصرًا واحدًا لكل عبارة متكررة، ولكل عنصر إحصاءات محسوبة على التقييمات التي تحتوي على تلك العبارة فقط. النتائج غير مقسّمة إلى صفحات؛ حدّد حدها الأقصى باستخدام phraseCount. كل عوامل التصفية اختيارية ويمكن جمعها، لذا فإن استخدام ratingFilters=[1,2] مع startDate يعطي شكاوى الربع السابق.

الاسمالموضعمطلوبملاحظات
locationIdsqueryلامصفوفة JSON من معرّفات المواقع الرقمية، مثل [1800289]. احذف هذا المعامل لتشمل كل موقع يتيح المفتاح قراءته.
siteUrlsqueryلامصفوفة JSON من أسماء المضيفين.
startDate, endDatequeryلاYYYY-MM-DD.
ratingFiltersqueryلامصفوفة JSON من التقييمات بالنجوم.
responseStatusqueryلامصفوفة JSON من RESPONDED أو PENDING.
sortOrderqueryلاNEWEST_FIRST أو OLDEST_FIRST أو LAST_RESPONDED أو LOWEST_RATING أو HIGHEST_RATING.
phraseCountqueryلاالحد الأقصى لعدد العبارات المراد إرجاعها.
searchStringqueryلاالعبارات التي تحتوي على هذه السلسلة الفرعية فقط.

بالإضافة إلى categories الاختياري والمعاملين المهملين ذوي القيمة الواحدة category وratingFilter المذكورين في الصفحة المرجعية.

Phrases
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'
JSON
{  "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 عدد مرات ظهور العبارة، ويمثّل overall-rating متوسط تقييم تلك التقييمات، ويمثّل delta نسبة التغيّر مقارنةً بالفترة السابقة، ويمثّل abs مقدار التغيّر المطلق. تعني استجابة 403 المصحوبة بـ SY90003 أن المفتاح لا يتيح قراءة أحد المواقع المطلوبة.

قراءة مؤشرات الأداء الرئيسية للتقييمات لموقع

يُرجع GET /locations/{locationId}/review-analytics-overview أربعة إحصاءات في data.interactionsAnalyticsStats.stats. النطاق الزمني اختياري؛ وهو يضيّق الفترة التي تُحسب خلالها القيم ومقادير تغيّرها. يمثّل كل delta نسبة التغيّر مقارنةً بالفترة السابقة المساوية لها في الطول.

الاسمالموضعمطلوبملاحظات
locationIdpathنعممعرّف Relay بترميز Base64 أو databaseId رقمي.
startDate, endDatequeryلاYYYY-MM-DD. اختياري هنا، بخلاف الخط الزمني.
Overview
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/review-analytics-overview?startDate=2026-08-01&endDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "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 }      ]    }  }}
namevalueتُفسَّر القيمة على أنها
total-reviewsعددجميع التقييمات الخاصة بالموقع.
new-reviewsعددالتقييمات المستلمة خلال الفترة.
overall-ratingمن 1 إلى 5متوسط التقييم بالنجوم.
review-response-rateنسبة مئويةنسبة التقييمات التي تتضمن ردًا من المالك.

يُظهر الحساب الجديد الذي لا تتوفر له فترة سابقة قيمة 100 في delta، لذا لا تفسّر مقادير التغيّر في الشهر الأول على أنها نمو.

جلب التسلسل الزمني اليومي للتقييمات

يعيد GET /locations/{locationId}/review-analytics-timeline عنصرًا واحدًا لكل يوم في data.interactionsChartData.data. مرّر startDate وendDate كلما كان النطاق الزمني للمخطط مهمًا؛ فحذفهما يتيح للخدمة اختيار نطاقها الزمني بنفسها. أضف site لرسم بيانات مصدر واحد بمفرده.

الاسمالموضعمطلوبملاحظات
locationIdpathنعممعرّف Relay بترميز Base64 أو databaseId رقمي.
startDate, endDatequeryلاYYYY-MM-DD. مرّر كليهما للحصول على نطاق زمني يمكن توقّعه.
sitequeryلااسم مضيف واحد من siteSettings[].name، مثل maps.google.com. لا تتيح أيٌّ من حزمتَي SDK هذا المعامل؛ استخدم استدعاء REST.
Timeline
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"
JSON
{  "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 }      ]    }  }}

ارسم interactionCount على هيئة أعمدة وaverageRating على هيئة خط. يخص المتوسط ذلك اليوم وحده، وليس متوسطًا تراكميًا، وتكون قيمته null في اليوم الذي لا توجد فيه تقييمات، لذا اترك فجوة بدلًا من رسم قيمة صفر.

تفصيل تحليلات التقييمات حسب المصدر

يعيد GET /locations/{locationId}/review-analytics-sites-stats عنصرًا واحدًا لكل مصدر تقييمات في data.interactionsSitesStats.stats. استخدمه لمعرفة المنصة التي غيّرت المتوسط.

الاسمالموضعمطلوبملاحظات
locationIdpathنعممعرّف Relay بترميز Base64 أو databaseId رقمي.
startDate, endDatequeryلاYYYY-MM-DD. تقارن قيم التغيّر هذه الفترة بالفترة السابقة المساوية لها في المدة.
By source
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"
JSON
{  "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 وnewInteractions قيمة value وقيمة delta؛ أما baseRating وbaseInteractions فهما القيمتان عند بداية الفترة التي يُقاس التغيّر انطلاقًا منها. يمثّل recency الطابع الزمني لأحدث تقييم، وتكون قيمته null إذا لم يُعِد المصدر أي تقييم مطلقًا. عادةً ما يعني وجود newInteractions بقيمة 0 مع recency يعود إلى عدة أشهر أن الاتصال بالمصدر لم يعد محدّثًا، لذا تحقّق من مصادر الموقع.

الأخطاء التي ستواجهها

الرمزالمعنىالحل
SY90016استُخدم مفتاح Read في عملية كتابة.استخدم مفتاح Write.
SY90001غير مصرّح به: المفتاح غير صالح، أو معرّف التقييم تابع لحساب آخر. في /reviewDetails، يُعاد هذا الخطأ بصيغة 200 مع interactionDetails: null.تحقّق من المفتاح والمعرّف.
SY90002معرّف غير صالح. وجود locationId رقمي في جسم طلب تعديل الإعدادات.أرسل معرّف Relay بترميز base64.
SY90003403، لا يستطيع المفتاح قراءة هذا الموقع أو تعديله.استخدم مفتاحًا لديه صلاحية الوصول إليه.
SY90006interactionIds مفقود في /reviewDetails.مرّر مصفوفة JSON من المعرّفات.
SY50121ردّ ثانٍ من المالك على تقييم في Google.عدّل الردّ الحالي.
429حدّ معدل الطلبات.انتظر المدة المحدّدة في Retry-After. راجع حدود معدل الطلبات.

قد تعيد عمليات الكتابة أيضًا 200 مع تعبئة errors داخل data.<op>، لذا اقرأ جسم الاستجابة لكل عملية كتابة. تتوفّر القائمة الكاملة في رموز الأخطاء.

الخطوات التالية