# Franchise Location Consistency Auditor (`junipr/franchise-location-consistency-auditor`) Actor

Compare franchise/location pages for brand, NAP, service, hours, CTA, schema, and template consistency while preserving location-specific differences

- **URL**: https://apify.com/junipr/franchise-location-consistency-auditor.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** SEO tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $11.50 / 1,000 franchise page analyzeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Franchise Location Consistency Auditor

Compare franchise and branch pages across brand, NAP, CTA, schema, and template rules while preserving explicitly allowed local differences.

### What it does

- Builds a source profile for every capped location page.
- Checks expected brand terms and required template elements.
- Uses the first page or an optional master page as the comparison baseline.
- Separates missing elements from unapproved differences.
- Calculates a transparent per-page consistency score.

### Input

- `startUrls`, `locationPages`, `sitemapUrls`, or `htmlInputs`.
- `expectedBrandTerms` and `requiredTemplateElements`.
- `allowedLocalVariations` for intentional differences.
- `compareAgainstMasterPage` and `consistencyThresholds.minimumScore`.
- `maxLocations`, `maxRules`, `maxPages`, `maxDepth`, and `maxChargeUsd`.

### Dataset output

Each dataset item is one JSON object. The schema includes:

- location URL and name.
- template rule.
- expected and actual values.
- consistency status.
- allowed-variation and location-difference flags.
- brand-term flag and consistency score.

The actor also writes a Markdown summary, CSV records, JSON issues, evidence excerpts, and run metadata to key-value storage. Raw HTML is excluded unless `includeRawSnapshots` is enabled.

### Pricing and charge safety

This actor uses pay per event with Apify platform-usage pass-through disabled. Charges are accepted before paid dataset or report output. `maxChargeUsd` stops the run before the next event would exceed the configured amount, including when the limit is zero.

| Event | Price |
| --- | ---: |
| `actor-start` | $0.03500 |
| `franchise-page-analyzed` | $0.01150 |
| `consistency-rule-checked` | $0.01150 |
| `consistency-issue-emitted` | $0.01150 |
| `executive-report-generated` | $0.40000 |

### Example input

```json
{
  "htmlInputs": [
    {
      "sourceUrl": "https://example.com/nashville",
      "html": "<h1>Acme Nashville</h1><p>100 Broadway, Nashville, TN 37201 · 615-555-0100</p><a href=\"/quote\">Request a quote</a><script type=\"application/ld+json\">{\"@type\":\"LocalBusiness\",\"name\":\"Acme Nashville\"}</script>"
    },
    {
      "sourceUrl": "https://example.com/franklin",
      "html": "<h1>Franklin</h1><p>200 Main St, Franklin, TN 37064</p>"
    }
  ],
  "expectedBrandTerms": [
    "Acme"
  ],
  "requiredTemplateElements": [
    "phone",
    "address",
    "cta",
    "schema"
  ],
  "maxLocations": 5,
  "maxRules": 20,
  "maxChargeUsd": 35
}
```

### Result quality

- Public URL fetching rejects localhost and private IPv4 targets.
- Domain allowlists, timeouts, request delays, crawl depth, and actor-specific limits are enforced.
- Missing or blocked source evidence produces an explicit diagnostic instead of invented values.
- Every dataset row follows the declared dataset schema.
- Reports include the evidence reference and recommended next action for each finding.

### Responsible use

Only process public pages or content you are authorized to analyze. Respect site terms, robots policies, rate limits, privacy obligations, and applicable law.

# Actor input Schema

## `startUrls` (type: `array`):

Public pages to fetch when HTML snapshots are not supplied.

## `sitemapUrls` (type: `array`):

Optional public XML sitemaps used for same-domain discovery.

## `htmlInputs` (type: `array`):

Optional source-backed HTML snapshots for deterministic extraction.

## `allowedDomains` (type: `array`):

Optional domain allowlist applied to every fetched or discovered URL.

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

Maximum public pages fetched or analyzed.

## `maxDepth` (type: `integer`):

Same-domain internal-link discovery depth.

## `includeEvidence` (type: `boolean`):

Include source excerpts in dataset rows.

## `includeRawSnapshots` (type: `boolean`):

Write capped raw HTML snapshots to key-value storage.

## `requestDelayMs` (type: `integer`):

Delay between public HTTP requests in milliseconds.

## `timeoutMs` (type: `integer`):

Per-request timeout in milliseconds.

## `userAgentMode` (type: `string`):

HTTP user-agent profile.

## `locationPages` (type: `array`):

Additional franchise or branch page URLs.

## `expectedBrandTerms` (type: `array`):

Brand names or phrases required on each location page.

## `requiredTemplateElements` (type: `array`):

Elements checked across every page.

## `allowedLocalVariations` (type: `array`):

Rule names explicitly allowed to vary by location.

## `compareAgainstMasterPage` (type: `string`):

Optional master or reference URL; the first analyzed page is the baseline when blank.

## `consistencyThresholds` (type: `object`):

Scoring threshold configuration.

## `maxLocations` (type: `integer`):

Maximum location pages compared.

## `maxRules` (type: `integer`):

Maximum brand and template rules evaluated per page.

## `maxChargeUsd` (type: `number`):

Maximum estimated PPE spend before a graceful stop.

## `includeReport` (type: `boolean`):

Write Markdown, CSV, JSON evidence, and run metadata.

## Actor input object example

```json
{
  "startUrls": [
    "https://example.com/"
  ],
  "sitemapUrls": [],
  "htmlInputs": [],
  "allowedDomains": [],
  "maxPages": 1,
  "maxDepth": 0,
  "includeEvidence": true,
  "includeRawSnapshots": false,
  "requestDelayMs": 250,
  "timeoutMs": 15000,
  "userAgentMode": "standard",
  "locationPages": [],
  "expectedBrandTerms": [],
  "requiredTemplateElements": [
    "phone",
    "address",
    "cta",
    "schema"
  ],
  "allowedLocalVariations": [],
  "compareAgainstMasterPage": "",
  "consistencyThresholds": {
    "minimumScore": 80
  },
  "maxLocations": 5,
  "maxRules": 25,
  "maxChargeUsd": 35,
  "includeReport": true
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `report` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/franchise-location-consistency-auditor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("junipr/franchise-location-consistency-auditor").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 '{}' |
apify call junipr/franchise-location-consistency-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,junipr/franchise-location-consistency-auditor"
        }
    }
}

```

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/7t6D63AR8KcIORjYD/builds/bZzr2uMuXeFQ2zs1d/openapi.json
