# Local SEO Audit for Small Businesses (AI Agent Ready) (`hereditary_model/local-seo-audit`) Actor

Audits a business website and returns on page SEO, technical health, local SEO signals (NAP, LocalBusiness schema, map embed), 0 to 100 scores, and a prioritized fix list. Pay per event.

- **URL**: https://apify.com/hereditary\_model/local-seo-audit.md
- **Developed by:** [Aaron Marxsen](https://apify.com/hereditary_model) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Local SEO Audit for Small Businesses (AI Agent Ready)

Audits a business website and returns a structured local SEO report: on page factors, technical health, local signals (NAP consistency, LocalBusiness schema, map embed, city keywords), a 0 to 100 score per category, and a prioritized fix list an AI agent can act on directly.

### What it does

1. Runs site level technical checks: HTTPS, robots.txt, sitemap.xml.
2. Crawls up to `maxPages` internal pages in a real browser (Playwright) and audits each one: title tag, meta description, H1 structure, image alt coverage, internal links, canonical tag, schema.org markup, word count, mobile viewport, load time, and page weight.
3. Detects local SEO signals: phone numbers (tel: links and text), street addresses, phone consistency across pages, embedded maps, LocalBusiness JSON-LD completeness, and city keywords in titles and headings.
4. Computes scores: On Page, Technical, Local, and Overall (0 to 100).
5. Outputs one dataset item per audited page plus one summary item with the scores and a prioritized fix list. Every fix has a severity, the affected page, the issue, and a specific recommendation.

### Input example

```json
{
    "websiteUrl": "https://example-plumber.com",
    "businessName": "Smith Family Plumbing",
    "city": "Asheville, NC",
    "maxPages": 10
}
````

Only `websiteUrl` is required. `businessName` and `city` unlock the name consistency and city keyword checks. `maxPages` (default 10, max 50) caps both crawl depth and your cost.

### Output example

The summary item (one per run, alongside one item per audited page):

```json
{
    "type": "summary",
    "websiteUrl": "https://www.12bones.com",
    "businessName": "12 Bones Smokehouse",
    "city": "Asheville, NC",
    "pagesAudited": 5,
    "stoppedByBudget": false,
    "scores": { "onPage": 100, "technical": 100, "local": 55, "overall": 87 },
    "technicalDetails": {
        "https": true,
        "robotsTxtFound": true,
        "sitemapFound": true,
        "brokenPages": [],
        "avgLoadTimeMs": 1538,
        "sitemapSource": "https://12bones.com/sitemap.xml"
    },
    "napDetails": {
        "phones": ["8286871395"],
        "phoneConsistent": true,
        "pagesWithPhone": 5,
        "addressDetected": true,
        "mapEmbed": true,
        "localBusinessSchemaPages": 0,
        "schemaCompleteness": 0
    },
    "fixList": [
        {
            "severity": "high",
            "page": "site-wide",
            "issue": "No LocalBusiness schema.org markup found",
            "recommendation": "Add JSON-LD LocalBusiness markup to the home page with name, address, telephone, geo, url, openingHoursSpecification (name: \"12 Bones Smokehouse\")."
        },
        {
            "severity": "high",
            "page": "site-wide",
            "issue": "City \"Asheville, NC\" not found in any title or H1",
            "recommendation": "Include \"Asheville, NC\" in the home page title and H1, for example \"12 Bones Smokehouse, Asheville, NC\" or \"Your Main Service in Asheville, NC\"."
        }
    ],
    "generatedAt": "2026-07-05T13:01:28.517Z"
}
```

This is real output from a live test run against a real restaurant website. Each audited page is additionally pushed as its own dataset item with `"type": "page"` and the full per page checks (title, meta description, H1, images, canonical, viewport, word count, schema types, load time, page weight, and local signals).

### Pricing

| Event | Price | When charged |
| --- | --- | --- |
| audit-init | $0.10 | Once at run start, covers site level technical checks |
| page-audited | $0.02 | Once per page analyzed |
| report-generated | $0.40 | Once when the summary with scores and fix list is pushed |

A default 10 page audit costs $0.70. Set a maximum total charge on the run to cap spend; the actor stops gracefully at your cap and only charges for completed work.

### Use with AI agents

This actor uses pay per event pricing with limited permissions and no standby mode, which makes it discoverable and payable by AI agents through Apify's agentic payment support (x402). An agent can read the input schema, set a budget cap, run the audit, and consume the machine readable fix list without any human in the loop.

### Limitations

- Audits publicly accessible pages only; pages behind login are not crawled.
- The crawl stays on the same hostname as `websiteUrl`.
- Phone detection is tuned for North American formats; international numbers in tel: links are still detected.
- `includeCompetitorSnapshot` is reserved for a future version and currently returns null.
- This actor audits the website itself. It does not fetch Google Business Profile data.

### Who this is for

local seo audit, gbp audit companion, small business seo checker, on page seo analysis, technical seo scan, nap consistency check, localbusiness schema validator, seo fix list api, city keyword check, mobile viewport audit, sitemap and robots txt checker, page speed snapshot

# Actor input Schema

## `websiteUrl` (type: `string`):

Full URL of the business website to audit, including protocol. Example: https://example-plumber.com

## `businessName` (type: `string`):

Exact business name as it appears on the Google Business Profile. Used to check name consistency across pages. Example: Smith Family Plumbing

## `city` (type: `string`):

City and state or region the business serves. Used to check for local keywords in titles and headings. Example: Asheville, NC

## `maxPages` (type: `integer`):

Upper bound on internal pages crawled and analyzed. Each analyzed page is one page-audited charge, so this caps your cost. Default 10, maximum 50.

## `includeCompetitorSnapshot` (type: `boolean`):

Reserved for a future version. Currently returns null in the summary when enabled. Keep false.

## Actor input object example

```json
{
  "websiteUrl": "https://example-plumber.com",
  "maxPages": 10,
  "includeCompetitorSnapshot": false
}
```

# 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 = {
    "websiteUrl": "https://example-plumber.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("hereditary_model/local-seo-audit").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 = { "websiteUrl": "https://example-plumber.com" }

# Run the Actor and wait for it to finish
run = client.actor("hereditary_model/local-seo-audit").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "websiteUrl": "https://example-plumber.com"
}' |
apify call hereditary_model/local-seo-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=hereditary_model/local-seo-audit",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Local SEO Audit for Small Businesses (AI Agent Ready)",
        "description": "Audits a business website and returns on page SEO, technical health, local SEO signals (NAP, LocalBusiness schema, map embed), 0 to 100 scores, and a prioritized fix list. Pay per event.",
        "version": "0.1",
        "x-build-id": "1vBjlOKI5b40vuibH"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/hereditary_model~local-seo-audit/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-hereditary_model-local-seo-audit",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/hereditary_model~local-seo-audit/runs": {
            "post": {
                "operationId": "runs-sync-hereditary_model-local-seo-audit",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/hereditary_model~local-seo-audit/run-sync": {
            "post": {
                "operationId": "run-sync-hereditary_model-local-seo-audit",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "websiteUrl"
                ],
                "properties": {
                    "websiteUrl": {
                        "title": "Website URL",
                        "pattern": "^https?://.+",
                        "type": "string",
                        "description": "Full URL of the business website to audit, including protocol. Example: https://example-plumber.com"
                    },
                    "businessName": {
                        "title": "Business name",
                        "type": "string",
                        "description": "Exact business name as it appears on the Google Business Profile. Used to check name consistency across pages. Example: Smith Family Plumbing"
                    },
                    "city": {
                        "title": "City",
                        "type": "string",
                        "description": "City and state or region the business serves. Used to check for local keywords in titles and headings. Example: Asheville, NC"
                    },
                    "maxPages": {
                        "title": "Max pages to audit",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Upper bound on internal pages crawled and analyzed. Each analyzed page is one page-audited charge, so this caps your cost. Default 10, maximum 50.",
                        "default": 10
                    },
                    "includeCompetitorSnapshot": {
                        "title": "Include competitor snapshot",
                        "type": "boolean",
                        "description": "Reserved for a future version. Currently returns null in the summary when enabled. Keep false.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
