Unternehmenseinträge mit einem listings scan prüfen

Firmen in Karten, Suchmaschinen, Verzeichnissen und KI-Assistenten prüfen: Name, Adresse, Telefon je Verzeichnis abgleichen; Abruf per Webhook/Polling.

Ein listings scan prüft, wie ein Unternehmen im Verzeichnisnetzwerk von listingsAPI eingetragen ist, und zeigt für jedes Verzeichnis, ob das Unternehmen gefunden wurde und ob Name, Adresse und Telefonnummer mit Ihren Angaben übereinstimmen. Das Unternehmen muss kein Standort in Ihrem Konto sein. Diese Anleitung erstellt einen Scan, wartet auf seinen Abschluss und liest die Ergebnisse aus.

Verwenden Sie ihn, um:

  • die Einträge eines potenziellen Kunden vor dem Onboarding zu prüfen, damit das erste Gespräch bei fehlenden oder fehlerhaften Einträgen ansetzt;
  • die Präsenz eines Kunden und die Konsistenz seiner NAP-Daten (Name, Adresse, Telefonnummer) vor und nach der Korrektur seiner Einträge zu prüfen;
  • einem KI-Agenten zu ermöglichen, die Frage „Wie ist dieses Unternehmen eingetragen?“ zu beantworten, ohne das Unternehmen zum Konto hinzuzufügen.

1. Scan erstellen

POST /listings/scans nimmt die Unternehmensdaten als einzelnes input-Objekt entgegen und gibt sofort den Scan im Status QUEUED zurück. Die Verzeichnisse werden im Hintergrund geprüft.

FeldErforderlichHinweise
nameJaBis zu 150 Zeichen.
streetJaBis zu 200 Zeichen.
cityJaBis zu 100 Zeichen.
stateIsoJa, außer bei GBCode des Bundesstaats oder der Provinz, bis zu 50 Zeichen.
postalCodeJa, außer bei NG und AEBis zu 20 Zeichen.
countryIsoJaISO-3166-1-Code mit zwei Buchstaben, zum Beispiel US.
phoneJa6 bis 15 Ziffern. Lokale Formate werden im Kontext von countryIso interpretiert; ein vorangestelltes + wird ebenfalls unterstützt.
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

Die Antwort enthält den Scan, wobei phone auf das internationale Format normalisiert ist. results bleibt leer, bis Verzeichnisse geprüft wurden. Bewahren Sie daher id auf.

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": []    }  }}

Die Antwort enthält außerdem ein quota-Objekt, das unter Kosten, Limits und Fehler beschrieben wird.

Prüfen Sie zwei Dinge, bevor Sie fortfahren:

  • reused. Wenn Sie einen Scan für ein Unternehmen anfordern, das Sie in den letzten 7 Tagen gescannt haben, gibt listingsAPI diesen Scan mit reused: true und seinem aktuellen Status, in der Regel COMPLETED, zurück, statt einen neuen zu starten. Ihr Kontingent wird nicht belastet, und es wird kein neuer Webhook dafür gesendet.
  • errors. Auch bei einer abgelehnten Anfrage wird der HTTP-Status 200 zurückgegeben. Die Ablehnung steht in data.createListingScan.errors, und scan ist null. Bei einer zu kurzen Telefonnummer sieht das so aus:
JSON
{  "data": {    "createListingScan": {      "reused": false,      "scan": null,      "errors": [        {          "code": "SY83003",          "message": "SY83003: Invalid value for phone",          "contextInfo": [            {              "key": "field",              "value": "phone"            }          ]        }      ]    }  }}

contextInfo nennt das Feld, bei dem die Prüfung fehlgeschlagen ist. Die weiteren möglichen Codes finden Sie in der Fehlertabelle.

2. Auf die Ergebnisse warten

Ein Scan wechselt von QUEUED über IN_PROGRESS zu COMPLETED oder FAILED. Die meisten Scans sind innerhalb von 1 bis 7 Minuten abgeschlossen. Wenn ein Verzeichnis nach etwa 15 Minuten nicht geantwortet hat, wird sein Ergebnis auf UNAVAILABLE gesetzt und der Scan mit den übrigen Ergebnissen abgeschlossen. Verwenden Sie nach Möglichkeit einen Webhook und fragen Sie den Status nur ersatzweise regelmäßig ab.

Wenn der Scan einen Endstatus erreicht, sendet listingsAPI ein listing_scan.completed- oder listing_scan.failed-Ereignis an Ihre Webhook-URL. Sein data.scan ist dasselbe Objekt, das GET zurückgibt, einschließlich der Ergebnisse, sodass Sie anschließend nichts mehr abrufen müssen.

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": [ "..." ]    }  }}

Die Nutzdaten sind hier gekürzt; das vollständige Beispiel finden Sie in der Ereignisreferenz. Ereignisse werden wie alle anderen Ereignisse signiert und zugestellt, mit einem Versuch und einem Zeitlimit von 5 Sekunden. Prüfen Sie daher die Signatur, speichern Sie den unveränderten Anfrageinhalt und bestätigen Sie den Empfang, bevor Sie weitere Schritte ausführen. Der Empfänger unter Mit Webhooks auf Ereignisse reagieren erledigt dies bereits; die einzige Änderung ist ein zusätzlicher Zweig für event.

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

Ein Ereignis wird nur an Konten gesendet, bei denen Webhooks aktiviert sind und eine verifizierte URL vorliegt. Wenn dies bei Ihrem Konto nicht der Fall ist oder ein Ereignis nie eintrifft, fragen Sie den Scan regelmäßig ab; der Scan wird in jedem Fall 90 Tage lang aufbewahrt. Einzelheiten zur Signierung finden Sie unter Signaturen und Verifizierung.

2b. Regelmäßige Abfragen als Ausweichlösung

GET /listings/scans/{scanId} gibt den Scan mit allen bisher verfügbaren Ergebnissen zurück. Während der Scan läuft, wird results ergänzt, sobald Verzeichnisse antworten, und summary.pending zählt die Verzeichnisse, deren Antworten noch ausstehen. Fragen Sie alle 15 Sekunden ab und nicht häufiger; jede Anfrage zählt für Ihr Ratenlimit.

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
statusBedeutung
QUEUEDAngenommen und wartet auf den Start.
IN_PROGRESSDie Verzeichnisse werden geprüft. results ist unvollständig.
COMPLETEDFür jedes Verzeichnis liegt eine Antwort vor. results und summary sind endgültig.
FAILEDDer Scan konnte nicht gestartet werden, beispielsweise weil der Dienst vorübergehend nicht verfügbar war (SY83010). failure enthält code und message, und results ist leer. Ein fehlgeschlagener Scan wird nicht auf Ihr Kontingent angerechnet, sodass Sie ihn erneut erstellen können.

Ein Scan, dessen Ergebnisse aus einem kürzlich durchgeführten Scan oder einem Ihrer eigenen Standorte stammen, ist bereits bei seiner Erstellung COMPLETED, sodass ein einzelner GET ausreicht.

3. Ergebnisse lesen

Ein abgeschlossener Scan enthält einen summary und für jedes geprüfte Verzeichnis einen Eintrag in results, je nach Land bis zu etwa 60. business gibt die von Ihnen gesendeten Eingabedaten zurück, wobei phone auf das internationale Format normalisiert ist.

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

total ist die Anzahl der Verzeichnisse. found gibt an, wie viele Verzeichnisse das Unternehmen aufführen, und setzt sich aus accurate, inaccurate und etwaigen unten beschriebenen Einträgen zusammen, bei denen nur das Vorhandensein bestätigt wird. notFound gibt an, wie viele Verzeichnisse das Unternehmen nicht aufführen. unavailable zählt die Verzeichnisse, die diesmal nicht geprüft werden konnten, und pending ist nur während des laufenden Scans ungleich 0.

Jedes Ergebnis enthält einen status für das Verzeichnis:

Ergebnis statusBedeutung
FOUNDDas Verzeichnis führt das Unternehmen auf. listing enthält die dort angezeigten Angaben.
NOT_FOUNDDas Verzeichnis wurde geprüft und das Unternehmen ist dort nicht eingetragen.
UNAVAILABLEDas Verzeichnis konnte diesmal nicht geprüft werden. Das bedeutet nicht, dass kein Eintrag vorhanden ist; melden Sie dies daher nicht als fehlenden Eintrag. Prüfen Sie dieses Verzeichnis später erneut.
PENDINGNoch nicht geprüft. Wird nur angezeigt, während der Scan läuft.

Bei einem Ergebnis mit FOUND gibt accurate an, ob der Eintrag mit Ihren Eingabedaten übereinstimmt:

  • true bedeutet, dass Name, Adresse und Telefonnummer übereinstimmen.
  • false bedeutet, dass mindestens eines dieser Felder nicht übereinstimmt. Ein im Eintrag fehlendes Feld gilt als Abweichung, sodass ein Eintrag ohne Telefonnummer false ist.
  • null bedeutet, dass das Unternehmen gefunden wurde, aber kein Abgleich der einzelnen Felder stattgefunden hat.

accuracy erläutert das Prüfergebnis mit einem status und einem message für jedes der Felder name, address und phone. status ist ACCURATE, INACCURATE oder MISSING, und message ist null, wenn das Feld korrekt ist. Hier ist eine Facebook-Seite, bei der Name und Adresse übereinstimmen, aber die Telefonnummer fehlt:

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}

Einige Verzeichnisse bestätigen lediglich, dass das Unternehmen existiert, und zeigen nicht genügend Angaben für einen Vergleich an. Für diese wird FOUND mit accurate: null zurückgegeben, und sie werden nur in found gezählt, nicht in accurate oder inaccurate. Behandeln Sie diese Einträge als vorhanden, nicht als verifiziert:

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}

Ein Ergebnis mit NOT_FOUND enthält weder listing noch 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}

Mehrere Verzeichnisse speichern keine eigenen Daten. Uber, Waze und Lyft zeigen Daten von Google Maps an, und Copilot zeigt Daten von Bing an. Ihre Ergebnisse entsprechen denen des Quellverzeichnisses, sodass sie in der Regel wiedergeben, was Google Maps oder Bing zurückgegeben hat, und sie enthalten keinen url für den Eintrag. Zählen Sie sie als separate Einträge in summary, werten Sie sie aber nicht als unabhängige Bestätigung:

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}

KI-Assistenten wie ChatGPT und Gemini sind ebenfalls enthalten. Bei ihnen zeigt listing, was der Assistent über das Unternehmen weiß, häufig nur einen Namen, eine vollständige Adresse und eine Telefonnummer, und es gibt keinen accuracy für die einzelnen Felder.

Um aus einem abgeschlossenen Scan eine Liste der nötigen Korrekturen zu erstellen, geben Sie jedes Verzeichnis mit einem falschen oder fehlenden Feld aus:

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)'

Für den Scan von Joe's Pizza werden dadurch zwei Zeilen ausgegeben: Bei Facebook fehlt die Telefonnummer, und Judys Book zeigt eine abweichende Telefonnummer an.

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

Woher die Ergebnisse stammen

source gibt an, wie die Scan-Anfrage beantwortet wurde, und resultsAsOf gibt an, wann die Daten erfasst wurden.

sourceBedeutung
DIRECTORY_SEARCHEine neue Suche in den Verzeichnissen. resultsAsOf gibt an, wann dieser Scan abgeschlossen wurde.
RECENT_SCANEine Kopie eines Scans desselben Unternehmens, den ein beliebiger Nutzer in den letzten sieben Tagen durchgeführt hat. Dieser Vorgang wird sofort abgeschlossen, und resultsAsOf gibt an, wann die ursprünglichen Daten erfasst wurden, sodass dieser Zeitpunkt vor createdAt liegen kann.
LOCATION_LISTINGSDas Unternehmen wurde anhand von Telefonnummer, Postleitzahl und Land einem Ihrer eigenen Standorte zugeordnet, daher stammen die Ergebnisse aus den tatsächlichen Einträgen dieses Standorts. locationId ist gesetzt, accuracySource ist SYNC_STATUS statt DIRECTORY_MATCH, und jedes Ergebnis enthält syncStatus des jeweiligen Eintrags.

Kosten, Limits und Fehler

Nur ein neu durchgeführter DIRECTORY_SEARCH-Scan wird auf Ihr monatliches Kontingent angerechnet, das von Ihrem Tarif abhängt und mit Ihrem Abrechnungszeitraum zurückgesetzt wird. Folgendes ist kostenlos:

  • die Wiederholung eines Scans desselben Unternehmens innerhalb von sieben Tagen. Ihr eigener früherer Scan wird mit reused: true zurückgegeben;
  • ein Scan, dessen Anfrage durch einen kürzlich durchgeführten Scan desselben Unternehmens aus einem beliebigen Konto beantwortet werden kann. Dabei handelt es sich um eine RECENT_SCAN-Kopie;
  • Scans, die einem Ihrer eigenen Standorte zugeordnet werden (LOCATION_LISTINGS);
  • Scans, die mit FAILED enden und deren Verbrauch dem Kontingent wieder gutgeschrieben wird.

Scans werden 90 Tage lang aufbewahrt. Danach gibt GET den Wert 404 mit SY83005 zurück.

Die Antworten von Create und List enthalten ein quota-Objekt, damit Sie Ihren aktuellen Kontingentstand prüfen können, bevor Sie eine Reihe von Scans starten. List gibt Ihre Scans mit den neuesten zuerst zurück, auf Seiten mit jeweils 1 bis 50 Scans, mit perPage und ohne 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'
Feld in quotaBedeutung
limitNeu durchgeführte Scans, die Ihr Tarif im aktuellen Zeitraum zulässt.
usedBisher verbrauchte neu durchgeführte Scans.
remaininglimit minus used, niemals unter null.
resetsAtZeitpunkt, zu dem das Kontingent zurückgesetzt wird.

Diese Fehler treten am häufigsten auf. Create gibt seine Fehler im Antworttext mit HTTP 200 zurück; Get und List geben den üblichen HTTP-Status zurück.

CodeWoBedeutung und Behebung
SY83002CreateDas monatliche Kontingent ist aufgebraucht. Die Meldung enthält das Limit und den Zeitpunkt der Zurücksetzung, und quota wird zurückgegeben. Warten Sie bis resetsAt oder verwenden Sie einen Scan aus den letzten sieben Tagen erneut, was kostenlos ist.
SY83003Create oder failure eines ScansEin Wert fehlt oder ist ungültig. contextInfo gibt das Feld an. Korrigieren Sie die Eingabe und senden Sie sie erneut.
SY83004CreateListings scans sind für diesen Wert von countryIso nicht verfügbar.
SY83001CreateIhr Tarif umfasst keine listings scans.
SY83005GetEs gibt keinen Scan mit dieser id, oder der Scan gehört zu einem anderen Konto oder ist älter als 90 Tage. HTTP 404.
SY83010Create oder failure eines ScansScans sind vorübergehend nicht verfügbar. Versuchen Sie es später erneut.
SY90016CreateDer Schlüssel erlaubt nur Lesezugriffe. Verwenden Sie einen Write-Schlüssel.

Ein GET für eine nicht vorhandene id gibt Folgendes zurück:

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

Bei einem Scan, der mit FAILED endet, steht der Grund in failure, und results bleibt leer:

JSON
{  "status": "FAILED",  "failure": {    "code": "SY83010",    "message": "SY83010: Listing scans are temporarily unavailable, try again later",    "field": null  }}

Das allgemeine Fehlerformat finden Sie unter Fehlercodes.

Für KI-Agenten

Der gehostete MCP-Server stellt diese Funktion über drei Tools bereit: listings_scans_create, listings_scans_get und listings_scans_list. Ein Assistent kann einen Scan für ein vom Nutzer genanntes Unternehmen starten, dessen Status mit listings_scans_get wiederholt abfragen und die Verzeichnisse zusammenfassen, bei denen Handlungsbedarf besteht. Wie bei REST ist zum Erstellen eines Scans ein Write-Schlüssel erforderlich. Die Einrichtung ist unter KI-Agenten mit listingsAPI MCP verbinden beschrieben.

Nächste Schritte