# Sitemap & SEO Page Audit - Titles, Meta, H1, Links (`plotpointtech/sitemap-seo-page-audit`) Actor

- **URL**: https://apify.com/plotpointtech/sitemap-seo-page-audit.md
- **Developed by:** [Plot Point Technologies](https://apify.com/plotpointtech) (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

from $4.00 / 1,000 page auditeds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Sitemap & SEO Page Audit

Check the on-page SEO basics of every page on a website in one run. The tool finds pages in the website's XML sitemaps (and, if you want, by following internal links), visits each page, and returns one row per page with its HTTP status, redirects, response time, title, meta description, canonical, robots directives, headings, word count, images, links, hreflang, Open Graph tags, structured data and a plain-English list of issues to fix.

A cheaper **Sitemap URLs only** mode lists every URL in the sitemaps without visiting the pages.

### Who uses it

- **SEO consultants and agencies** running quick technical audits for clients and prospects.
- **In-house marketing and web teams** checking a site before and after a launch, migration or redesign.
- **Developers** catching broken pages, redirect chains and missing tags in a scheduled run.
- **Content teams** finding missing or duplicate titles and descriptions across hundreds of pages.

### How pages are found

1. Sitemaps listed in the website's `robots.txt` are read. If none are listed, `/sitemap.xml` and `/sitemap_index.xml` are tried.
2. Sitemap index files are followed, and gzipped (`.xml.gz`) and plain-text sitemaps are supported.
3. Optionally, internal links on audited pages are followed to find pages missing from the sitemaps. If sitemaps are switched off, link crawling is used automatically.
4. With "Stay within the start URL's folder" on, entering `example.com/blog/` audits only `/blog/` pages.

### Input

| Field | What it does |
|---|---|
| Websites | One or more home pages or site sections. `example.com` works too. |
| Mode | Full SEO audit (default) or Sitemap URLs only. |
| Maximum pages per website | Default 50. |
| Find pages in sitemaps | Default on. |
| Also follow internal links | Default off. |
| Stay within the start URL's folder | Default on. |
| Only save pages with issues | Skip clean pages; skipped pages are not charged. |
| Pages at once | 1 to 10 (default 5). |

### Output (full audit)

| Field | Description |
|---|---|
| `url`, `foundIn`, `inSitemap` | Page URL, how it was found (sitemap, link or start URL), and whether it is in a sitemap |
| `httpStatus`, `redirectTarget`, `redirectCount`, `finalStatus` | Status code of the URL itself; for redirects, where it ends up |
| `responseTimeMs` | Time to download the page, in milliseconds |
| `title`, `titleLength` | Title tag and its length in characters |
| `metaDescription`, `metaDescriptionLength` | Meta description and its length |
| `canonical` | Canonical URL |
| `robotsMeta`, `xRobotsTag` | Robots meta tag and X-Robots-Tag header |
| `h1`, `h1Count`, `h2Count` | H1 texts and heading counts |
| `wordCount` | Words of visible text |
| `imageCount`, `imagesMissingAlt`, `imagesEmptyAlt` | Images, images with no alt attribute, and images with an empty alt (often decorative) |
| `internalLinks`, `externalLinks`, `nofollowLinks` | Unique links on the page |
| `hreflang` | Alternate language versions |
| `hasOgTitle`, `hasOgImage`, `hasViewport` | Open Graph title and image, mobile viewport tag |
| `structuredDataTypes` | Schema.org types found in JSON-LD or microdata, e.g. Organization, Product, BreadcrumbList |
| `issues`, `issueCount` | The problems found on the page |

Issues checked: broken page (4xx), server error (5xx), redirect and redirect chain, blocked by robots.txt, missing / too long (over 60 characters) / too short title, duplicate title, missing / too long (over 160) / too short (under 50) meta description, duplicate meta description, missing or multiple H1, noindex, nofollow, canonical pointing to another URL, images missing alt text, thin content (under 200 words), slow response (over 3 seconds) and missing viewport tag. Duplicates are compared across the pages audited in the same run.

In **Sitemap URLs only** mode each row has `url`, `lastmod`, `changefreq`, `priority`, `imageCount` and the `sitemap` it came from.

### Pricing

Two prices: one per audited page, and a much lower one per URL in Sitemap URLs only mode. Pages you choose to skip are not charged.

### Notes and limits

- **robots.txt is always respected.** URLs that robots.txt disallows are not downloaded; they are reported with the issue "Blocked by robots.txt" so you can see which sitemap URLs crawlers cannot reach.
- Requests are spaced out per website, and the tool identifies itself as `PlotPointBot`. Response times are measured from Apify's servers and are a guide, not a lab speed test.
- Pages are downloaded without a browser, so tags added by JavaScript after the page loads are not seen. This matches how many crawlers first read a page.
- Only public pages are checked: no logins, no CAPTCHA solving and no proxies.
- This is an on-page check. It does not report rankings, backlinks, traffic or Core Web Vitals.

Plot Point Technologies is not affiliated with Google, any website you audit, or Apify.

# Actor input Schema

## `websites` (type: `array`):

Website home pages or sections to audit, e.g. https://www.example.com/ or example.com/blog/.

## `mode` (type: `string`):

Full audit downloads and checks every page. Sitemap URLs only lists the URLs in the website's sitemaps (with lastmod, changefreq and priority) without visiting the pages, at a much lower price.

## `maxPagesPerSite` (type: `integer`):

Stop after this many pages (or sitemap URLs) per website.

## `useSitemaps` (type: `boolean`):

Read the sitemaps listed in robots.txt, or /sitemap.xml, including sitemap index files and .gz sitemaps.

## `crawlLinks` (type: `boolean`):

Also discover pages by following links on audited pages (same website). Used automatically when sitemaps are switched off or list fewer than 10 pages. Full audit mode only.

## `stayWithinStartPath` (type: `boolean`):

Only include pages under the start URL's path, e.g. only /blog/ pages when you enter example.com/blog/.

## `onlyPagesWithIssues` (type: `boolean`):

Skip pages where no issue was found. Skipped pages are not charged.

## `maxConcurrency` (type: `integer`):

Parallel requests. Requests to each site are also spaced out politely, and any Crawl-delay in robots.txt is honoured.

## Actor input object example

```json
{
  "websites": [
    "https://fastapi.tiangolo.com/"
  ],
  "mode": "audit",
  "maxPagesPerSite": 50,
  "useSitemaps": true,
  "crawlLinks": false,
  "stayWithinStartPath": true,
  "onlyPagesWithIssues": false,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `results` (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 = {
    "websites": [
        "https://fastapi.tiangolo.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plotpointtech/sitemap-seo-page-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 = { "websites": ["https://fastapi.tiangolo.com/"] }

# Run the Actor and wait for it to finish
run = client.actor("plotpointtech/sitemap-seo-page-audit").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 '{
  "websites": [
    "https://fastapi.tiangolo.com/"
  ]
}' |
apify call plotpointtech/sitemap-seo-page-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plotpointtech/sitemap-seo-page-audit"
        }
    }
}
```

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/EUdsotjYuk49FxMdc/builds/bTPxwn57VB7oNB4Rx/openapi.json
