# Yext Alternative: Local Listing Audit (`khadinakbar/yext-alternative`) Actor

Audit a known business's public directory visibility and NAP evidence across a fixed directory set. Receive source links, observed match states, gaps, and a transparent coverage score for recurring local-listing monitoring.

- **URL**: https://apify.com/khadinakbar/yext-alternative.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** SEO tools, Automation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $250.00 / 1,000 completed listing audits

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Yext Alternative: Local Listing Audit

Audit the public directory visibility and NAP evidence for businesses you already know. For each supplied business, this Actor searches a fixed set of fifteen directory domains, records a source URL when a same-domain result is present, and labels each observable name, phone, address/city, and website signal as a match, mismatch, not observed, or not requested.

Use it for a recurring, source-linked audit of a known location list. Its focused role is public-evidence observation; use Yext for managed listing actions, publisher distribution, reviews, approvals, analytics, and knowledge-graph workflows.

### What you get

One complete dataset record per persisted audit, including:

| Field | Meaning |
| --- | --- |
| `directoriesFound` / `directoriesMissing` | Count of same-domain results found or not found in the inspected search result set. A missing result is not proof that no listing exists. |
| `directories[]` | One evidence record per directory with its query, source URL, snippet, and individual match states. |
| `directoriesWithObservedMismatch` | Directories where an available snippet signal disagreed with caller-provided canonical data. |
| `directoriesWithInsufficientEvidence` | Directories where a result was found but the search snippet did not expose enough information to assess every supplied signal. |
| `observedCitationHealthScore` | A transparent 0–100 coverage-and-evidence score, not a ranking, listing-ownership, sync, or visibility guarantee. |
| `sourceRunId` | The owned Google SERP sub-run used to discover directory evidence. |

### Quick start input

```json
{
  "businesses": [{
    "externalId": "location-001",
    "businessName": "Example Bakery",
    "phone": "+1 212 555 0100",
    "address": "123 Example Street",
    "city": "New York",
    "state": "NY",
    "website": "https://example.com"
  }],
  "country": "US",
  "maxBusinesses": 10
}
```

The Actor requires a name, a telephone number with at least seven digits, and a city. Give the canonical address and website whenever available; they let the output say exactly what was or was not observable.

### Output example

```json
{
  "externalId": "location-001",
  "businessName": "Example Bakery",
  "city": "New York",
  "directoriesChecked": 15,
  "directoriesFound": 9,
  "directoriesMissing": 6,
  "directoriesWithObservedMismatch": 1,
  "directoriesWithInsufficientEvidence": 4,
  "observedCitationHealthScore": 63,
  "directories": [{
    "directory": "yelp",
    "findingState": "found_with_complete_match_evidence",
    "listingUrl": "https://www.yelp.com/biz/example-bakery",
    "nameMatch": "match",
    "phoneMatch": "match"
  }],
  "source": "google_site_search_via_owned_serp_actor"
}
```

### How this bounded workflow compares with Yext

This independent Actor replaces one limited step: auditing public directory-discovery evidence for locations you already know, with a dataset you can schedule, export, or send to another workflow. Yext remains the appropriate choice for its managed, direct-publisher listing distribution, knowledge graph, reviews, role-based workflows, analytics, and listing-action controls.

| Decision | This Actor | Yext | Best fit |
| --- | --- | --- | --- |
| Scope | Public directory discovery and NAP-evidence audit for known locations | Managed listings, data, review, analytics, and enterprise workflows | Use this Actor for audit records; use Yext for managed publisher operations. |
| Starting point | Known business name, phone, and city | Organization/location data in the Yext platform | Use this Actor when you already maintain the location list. |
| Output | Source URL, search snippet, observed match state, explicit data gaps | Product-managed operational controls and publisher integrations | Use the Actor where auditable public evidence is enough. |
| Billing | $0.25 per persisted completed audit plus Apify platform usage | Yext's current pricing is sales-led; no public same-job price was verified for this dossier | Compare only an equivalent location count, directory coverage, and action scope. |
| Effective efficiency | One source-linked audit record per known location | Broader operational workflows | Compare accepted records and operator review minutes for the same location set. |
| Actions | Read-only; does not claim, create, update, sync, or suppress listings | Supports listings operations and connected publisher workflows | Choose Yext when a human or approved workflow must change publisher data. |

Yext is a trademark of its owner. This independent Actor is not affiliated with, associated with, or endorsed by Yext.

### How evidence is collected

For every business, the Actor makes one batched call to the owned `khadinakbar/scrape-google-serp` Actor. The call queries each fixed directory domain with a query like `site:yelp.com "Example Bakery" "New York"`. The Actor then keeps only organic results whose host is the checked directory and compares the available title/snippet against caller-provided canonical values.

The method intentionally reports `not_observed` when a result snippet does not expose a phone number, address, or website. It does not silently treat absent snippet text as a mismatch. Search indexes change, and a directory can hold a listing that does not surface in the inspected result set; use source URLs and a human review before claiming a business is absent or incorrect.

### Use through the API

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/yext-alternative').call({
  businesses: [{ businessName: 'Example Bakery', phone: '+1 212 555 0100', city: 'New York' }],
  country: 'US',
  maxBusinesses: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].directories);
```

### Use with AI agents through Apify MCP

> Audit the public directory evidence for the known locations in my CRM. Keep the external ID, show only observed mismatches and insufficient-evidence records, preserve source URLs, and recommend directory changes only after a human review.

Use the current client setup at [Apify MCP](https://mcp.apify.com). Ask the agent to inspect both the dataset and `OUTPUT` before interpreting a run. The terminal outcome records complete, partial, invalid-input, and upstream-result states.

### Pricing

This Actor uses **Pay per event** with platform usage passed through: **$0.25 per persisted completed audit**, plus Apify platform usage. A run that persists ten completed audits has $2.50 in audit events plus current platform usage. The event is coupled to the dataset write, so only persisted completed audits create the completed-audit event. Check the live Pricing tab after private deployment for current configuration and charge behavior.

### Best results

- Start with a clean canonical location list: official name, direct business phone, city, address, and website.
- Use the US directory set for US locations; other countries are available only for limited exploratory use in v0.1.
- Review a sample of source URLs before treating a directory gap or mismatch as an operational task.
- Schedule repeated runs when monitoring changes, while keeping the prior output as a dated observation rather than proof of continuous accuracy.

### Builder's note

I designed the match states around the weak point of directory audits: search snippets often omit a phone, address, or website. A missing snippet field is therefore reported as `not_observed`, while an available conflicting signal is reported as a mismatch. That keeps the output useful for a review queue without turning absent evidence into a false correction task.

### Focused standalone workflow

This Actor works as a focused standalone workflow for teams that maintain their own location list and want a source-linked audit before a human decides whether to investigate or update anything.

### Responsible use

Use public listing information only for locations you are authorized to audit. Respect search-engine and directory terms, privacy law, and any review or approval process before changing a listing.

# Actor input Schema

## `businesses` (type: `array`):

One to 50 business records you already know. Each needs businessName, phone, and city; address, state, website, and externalId improve matching and are returned as caller-provided context.

## `country` (type: `string`):

Google search country used for directory discovery. The v0.1 directory set is US-oriented; use another supported market only when its directories are relevant to your audit.

## `maxBusinesses` (type: `integer`):

Hard cap for businesses processed in this run. Defaults to 10, accepts 1 to 50, and limits event charges to $0.25 per completed audit plus Apify platform usage.

## Actor input object example

```json
{
  "businesses": [
    {
      "businessName": "Example Bakery",
      "phone": "+1 212 555 0100",
      "address": "123 Example Street",
      "city": "New York",
      "state": "NY",
      "website": "https://example.com",
      "externalId": "location-001"
    }
  ],
  "country": "US",
  "maxBusinesses": 10
}
```

# Actor output Schema

## `audits` (type: `string`):

One complete source-linked audit record for every persisted business.

## `compactOutput` (type: `string`):

Stable terminal outcome, counts, warnings, and charge-event counts.

## `runSummary` (type: `string`):

Detailed terminal diagnostics including input validation, source-run status, and charge-event counts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "businesses": [
        {
            "businessName": "Example Bakery",
            "phone": "+1 212 555 0100",
            "address": "123 Example Street",
            "city": "New York",
            "state": "NY",
            "website": "https://example.com",
            "externalId": "location-001"
        }
    ],
    "country": "US",
    "maxBusinesses": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/yext-alternative").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "businesses": [{
            "businessName": "Example Bakery",
            "phone": "+1 212 555 0100",
            "address": "123 Example Street",
            "city": "New York",
            "state": "NY",
            "website": "https://example.com",
            "externalId": "location-001",
        }],
    "country": "US",
    "maxBusinesses": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/yext-alternative").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "businesses": [
    {
      "businessName": "Example Bakery",
      "phone": "+1 212 555 0100",
      "address": "123 Example Street",
      "city": "New York",
      "state": "NY",
      "website": "https://example.com",
      "externalId": "location-001"
    }
  ],
  "country": "US",
  "maxBusinesses": 10
}' |
apify call khadinakbar/yext-alternative --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/yext-alternative"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tNfYw3ji6hdtmS3I4/builds/vGKzhe2sl7kjXv4jX/openapi.json
