使用 listings scan 稽核企業的商家資訊

查看任何企業在地圖、搜尋引擎、目錄及 AI 助理中的呈現情況,檢視各目錄中名稱、地址與電話的準確性,並透過 webhook 或輪詢取得結果。

listings scan 會檢查某個商家在 listingsAPI 目錄網路中的商家資訊,並逐一告知您是否在各目錄中找到該商家,以及其名稱、地址和電話是否與您提供的資料相符。該商家不必是您帳戶中的地點。本指南會建立掃描、等待掃描完成,然後讀取結果。

您可以用它來:

  • 在為潛在客戶完成設定前進行稽核,讓初次討論聚焦於缺漏或錯誤的商家資訊;
  • 在修正客戶的商家資訊前後,檢查其商家資訊是否出現在各目錄中,以及 NAP(名稱、地址、電話)是否一致;
  • 讓 AI 代理程式無須將商家新增至帳戶,就能回答「這個商家的商家資訊在各目錄中刊登的情況如何?」。

1. 建立掃描

POST /listings/scans 接收以單一 input 物件提供的商家資料,並立即傳回狀態為 QUEUED 的掃描。各目錄的檢查會在背景執行。

欄位必填備註
name是最多 150 個字元。
street是最多 200 個字元。
city是最多 100 個字元。
stateIso是,但 GB 除外州或省的代碼,最多 50 個字元。
postalCode是,但 NG 和 AE 除外最多 20 個字元。
countryIso是由 2 個字母組成的 ISO 3166-1 代碼,例如 US。
phone是6 至 15 位數字。本地格式會依據 countryIso 解讀,也支援以 + 開頭的格式。
Create a scan
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。

JSON
{  "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。 請求遭拒絕時,仍會傳回 HTTP 200。拒絕資訊位於 data.createListingScan.errors,而 scan 為 null。電話號碼過短時的回應如下:
JSON
{  "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,僅在需要備援時使用輪詢。

當掃描達到最終狀態時,listingsAPI 會將 1 個 listing_scan.completed 或 listing_scan.failed 事件傳送至您的 webhook URL。事件中的 data.scan 與 GET 傳回的物件相同,且包含結果,因此之後無須再擷取資料。

JSON
{  "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 上新增 1 個分支。

One more branch in your receiver
# 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 秒輪詢一次,不可更頻繁;每次請求都會計入您的速率限制。

Poll until the scan finishes
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
status意義
QUEUED已接受,等待開始。
IN_PROGRESS正在檢查各目錄。results 僅包含部分結果。
COMPLETED每個目錄都有結果。results 和 summary 均為最終結果。
FAILED掃描無法啟動,例如服務暫時無法使用時(SY83010)。failure 包含 code 和 message,而 results 為空。失敗的掃描不會耗用您的額度,因此您可以再次建立掃描。

若掃描結果來自近期的掃描或您自己的某個地點,建立時就會處於 COMPLETED 狀態,因此只需執行一次 GET。

3. 讀取結果

已完成的掃描包含一個 summary,且每個已檢查的目錄在 results 中都有一筆項目,依國家而異,最多約 60 筆。business 會傳回您送出的輸入資料,其中 phone 已正規化為國際格式。

JSON
{  "total": 62,  "found": 21,  "accurate": 18,  "inaccurate": 2,  "notFound": 41,  "pending": 0,  "unavailable": 0}

total 是目錄總數。found 是刊登該商家的目錄數量,可分為 accurate、inaccurate,以及下方說明的僅確認存在的商家資訊。notFound 是未刊登該商家的目錄數量。unavailable 計算本次無法檢查的目錄數量,而 pending 只有在掃描執行期間才會不為 0。

每筆結果都有該目錄的 status:

結果的 status意義
FOUND該目錄已刊登此商家。listing 包含該目錄顯示的內容。
NOT_FOUND已檢查該目錄,其中沒有此商家。
UNAVAILABLE本次無法檢查該目錄。這與未刊登不同,因此請勿將其回報為缺漏。請稍後再次檢查該目錄。
PENDING尚未檢查。只會在掃描執行期間出現。

對於 FOUND 結果,accurate 會指出商家資訊是否與您的輸入資料相符:

  • true 表示名稱、地址和電話皆相符。
  • false 表示至少有一項不相符。商家資訊中缺少的欄位會視為不相符,因此沒有電話號碼的商家資訊會是 false。
  • null 表示已找到該商家,但未逐一檢查欄位。

accuracy 會針對 name、address 和 phone 各提供一個 status 和一個 message,以說明判定結果。status 為 ACCURATE、INACCURATE 或 MISSING,而欄位資料正確時,message 為 null。以下是一個名稱和地址相符,但沒有電話號碼的 Facebook 頁面:

JSON
{  "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。請將這些商家資訊視為已存在,而非已驗證:

JSON
{  "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:

JSON
{  "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 中的獨立項目,但不要將它們解讀為獨立的確認依據:

JSON
{  "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。

若要根據已完成的掃描建立修正清單,請列印每個有欄位錯誤或缺漏的目錄:

Directories that need attention
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 的掃描,這會列印 2 行:Facebook 沒有電話號碼,而 Judys Book 顯示的電話號碼與輸入資料不同。

Text
Facebook phone: No phone number on the listingJudys Book phone: Phone number does not match

結果來源

source 表示掃描結果的取得方式,resultsAsOf 則是資料收集時間。

source意義
DIRECTORY_SEARCH重新搜尋各個目錄。resultsAsOf 是這次掃描完成的時間。
RECENT_SCAN任何人在過去 7 天內對同一家商家執行的掃描副本。這類掃描會立即完成,而 resultsAsOf 是原始資料的收集時間,因此可能早於 createdAt。
LOCATION_LISTINGS商家的電話、郵遞區號和國家與您自己的某個地點相符,因此結果來自該地點的實際商家資訊。locationId 會設有值,accuracySource 會是 SYNC_STATUS 而非 DIRECTORY_MATCH,且每筆結果都會包含該商家資訊的 syncStatus。

費用、限制與錯誤

只有全新的 DIRECTORY_SEARCH 掃描會使用您的每月額度,額度依您的方案而定,並隨計費週期重設。以下情況不會計費:

  • 在 7 天內重複掃描同一家商家。系統會傳回您自己先前的掃描,並附上 reused: true;
  • 任何帳戶最近對同一家商家執行的掃描可提供所需結果。這會是 RECENT_SCAN 副本;
  • 與您自己的某個地點相符的掃描(LOCATION_LISTINGS);
  • 以 FAILED 結束的掃描,其使用的額度會退還。

掃描會保留 90 天。之後,GET 會傳回 404,並附上 SY83005。

建立和列出掃描的回應會包含 quota 物件,讓您在開始批次處理前查看額度使用情況。列出掃描時,系統會依時間由新到舊傳回您的掃描,每頁 1 至 50 筆,包含 perPage,不含 results。

Check your allowance
curl -s "https://listingsapi.com/api/v4/listings/scans?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY" \| jq '.data.listingScans.quota'
quota 欄位意義
limit您的方案在目前週期內允許的全新掃描次數。
used目前已使用的全新掃描次數。
remaininglimit 減去 used,最低為 0。
resetsAt額度重設時間。

以下是最常見的錯誤。建立掃描時,錯誤會在回應本文中傳回,HTTP 狀態為 200;取得和列出掃描時,則會傳回一般的 HTTP 狀態。

代碼發生位置意義與修正方式
SY83002建立每月額度已用完。訊息會包含額度上限和重設時間,並傳回 quota。請等到 resetsAt,或重複使用過去 7 天內的掃描,這不會產生費用。
SY83003建立,或掃描的 failure某個值遺漏或無效。contextInfo 會指出欄位名稱。請修正輸入後重新傳送。
SY83004建立該 countryIso 不支援 Listings scans。
SY83001建立您的方案不包含 listings scans。
SY83005取得找不到該 id 的掃描,或該掃描屬於另一個帳戶,或已超過 90 天。HTTP 404。
SY83010建立,或掃描的 failure掃描暫時無法使用。請稍後再試。
SY90016建立此金鑰僅供讀取。請使用 Write 金鑰。

對不存在的 id 執行 GET 會傳回:

JSON
{  "data": {    "listingScan": null  },  "errors": [    {      "message": "SY83005: Listing scan not found"    }  ]}

以 FAILED 結束的掃描會在 failure 中提供原因,且 results 會保持空白:

JSON
{  "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。

後續步驟