Audite listagens de uma empresa com um listings scan
Confira empresas em mapas, buscas, diretórios e assistentes de IA: precisão de nome, endereço e telefone por diretório e resultados via webhook ou polling.
Um listings scan verifica como uma empresa está listada na rede de diretórios listingsAPI e informa, diretório por diretório, se ela foi encontrada e se o nome, o endereço e o telefone correspondem aos dados que você forneceu. A empresa não precisa ser um local na sua conta. Este guia cria uma varredura, aguarda sua conclusão e lê os resultados.
Use para:
- auditar um cliente em potencial antes de cadastrá-lo, para que a primeira conversa comece pelas listagens ausentes ou incorretas;
- verificar a presença de um cliente e a consistência do NAP (nome, endereço e telefone) antes e depois de corrigir suas listagens;
- permitir que um agente de IA responda à pergunta "como esta empresa está listada?" sem adicionar a empresa à conta.
1. Crie a varredura
POST /listings/scans recebe os dados da empresa em um único objeto input e retorna imediatamente com a varredura em QUEUED. Os diretórios são verificados em segundo plano.
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"}}JSONA resposta retorna a varredura, com phone normalizado para o formato internacional. results fica vazio até que os diretórios sejam verificados, então guarde o 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": [] } }}A resposta também inclui um objeto quota, descrito em Custos, limites e erros.
Verifique 2 pontos antes de continuar:
reused. Quando você solicita uma varredura de uma empresa que já verificou nos últimos 7 dias, listingsAPI retorna essa varredura em vez de iniciar uma nova, comreused: truee seu status atual, geralmenteCOMPLETED. Nada é descontado da sua cota, e nenhum novo webhook é enviado para essa varredura.errors. Uma solicitação rejeitada ainda retorna HTTP200. A rejeição está emdata.createListingScan.errors, escanénull. Um número de telefone curto demais gera uma resposta como esta:
{ "data": { "createListingScan": { "reused": false, "scan": null, "errors": [ { "code": "SY83003", "message": "SY83003: Invalid value for phone", "contextInfo": [ { "key": "field", "value": "phone" } ] } ] } }}contextInfo indica o campo que falhou. Os outros códigos que você pode receber estão na tabela de erros.
2. Aguarde os resultados
Uma varredura passa de QUEUED para IN_PROGRESS e depois para COMPLETED ou FAILED. A maioria termina em 1 a 7 minutos. Se um diretório não responder após cerca de 15 minutos, seu resultado será definido como UNAVAILABLE, e a varredura será concluída com os demais resultados. Use um webhook se puder e faça consultas periódicas apenas como alternativa.
2a. Receba o webhook (recomendado)
Quando a varredura atinge um estado final, listingsAPI envia um evento listing_scan.completed ou listing_scan.failed para a URL do seu webhook. O data.scan do evento é o mesmo objeto retornado por GET, incluindo os resultados, portanto não há nada a buscar depois.
{ "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": [ "..." ] } }}O corpo do evento está abreviado aqui; o exemplo completo está na referência de eventos. Os eventos são assinados e entregues como qualquer outro evento, com 1 tentativa e um limite de 5 segundos, portanto verifique a assinatura, armazene o corpo bruto e confirme o recebimento antes de fazer qualquer outra coisa. O receptor em Reagir a eventos com webhooks já faz isso; a única alteração é mais uma condição para 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}, 200Um evento é enviado apenas para contas com webhooks habilitados e uma URL verificada. Se a sua conta não atender a essas condições, ou se um evento nunca chegar, consulte a varredura periodicamente; ela é mantida por 90 dias em qualquer caso. Os detalhes sobre a assinatura estão em Assinaturas e verificação.
2b. Faça consultas periódicas como alternativa
GET /listings/scans/{scanId} retorna a varredura com os resultados disponíveis até o momento. Durante a execução da varredura, results é preenchido conforme os diretórios respondem, e summary.pending conta os que ainda estão pendentes. Faça consultas a cada 15 segundos, nunca em intervalos menores; cada solicitação conta para o seu limite de requisições.
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 15doneUma varredura respondida com dados de uma varredura recente ou de um dos seus próprios locais já está em COMPLETED no momento em que é criada, então basta um único GET.
3. Leia os resultados
Uma varredura concluída tem um summary e uma entrada em results para cada diretório verificado, até cerca de 60, dependendo do país. business retorna os dados de entrada que você enviou, com phone normalizado para o formato internacional.
{ "total": 62, "found": 21, "accurate": 18, "inaccurate": 2, "notFound": 41, "pending": 0, "unavailable": 0}total é o número de diretórios. found indica quantos têm uma listagem da empresa e se divide em accurate, inaccurate e quaisquer listagens que apenas confirmam a presença, descritas abaixo. notFound indica quantos não têm uma listagem da empresa. unavailable conta os diretórios que não puderam ser verificados desta vez, e pending só é diferente de zero enquanto a varredura está em execução.
Cada resultado tem um status para o diretório:
Para um resultado FOUND, accurate indica se a listagem corresponde aos dados de entrada:
truesignifica que nome, endereço e telefone correspondem aos dados de entrada.falsesignifica que pelo menos um deles não corresponde. Um campo omitido na listagem conta como uma divergência, então uma listagem sem número de telefone éfalse.nullsignifica que a empresa foi encontrada, mas não houve uma verificação campo a campo.
accuracy explica a conclusão com um status e um message para cada um dos campos name, address e phone. O valor de status é ACCURATE, INACCURATE ou MISSING, e message é null quando o campo está correto. Veja uma página do Facebook cujo nome e endereço correspondem aos dados de entrada, mas que não tem número de telefone:
{ "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}Alguns diretórios apenas confirmam que a empresa existe e não mostram detalhes suficientes para uma comparação. Os resultados desses diretórios retornam como FOUND com accurate: null e são contabilizados apenas em found, não em accurate nem em inaccurate. Considere essas listagens como presentes, não como verificadas:
{ "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}Um resultado NOT_FOUND não tem listing nem accuracy:
{ "directory": { "id": 352, "name": "YellowPages", "url": "www.yellowpages.com" }, "status": "NOT_FOUND", "accurate": null, "accuracySource": "DIRECTORY_MATCH", "accuracy": null, "listing": null, "syncStatus": null}Vários diretórios não mantêm dados próprios. Uber, Waze e Lyft mostram dados do Google Maps, e Copilot mostra dados do Bing. Seus resultados refletem os do diretório de origem, então geralmente repetem o que o Google Maps ou o Bing retornou e não têm url da listagem. Conte esses resultados como entradas separadas em summary, mas não os interprete como confirmações independentes:
{ "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}Assistentes de IA como ChatGPT e Gemini também estão incluídos. Para eles, listing mostra o que o assistente sabe sobre a empresa, o que muitas vezes se resume a um nome, um endereço completo e um número de telefone, e não há accuracy por campo.
Para transformar uma varredura concluída em uma lista de correções, imprima cada diretório que tenha um campo incorreto ou ausente:
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)'Para a varredura da Joe's Pizza, isso imprime duas linhas: o Facebook não tem número de telefone, e Judys Book mostra um número diferente.
Facebook phone: No phone number on the listingJudys Book phone: Phone number does not matchDe onde vêm os resultados
source informa como o resultado da varredura foi obtido, e resultsAsOf indica quando os dados foram coletados.
Custos, limites e erros
Somente uma nova varredura DIRECTORY_SEARCH consome sua cota mensal, que depende do seu plano e é renovada a cada período de faturamento. Estas operações são gratuitas:
- repetir uma varredura da mesma empresa dentro de 7 dias. Sua própria varredura anterior é retornada com
reused: true; - uma varredura cujo resultado pode ser obtido de uma varredura recente da mesma empresa, realizada por qualquer conta. Ela é uma cópia
RECENT_SCAN; - varreduras que correspondem a um dos seus próprios locais (
LOCATION_LISTINGS); - varreduras que terminam com
FAILED, cujo consumo da cota é estornado.
As varreduras são mantidas por 90 dias. Depois disso, GET retorna 404 com SY83005.
As respostas de criação e listagem incluem um objeto quota, para que você possa verificar o uso da sua cota antes de iniciar um lote. A operação de listagem retorna suas varreduras da mais recente para a mais antiga, em páginas de 1 a 50 resultados com perPage, sem results.
curl -s "https://listingsapi.com/api/v4/listings/scans?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY" \| jq '.data.listingScans.quota'Estes são os erros que você verá com mais frequência. A operação de criação retorna seus erros no corpo da resposta com HTTP 200; as operações de obtenção e listagem retornam o status HTTP habitual.
Uma chamada GET para um id que não existe retorna:
{ "data": { "listingScan": null }, "errors": [ { "message": "SY83005: Listing scan not found" } ]}Uma varredura que termina com FAILED tem o motivo registrado em failure, e results permanece vazio:
{ "status": "FAILED", "failure": { "code": "SY83010", "message": "SY83010: Listing scans are temporarily unavailable, try again later", "field": null }}O formato geral dos erros está em Códigos de erro.
Para agentes de IA
O servidor MCP hospedado disponibiliza esse recurso por meio de três ferramentas: listings_scans_create, listings_scans_get e listings_scans_list. Um assistente pode iniciar uma varredura para uma empresa indicada pelo usuário, consultá-la periodicamente com listings_scans_get e resumir os diretórios que precisam de atenção. Assim como em REST, criar uma varredura exige uma chave Write. As instruções de configuração estão em Conectar agentes de IA ao MCP do listingsAPI.
Próximas etapas
- Reagir a eventos com webhooks: o receptor ao qual os eventos da varredura são enviados.
- Verificar o status das listagens e os links ativos e Encontrar e corrigir erros nas listagens: depois que uma empresa se tornar um local na sua conta, acompanhe e corrija suas listagens.
- Adicionar um local: cadastre a empresa que você auditou.
- Referência: Criar um listings scan, Obter um listings scan, Listar listings scans, Referência de eventos, Códigos de erro.