掲載情報のステータスを確認し、公開中のリンクを取得する

拠点のすべての掲載先の同期ステータスを読み取り、公開中の掲載情報のURLを収集し、掲載状況を集計し、音声アシスタントを確認し、ポーリングの代わりにWebhookで通知を受け取ります。

拠点が作成されると、プランに含まれる掲載先ごとに1件の掲載情報が自動的に送信されます。このガイドでは、各掲載情報の現在の状態を確認し、公開中の掲載情報のURLを取得し、Webhookの設定後にポーリングを停止する方法を説明します。

1. 拠点のプレミアム掲載情報を取得する

GET /locations/{locationId}/listings/premiumは、プランに含まれるプレミアム掲載先ごとに1件のレコードを返します。ページ分割されたリストではなく、単純な配列です。対応するルート/listings/additionalは無料のディレクトリを同じ構造で返しますが、listingTypeクエリパラメーターはありません。

Premium listings
curl https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/listings/premium \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "listingsForLocation": [      {        "site": { "name": "Google Maps", "url": "maps.google.com" },        "syncStatus": "REQUIRING_ACTION",        "displayStatus": "Connect your account to sync the listing",        "actionRequired": true,        "listingUrl": null,        "syncIssue": null,        "lastUpdate": "2026-07-06T18:33:28Z"      },      {        "site": { "name": "BeLocalFocussed", "url": "belocalfocussed.com" },        "syncStatus": "SYNCED",        "displayStatus": "Synced",        "actionRequired": false,        "listingUrl": "https://belocalfocussed.com/jenny-home-26x0ffkd0e",        "syncIssue": null,        "lastUpdate": "2026-07-06T18:33:30Z"      }    ]  }}

各行では、siteに機械可読のsyncStatusと人が読めるdisplayStatusが対応付けられています。lastUpdateはその行の最終変更日時を示すため、処理が停滞している送信を見つけるのに役立ちます。

2. 各掲載先のステータスを読み取る

syncStatusは分岐条件に使用するフィールドです。displayStatusはユーザーに表示するテキストで、syncIssueには掲載先から理由が提供されている場合にその理由が格納されます。

syncStatus意味対応方法
AVAILABLE送信の準備はできていますが、まだ開始されていません。対応は不要です。自動的に進行します。
IN_PROGRESS掲載先に送信済みで、応答を待っています。お待ちください。数週間経過している場合はlastUpdateを確認してください。
PENDING_APPROVAL掲載先が受信し、審査しています。お待ちください。
SYNCEDまたはCOMPLETED公開済みです。listingUrlに値が設定されています。リンクを収集してください(手順3)。
REQUIRING_ACTIONユーザー側の対応が必要なため、処理が停止しています。actionRequiredはtrueです。displayStatusを読んでから、掲載情報のエラーを見つけて修正するを参照してください。
FAILED掲載先が拒否したか、処理できませんでした。syncIssueを読み、拠点を修正して、再度ポーリングしてください。
CANNOT_SUBMITこの掲載先は、この拠点を受け付けることができません。通常は、掲載先が対応していない国またはカテゴリが原因です。

Google MapsとFacebookは、それぞれの掲載先のアカウントが接続されるまでREQUIRING_ACTIONのままです。接続するのは、Google Mapsの場合はGoogle Business Profile、Facebookの場合はFacebookページです。これは新しい拠点では想定される状態であり、不具合ではありません。

Apple Mapsには接続は不要です。オーナーが認証済みのApple Business組織アカウントを接続していない場合、ListingsAPIは自社のApple Business Connectアカウントを通じて拠点を送信し、Appleが送信内容を確認してから公開します。Apple Business Connectを接続するを参照してください。

listingUrlは公開中の行にのみ設定されます。SYNCED(およびCOMPLETED)で絞り込み、URLをサイト名とともに保持すると、「公開ページを見る」リストとして表示したり、自社のレコードに関連付けて保存したりできます。

Live links
curl -s https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/listings/premium \-H "Authorization: API $LISTINGSAPI_KEY" \| jq '[.data.listingsForLocation[]       | select(.listingUrl != null)       | {site: .site.name, url: .listingUrl}]'

SYNCEDの行でも、listingUrlがnullの場合があります。一部のディレクトリでは公開ページのURLが提供されないためです。ステータスを正式な判断基準とし、リンクは任意の情報として扱ってください。

4. 掲載状況のサマリーを作成する

syncStatusごとに行を数えると、公開中の掲載先、処理中の掲載先、処理が停止している掲載先がそれぞれ何件あるかという、拠点ごとの健全性指標を1行にまとめられます。この数値をダッシュボードに表示します。

Coverage
curl -s https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/listings/premium \-H "Authorization: API $LISTINGSAPI_KEY" \| jq '.data.listingsForLocation      | group_by(.syncStatus)      | map({status: .[0].syncStatus, count: length})'

GET /locationsをページごとに取得し、拠点ごとにプレミアムエンドポイントを1回呼び出すことで、多数の拠点に対してこの処理を実行できます。各呼び出しはレート制限の対象になるため、呼び出しの間に間隔を設け、429が返された場合はRetry-Afterに従ってください。掲載情報のエラーを見つけて修正するでは、このループをアカウント全体を巡回する処理として紹介しています。

5. 音声アシスタントを確認する

音声アシスタント(Google Assistant、Alexa、Siri、Cortana、Bixby)には専用のエンドポイント GET /locations/{locationId}/voice-assistants があり、ステータスの種類が少なくなっています。Google Assistant は Google 接続に依存しているため、Google 接続がない拠点はここでも対応が必要です。Siri の結果は、その拠点の Apple Maps の掲載情報に基づきます。

Voice assistants
curl https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/voice-assistants \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "voiceAssistantsForLocation": [      {        "voiceIdentifier": "GOOGLE_ASSISTANT",        "name": "Google Assistant",        "syncStatus": "REQUIRING_ACTION",        "actionRequired": true,        "syncIssue": null,        "errors": []      },      {        "voiceIdentifier": "SIRI",        "name": "Siri",        "syncStatus": "IN_PROGRESS",        "actionRequired": false,        "syncIssue": null,        "errors": []      }    ]  }}
syncStatus意味
NOT_SUBMITTEDアシスタントにまだ送信されていません。
IN_PROGRESS送信処理中です。
REQUIRING_ACTIONユーザー側の対応待ちで処理が停止しています。syncIssue を確認してください。
LIVE公開済みです。

音声アシスタントには公開ページへのリンクがなく、LIVE が最終状態です。

6. ポーリングの代わりに Webhook イベントを受信する

/dashboard/webhooks で Webhook URL を設定している場合、1 つの拠点について掲載先への送信が最終状態に達するたびに、listing.submission イベントが発生します。このイベントには status(success、incomplete、または canceled)とサイトが含まれ、成功時には手順 3 で取得したものと同じ URL である live_link も含まれます。

Route listing.submission
import base64 def handle(payload: dict) -> None:  if payload["event"] != "listing.submission":      return   data = payload["data"]  # "TG9jYXRpb246Mjc5Mzgx" -> "Location:279381"  global_id = base64.b64decode(data["location_id"]).decode()  database_id = int(global_id.split(":")[1])   site = data["site"]["name"]  status = payload["status"]   if status == "success":      live_link = payload.get("live_link")      save_live_link(database_id, site, live_link)  elif status == "incomplete":      flag_for_review(database_id, site, payload.get("error_message"))

5 秒以内に 200 を返し、その後で処理を行ってください。再試行はありません。受信側のひな形と署名の検証については、Webhook でイベントに対応するを参照してください。

次の手順