使用 listings scan 审核企业商家信息
检查任意企业在地图、搜索引擎、目录和 AI 助手中的展示情况,查看各目录中名称、地址和电话号码的准确性,并通过 webhook 或轮询获取结果。
listings scan 会检查一个商家在 listingsAPI 目录网络中的商家信息,并逐个目录告知您是否找到了该商家,以及其名称、地址和电话是否与您提供的信息一致。该商家不必是您账户中的地点。本指南将创建一次扫描,等待扫描完成,然后读取结果。
您可以用它来:
- 在为潜在客户办理入驻前进行审核,以便在首次沟通时讨论缺失或错误的商家信息;
- 在修复客户的商家信息前后,检查其商家信息的覆盖情况以及 NAP(名称、地址、电话)的一致性;
- 让 AI 智能体能够回答“这个商家的商家信息发布情况如何?”,而无需将该商家添加到账户中。
1. 创建扫描
POST /listings/scans 通过单个 input 对象接收商家信息,并立即返回处于 QUEUED 状态的扫描。目录检查在后台进行。
curl -X POST https://listingsapi.com/api/v4/listings/scans \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d @- <<'JSON'{"input": { "name": "Joe's Pizza", "street": "7 Carmine Street", "city": "New York", "stateIso": "NY", "postalCode": "10014", "countryIso": "US", "phone": "2123661182"}}JSON响应返回扫描对象,其中的 phone 已规范化为国际格式。在目录检查完成前,results 为空,因此请保存 id。
{ "data": { "createListingScan": { "reused": false, "scan": { "id": "TGlzdGluZ1NjYW46Mzk0YTRhNWMtZjcwMy00NjZiLTg2NjAtMDU4MTlmNDhkZjMz", "status": "QUEUED", "source": "DIRECTORY_SEARCH", "locationId": null, "resultsAsOf": null, "createdAt": "2026-11-05T07:01:08Z", "startedAt": null, "completedAt": null, "business": { "name": "Joe's Pizza", "street": "7 Carmine Street", "city": "New York", "stateIso": "NY", "postalCode": "10014", "countryIso": "US", "phone": "+12123661182" }, "summary": { "total": 0, "found": 0, "accurate": 0, "inaccurate": 0, "notFound": 0, "pending": 0, "unavailable": 0 }, "failure": null, "results": [] }, "errors": [] } }}响应还包含一个 quota 对象,详见费用、限制和错误。
继续之前,请检查以下 2 点:
reused。当您请求扫描过去 7 天内已扫描过的商家时,listingsAPI 会返回已有扫描,而不会启动新扫描;返回内容包含reused: true及其当前状态,通常为COMPLETED。这不会扣减您的配额,也不会为此发送新的 webhook 通知。errors。被拒绝的请求仍会返回 HTTP200。拒绝原因位于data.createListingScan.errors中,且scan为null。电话号码过短时的响应如下:
{ "data": { "createListingScan": { "reused": false, "scan": null, "errors": [ { "code": "SY83003", "message": "SY83003: Invalid value for phone", "contextInfo": [ { "key": "field", "value": "phone" } ] } ] } }}contextInfo 指明了验证失败的字段。您可能收到的其他代码列在错误表中。
2. 等待结果
扫描从 QUEUED 转为 IN_PROGRESS,然后转为 COMPLETED 或 FAILED。大多数扫描会在 1 至 7 分钟内完成。如果某个目录在约 15 分钟后仍未响应,其结果会被设为 UNAVAILABLE,扫描会连同其他结果一起完成。请尽可能使用 webhook,仅将轮询用作备用方式。
2a. 接收 webhook(推荐)
当扫描进入最终状态时,listingsAPI 会向您的 webhook URL 发送一个 listing_scan.completed 或 listing_scan.failed 事件。事件中的 data.scan 与 GET 返回的对象相同,其中包含结果,因此您无需在之后另行获取。
{ "event": "listing_scan.completed", "timestamp": "2026-11-05T07:01:52Z", "account_id": 12345, "data": { "scan": { "id": "TGlzdGluZ1NjYW46Mzk0YTRhNWMtZjcwMy00NjZiLTg2NjAtMDU4MTlmNDhkZjMz", "status": "COMPLETED", "summary": { "total": 62, "found": 21, "accurate": 18, "inaccurate": 2, "notFound": 41, "pending": 0, "unavailable": 0 }, "results": [ "..." ] } }}此处的负载已精简;完整示例见事件参考。与其他事件一样,这些事件会经过签名并投递,仅尝试 1 次,时限为 5 秒,因此请先验证签名、存储原始请求体并确认接收,再执行其他操作。使用 webhook 响应事件中的接收端已实现这些操作;唯一需要的更改是在 event 上增加一个分支。
# After the signature check and the endpoint.verification branch:if body.get("event") in ("listing_scan.completed", "listing_scan.failed"): inbox.put(raw) # commit before the 200; read data.scan from the queue return {"received": True}, 200事件只会发送到已启用 webhook 且 URL 已通过验证的账户。如果您的账户未满足这些条件,或事件始终未送达,请轮询扫描;无论哪种情况,扫描都会保留 90 天。签名详情见签名与验证。
2b. 使用轮询作为备用方案
GET /listings/scans/{scanId} 返回扫描及其截至目前已有的结果。扫描运行期间,随着各目录返回结果,results 会逐步填充,summary.pending 则统计尚未返回结果的目录数量。每 15 秒轮询一次,不要更频繁;每次请求都会计入您的速率限制。
SCAN_ID="TGlzdGluZ1NjYW46Mzk0YTRhNWMtZjcwMy00NjZiLTg2NjAtMDU4MTlmNDhkZjMz" while true; doscan=$(curl -s "https://listingsapi.com/api/v4/listings/scans/$SCAN_ID" \ -H "Authorization: API $LISTINGSAPI_KEY")status=$(echo "$scan" | jq -r '.data.listingScan.status')echo "status: $status"case "$status" in COMPLETED|FAILED) echo "$scan" | jq '.data.listingScan | {status, summary, failure}' break ;; null) echo "$scan" break ;;esacsleep 15done如果扫描结果来自近期扫描或您自己的某个地点,扫描在创建时就处于 COMPLETED 状态,因此只需调用一次 GET。
3. 读取结果
已完成的扫描包含一个 summary,并在 results 中为每个已检查的目录提供一个条目,具体数量取决于国家或地区,最多约 60 个。business 返回您发送的输入,其中 phone 已规范化为国际格式。
{ "total": 62, "found": 21, "accurate": 18, "inaccurate": 2, "notFound": 41, "pending": 0, "unavailable": 0}total 是目录总数。found 是收录该商家的目录数量,包括 accurate、inaccurate 以及下文所述的仅确认存在的商家信息。notFound 是未收录该商家的目录数量。unavailable 统计本次无法检查的目录数量,pending 仅在扫描运行期间可能为非零值。
每个结果都有一个表示该目录状态的 status:
对于 FOUND 结果,accurate 表示商家信息是否与您的输入匹配:
true表示名称、地址和电话号码均匹配。false表示至少有一项不匹配。商家信息中缺失的字段也视为不匹配,因此没有电话号码的商家信息为false。null表示找到了该商家,但未逐字段检查。
accuracy 通过为 name、address 和 phone 分别提供 status 和 message 来解释判定结果。status 为 ACCURATE、INACCURATE 或 MISSING,字段准确时,message 为 null。以下 Facebook 页面中的名称和地址匹配,但缺少电话号码:
{ "directory": { "id": 184, "name": "Facebook", "url": "facebook.com" }, "status": "FOUND", "accurate": false, "accuracySource": "DIRECTORY_MATCH", "accuracy": { "name": { "status": "ACCURATE", "message": null }, "address": { "status": "ACCURATE", "message": null }, "phone": { "status": "MISSING", "message": "No phone number on the listing" } }, "listing": { "name": "Joe's Pizza", "street": "7 Carmine St", "city": "New York", "state": "NY", "postalCode": "10014", "country": "US", "fullAddress": "7 Carmine St, New York, NY 10014", "phones": [], "url": "https://www.facebook.com/177353602413952" }, "syncStatus": null}有些目录仅确认商家存在,不显示足以用于比较的详细信息。这些目录返回 FOUND,同时带有 accurate: null,并且仅计入 found,不计入 accurate 或 inaccurate。请将其视为已存在,而非已验证:
{ "directory": { "id": 374, "name": "Map Quest", "url": "www.mapquest.com" }, "status": "FOUND", "accurate": null, "accuracySource": "DIRECTORY_MATCH", "accuracy": { "name": { "status": "ACCURATE", "message": null }, "address": { "status": "MISSING", "message": "Not shown" }, "phone": { "status": "MISSING", "message": "Not shown" } }, "listing": { "name": "Joe's Pizza", "street": "7 Carmine St", "city": "New York", "state": "NY", "postalCode": "10014", "country": null, "fullAddress": "7 Carmine St, New York, NY 10014, US", "phones": [], "url": null }, "syncStatus": null}NOT_FOUND 结果既没有 listing,也没有 accuracy:
{ "directory": { "id": 352, "name": "YellowPages", "url": "www.yellowpages.com" }, "status": "NOT_FOUND", "accurate": null, "accuracySource": "DIRECTORY_MATCH", "accuracy": null, "listing": null, "syncStatus": null}有些目录不存储自己的数据。Uber、Waze 和 Lyft 显示 Google Maps 的数据,Copilot 显示 Bing 的数据。它们的结果与来源目录一致,因此通常会重复 Google Maps 或 Bing 返回的内容,并且没有商家信息的 url。请在 summary 中将它们计为独立条目,但不要将其视为独立的确认依据:
{ "directory": { "id": 350, "name": "Uber", "url": "uber.com" }, "status": "FOUND", "accurate": true, "accuracySource": "DIRECTORY_MATCH", "accuracy": { "name": { "status": "ACCURATE", "message": null }, "address": { "status": "ACCURATE", "message": null }, "phone": { "status": "ACCURATE", "message": null } }, "listing": { "name": "Joe's Pizza", "street": "7 Carmine Street", "city": "New York", "state": "NY", "postalCode": "10014", "country": "US", "fullAddress": "7 Carmine St, New York, NY 10014, USA", "phones": [ "+1 212-366-1182" ], "url": null }, "syncStatus": null}扫描也包括 ChatGPT 和 Gemini 等 AI 助手。对于这些助手,listing 显示助手所了解的商家信息,通常只有名称、完整地址和电话号码,并且没有针对各字段的 accuracy。
要将已完成的扫描转为修正清单,请打印所有存在错误或缺失字段的目录:
curl -s https://listingsapi.com/api/v4/listings/scans/TGlzdGluZ1NjYW46Mzk0YTRhNWMtZjcwMy00NjZiLTg2NjAtMDU4MTlmNDhkZjMz \-H "Authorization: API $LISTINGSAPI_KEY" \| jq -r '.data.listingScan.results[] | select(.accurate == false) | .directory.name as $directory | .accuracy | to_entries[] | select(.value.status != "ACCURATE") | $directory + " " + .key + ": " + (.value.message // .value.status)'对于 Joe's Pizza 的扫描,这会打印两行:Facebook 缺少电话号码,Judys Book 显示的电话号码则与输入不同。
Facebook phone: No phone number on the listingJudys Book phone: Phone number does not match结果来源
source 表示扫描结果的获取方式,resultsAsOf 表示数据的采集时间。
费用、限制和错误
只有全新的 DIRECTORY_SEARCH 扫描才会消耗您的月度配额,该配额取决于您的套餐,并随计费周期重置。以下扫描不消耗配额:
- 在 7 天内重复扫描同一家商家。系统会返回您自己之前的扫描,并附带
reused: true; - 任何账户最近对同一家商家的扫描结果可用于本次扫描。此时返回的是
RECENT_SCAN副本; - 与您自己的某个地点匹配的扫描(
LOCATION_LISTINGS); - 以
FAILED状态结束的扫描,其消耗的配额会退还。
扫描会保留 90 天。此后,GET 会返回 404,并附带 SY83005。
创建和列出操作的响应都包含一个 quota 对象,方便您在开始批量扫描前查看配额使用情况。列出操作按从新到旧的顺序返回您的扫描,每页包含 1 至 50 条,包含 perPage,不包含 results。
curl -s "https://listingsapi.com/api/v4/listings/scans?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY" \| jq '.data.listingScans.quota'以下是最常见的错误。创建操作返回 HTTP 200,并在响应正文中提供错误信息;获取和列出操作则返回常规的 HTTP 状态码。
对不存在的 id 执行 GET 会返回:
{ "data": { "listingScan": null }, "errors": [ { "message": "SY83005: Listing scan not found" } ]}以 FAILED 状态结束的扫描会在 failure 中提供原因,且 results 保持为空:
{ "status": "FAILED", "failure": { "code": "SY83010", "message": "SY83010: Listing scans are temporarily unavailable, try again later", "field": null }}通用错误格式请参阅错误码。
供 AI 智能体使用
托管 MCP 服务器通过 3 个工具提供此功能:listings_scans_create、listings_scans_get 和 listings_scans_list。助手可以为用户指定的商家启动扫描,使用 listings_scans_get 轮询扫描,并汇总需要关注的目录。与 REST 一样,创建扫描需要 Write 密钥。设置方法请参阅将 AI 智能体连接到 listingsAPI MCP。
后续步骤
- 使用 webhooks 响应事件:接收扫描事件的接收端。
- 检查商家信息状态和线上链接以及查找并修复商家信息错误:将商家添加为您账户中的地点后,跟踪并修复其商家信息。
- 添加地点:添加您已审核的商家。
- 参考:创建 listings scan、获取 listings scan、列出 listings scans、事件参考、错误码。