POST/api/v4/listings/scans

Crear un listings scan

Inicia una auditoría de cómo figura cualquier negocio en la red de directorios y devuelve el escaneo al instante para esperar el webhook de finalización.

Requiere una clave de API. Consulta Autenticación para conocer el formato del encabezado y la rotación de claves.

Parámetros

Cuerpo

NombreTipoObligatorioDescripción
inputobjectobligatorioWrapper object. The entire request body must be nested under `input`.
input.namestringobligatorioBusiness name, up to 150 characters.
input.streetstringobligatorioStreet address, up to 200 characters.
input.citystringobligatorioCity, up to 100 characters.
input.stateIsostringopcionalState or province code, up to 50 characters. Required for every country except `GB`.
input.postalCodestringopcionalPostal code, up to 20 characters. Required for every country except `NG` and `AE`.
input.countryIsostringobligatorioTwo-letter ISO 3166-1 country code, for example `US`.
input.phonestringobligatorioBusiness phone number with 6 to 15 digits. Local formats are read in the context of `countryIso`, and an international format with a leading `+` works too.

Solicitud de ejemplo

Cuerpo listo para pegar. Sustituye los ID y valores de ejemplo por los tuyos.

Request body
{  "input": {    "name": "Franklin Barbecue",    "street": "900 E 11th St",    "city": "Austin",    "stateIso": "TX",    "postalCode": "78702",    "countryIso": "US",    "phone": "+15126531187"  }}

Respuestas

200The scan was accepted and is `QUEUED`. `reused` is `false` and `results` is empty until directories are checked. Wait for the `listing_scan.completed` webhook, or poll the scan.
Response
{  "data": {    "createListingScan": {      "reused": false,      "scan": {        "id": "TGlzdGluZ1NjYW46N2MxZTRmNTItOWEzYi00ZDY4LWIwZTEtNWYyYThjOWQzZTQ3",        "status": "QUEUED",        "source": "DIRECTORY_SEARCH",        "locationId": null,        "resultsAsOf": null,        "createdAt": "2026-11-05T07:00:41Z",        "startedAt": null,        "completedAt": null,        "business": {          "name": "Franklin Barbecue",          "street": "900 E 11th St",          "city": "Austin",          "stateIso": "TX",          "postalCode": "78702",          "countryIso": "US",          "phone": "+15126531187"        },        "summary": {          "total": 0,          "found": 0,          "accurate": 0,          "inaccurate": 0,          "notFound": 0,          "pending": 0,          "unavailable": 0        },        "failure": null,        "results": []      },      "quota": {        "limit": 50,        "used": 6,        "remaining": 44,        "resetsAt": "2026-11-23T12:38:03Z"      },      "errors": []    }  }}
200The request was rejected, so **no scan was created**. The error is reported in `errors[]` on an `HTTP 200`, `scan` is `null`, and `quota` still returns the current allowance. This example is a phone number with too few digits.
Response
{  "data": {    "createListingScan": {      "reused": false,      "scan": null,      "quota": {        "limit": 50,        "used": 5,        "remaining": 45,        "resetsAt": "2026-11-23T12:38:03Z"      },      "errors": [        {          "code": "SY83003",          "message": "SY83003: Invalid value for phone",          "contextInfo": [            {              "key": "field",              "value": "phone"            }          ]        }      ]    }  }}
400A read-only key was used on this write (`SY90016`). Use a Write key.
401Unauthenticated, missing or invalid API key.
429Rate limit exceeded. Retry after the `Retry-After` header value.

Inicia un escaneo de un negocio. El escaneo comprueba si el negocio aparece en la red de directorios y con qué precisión: mapas y motores de búsqueda como Google, Bing, Apple Maps, Yelp, Facebook y MapQuest, agregadores de datos y directorios locales, y asistentes de IA como ChatGPT y Gemini. Según el país, un escaneo comprueba hasta unos 60 directorios. El negocio no tiene que ser una ubicación de tu cuenta, por lo que puedes auditar a un cliente potencial o a un cliente antes de incorporarlo.

La llamada devuelve de inmediato el escaneo con el estado QUEUED. Las comprobaciones de los directorios se ejecutan en segundo plano y el resultado se consulta con GET /listings/scans/{scanId}.

Caso de uso: auditoría de fichas de un cliente potencial. Tu herramienta de ventas recopila el nombre, la dirección y el número de teléfono de un negocio. Crea un escaneo, guarda el scan.id devuelto y consulta el escaneo finalizado en data.scan cuando llegue el evento listing_scan.completed. summary proporciona el resumen (cuántos directorios encontraron el negocio y cuántos de ellos tienen datos correctos), y results[] proporciona el detalle por directorio para mostrarlo en el informe.

Caso de uso: comprobación del estado de un negocio que ya gestionas. Escanea los datos del negocio de una de tus propias ubicaciones. El escaneo lo reconoce y genera los resultados a partir de las fichas reales de esa ubicación en lugar de volver a buscar (consulta Reutilización y escaneos gratuitos).

Cómo finaliza un escaneo

Un escaneo pasa por QUEUED y IN_PROGRESS, y después termina con el estado COMPLETED o FAILED. La mayoría de los escaneos se completan en un plazo de 1 a 7 minutos. Si un directorio no ha respondido después de unos 15 minutos, su resultado se establece en UNAVAILABLE y el escaneo se completa con los demás resultados.

  • Usa el webhook como opción preferente. Los eventos listing_scan.completed y listing_scan.failed se entregan una vez por escaneo, con el mismo objeto de escaneo que devuelve GET /listings/scans/{scanId}, incluidos los resultados. Se envían a las cuentas que tienen los webhooks habilitados y una URL de webhook verificada, y se firman como cualquier otro evento. Consulta listing_scan.completed.
  • Usa consultas periódicas como alternativa. Si no puedes recibir webhooks, consulta el escaneo cada 15 segundos hasta que status sea COMPLETED o FAILED. Consultarlo con más frecuencia no aporta nada y consume tu cupo de solicitudes.

Campos obligatorios

name, street, city, countryIso y phone son siempre obligatorios. Dos campos dependen del país:

CampoObligatorioExcepciones
stateIsoSíNo es obligatorio para GB.
postalCodeSíNo es obligatorio para NG y AE.

Un valor ausente o con un formato incorrecto se rechaza con SY83003, y el error indica el nombre del campo. phone debe tener entre 6 y 15 dígitos, y countryIso debe constar de dos letras.

Reutilización y escaneos gratuitos

Un escaneo no siempre realiza una búsqueda nueva. El campo source del escaneo devuelto indica de dónde proceden sus resultados:

sourceCuándo se obtiene
DIRECTORY_SEARCHUna búsqueda nueva en los directorios. Es el único tipo que consume tu cupo mensual.
RECENT_SCANAlguien escaneó el mismo negocio en los últimos 7 días, por lo que se copiaron sus resultados. resultsAsOf indica cuándo se recopilaron los datos. Se devuelve ya con el estado COMPLETED.
LOCATION_LISTINGSEl negocio coincide con una de tus propias ubicaciones por número de teléfono, código postal y país. Los resultados proceden de las fichas reales de esa ubicación, se establece locationId y cada resultado incluye un syncStatus.

Si vuelves a escanear el mismo negocio en un plazo de 7 días, se devuelve el escaneo existente de tu cuenta en lugar de uno nuevo, con reused: true en la respuesta. No se inicia ningún escaneo nuevo ni se envía ningún webhook nuevo, así que consulta el escaneo devuelto (puede que aún esté en curso) en lugar de esperar otro evento. Volver a escanear una de tus propias ubicaciones dentro del periodo de reutilización funciona de la misma manera.

Cupo mensual

Los Listings scans se incluyen en los planes de pago con un cupo mensual que depende de tu plan. No están disponibles con un pase de un día gratuito para el entorno de pruebas. Solo un escaneo DIRECTORY_SEARCH nuevo consume el cupo. Los siguientes son gratuitos:

  • una repetición para el mismo negocio en un plazo de 7 días (reused: true),
  • una copia RECENT_SCAN,
  • un escaneo LOCATION_LISTINGS,
  • un escaneo que falla, que no se contabiliza.

El cupo se restablece con el periodo de facturación de tu cuenta. Cada respuesta a una solicitud de creación incluye quota con limit, used, remaining y resetsAt, incluso cuando se rechaza la solicitud. Consulta Planes y complementos.

Errores

Una solicitud de creación rechazada devuelve HTTP 200 con scan: null y el motivo en errors[], así que comprueba errors y no solo el código de estado. Las claves de solo lectura no pueden crear escaneos: ese es el único fallo a nivel de solicitud, que devuelve HTTP 400 con SY90016.

CódigoSignificadoQué hacer
SY83001Los Listings scans no están disponibles en tu plan.Usa una cuenta con un plan de pago. Los pases de un día no permiten ejecutar escaneos.
SY83002Se ha agotado el cupo mensual. El mensaje incluye el límite y el momento del restablecimiento, y se devuelve quota.Espera hasta quota.resetsAt o ponte en contacto con nosotros para solicitar un cupo mayor. Reutilizar un escaneo reciente es gratuito.
SY83003Falta un campo o su valor no es válido. contextInfo lo identifica en field.Corrige ese campo y vuelve a enviar la solicitud.
SY83004Los escaneos no están disponibles para ese país.Comprueba countryIso. El mensaje indica el código que se ha rechazado.
SY83010Los escaneos no están disponibles temporalmente.Vuelve a intentarlo más tarde.

La lista completa de códigos está en Códigos de error.

Notas.

  • El cuerpo de la solicitud debe estar contenido en un objeto input.
  • Comprueba errors, no el estado HTTP. Una solicitud de creación rechazada devuelve HTTP 200.
  • Los números de teléfono se normalizan antes de ejecutar el escaneo, y dos solicitudes que solo difieren en el formato, las mayúsculas y minúsculas o los espacios se consideran del mismo negocio.
  • Cada solicitud de creación consume una solicitud de tu límite de solicitudes, independientemente de cuántos directorios compruebe el escaneo.
  • Un escaneo se conserva durante 90 días. Después de ese plazo, su lectura devuelve 404 con SY83005.
  • Esta llamada requiere una clave Write (escritura).
Request
curl -X POST 'https://listingsapi.com/api/v4/listings/scans' \  -H "Authorization: API $LISTINGSAPI_KEY" \  -H 'Content-Type: application/json' \  -d '{    "input": {      "name": "Franklin Barbecue",      "street": "900 E 11th St",      "city": "Austin",      "stateIso": "TX",      "postalCode": "78702",      "countryIso": "US",      "phone": "+15126531187"    }  }'