# Sitemap Analyzer — Nested XML URL Audit (`taroyamada/sitemap-analyzer`) Actor

Analyze XML sitemaps. No API key / no login. Open Input → leave defaults → Start (1 sitemap + maxUrls 3 ≈ USD 0.005 total): https://console.apify.com/actors/wJILhGwhAXWPfqBA2/input

- **URL**: https://apify.com/taroyamada/sitemap-analyzer.md
- **Developed by:** [naoki anzai](https://apify.com/taroyamada) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Features:** Limited permissions
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

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 Analyzer API | Coverage, Freshness & Indexability

**What you get:** one row per sitemap with its type (urlset or index), URL count, top directories, depth distribution, `lastmod` / `changefreq` / `priority` coverage and, with `checkStatus`, dead links.

Sample output from a real run (2026-10-18, default input: 2 sitemaps, `maxUrls: 3`, 2 rows):

| sitemapUrl | type | URLs read | top directories | URLs with lastmod | changefreq |
|---|---|---|---|---|---|
| https://apify.com/sitemap.xml | urlset | 3 (truncated) | /about, /actors | 0 | – |
| https://www.cloudflare.com/sitemap.xml | urlset | 3 (truncated) | /plans, /products | 3 (all 2026-10-18) | daily 1, weekly 2 |

That run was one Actor start ($0.001) + 2 sitemap rows × $0.004 = $0.009. The price is per sitemap row, not per URL, so raising `maxUrls` (for example to 100, which on apify.com showed /api 65 %, /alternatives 28 %) gives a fuller picture at the same cost.

[Open Input (leave defaults → Start)](https://console.apify.com/actors/wJILhGwhAXWPfqBA2/input)
Paid first run ≈ **USD 0.005 total** (1 sitemap + maxUrls 3). Keep reports, exports, and movement options off for the first run. Open Console Input (deep link above) and run this JSON.

```json
{
  "sitemapUrls": [
    "https://apify.com/sitemap.xml"
  ],
  "maxUrls": 3,
  "checkStatus": false,
  "concurrency": 1,
  "delivery": "dataset",
  "dryRun": false
}
```

Paste sitemap URL and Start.

Bypass heavy recursive web crawlers by directly extracting all underlying pages from any website's XML sitemaps. This Sitemap Scraper & Analyzer API is a purpose-built data extraction utility designed for SEO professionals and developers who need instant access to a domain's complete URL inventory. Instead of navigating confusing menus, simply use a sitemap URL to parse complex nested index files and extract thousands of links in seconds without spinning up a headless browser.

### Store Quickstart

- Start with `store-input.example.json` to analyze one public sitemap with a small URL cap.
- If that matches your SEO workflow, switch to `store-input.templates.json` and pick one of:
- `Quickstart (Dataset)` for a fast structural audit
- `Large Site Audit` for deeper coverage and status checks
- `Webhook Alert` for change-driven monitoring

### Use with Apify MCP

Exact actor: `taroyamada/sitemap-analyzer`

Sample input JSON:

```json
{
  "sitemapUrls": [
    "https://apify.com/sitemap.xml"
  ],
  "maxUrls": 100,
  "checkStatus": false,
  "concurrency": 3,
  "delivery": "dataset"
}
```

Users frequently schedule this scraper to run daily to monitor website structure changes, feed fresh URLs into search engines like Google, or supply seed lists to other web scraping tools. It serves as the perfect initial step before running heavier article or contact details extractors. Beyond just pulling links, this tool performs optional HEAD requests to verify if pages are active, returning detailed structural data including HTTP response codes, directory depth metrics, and file types.

Whether you are conducting a massive site audit, mapping a competitor's website architecture, or gathering raw scraped results to export and integrate into internal dashboards, this utility delivers clean data. By pulling direct from the sitemap.xml, you guarantee complete coverage of the websites intended for search visibility, capturing essential details like freshness metrics to keep your index perfectly synced.

### Key Features

- 🗺️ **Sitemap index support** — Handles nested sitemap structures
- 📊 **Structure analysis** — Top directories, depth distribution, file extensions
- 📅 **Update pattern detection** — lastmod distribution, changefreq analysis
- 🔗 **Dead link checker** — Optional HEAD request sampling to find broken URLs
- 🏗️ **Architecture insights** — Understand site structure from sitemap alone
- 📋 **Bulk processing** — Analyze multiple sitemaps per run

### Use Cases

| Who | Why |
|-----|-----|
| SEO agencies | Technical SEO audits — sitemap completeness and structure |
| Content strategists | Identify content update patterns and stale pages |
| Web developers | Verify sitemap structure before search engine submission |
| Competitive analysts | Map competitor site architecture from public sitemaps |

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| sitemapUrls | array | prefilled | URLs of sitemap.xml files to analyze. Auto-discovers /sitemap.xml if you provide just a domain. |
| maxUrls | integer | `3` | Maximum number of URLs to process from each sitemap (up to 50,000). The price is per sitemap row, so a higher value costs the same. |
| checkStatus | boolean | `false` | Send HEAD requests to check if URLs return 200. Slower but finds dead links. |
| delivery | string | `"dataset"` | How to deliver results. 'dataset' saves to Apify Dataset (recommended), 'webhook' sends to a URL. |
| webhookUrl | string | — | Webhook URL to send results to (only used when delivery is 'webhook'). Works with Slack, Discord, or any HTTP endpoint. |
| concurrency | integer | `3` | Maximum number of parallel requests. Higher = faster but may trigger rate limits. |
| dryRun | boolean | `false` | If true, runs without saving results or sending webhooks. Useful for testing. |

#### Input Example

```json
{
  "sitemapUrls": ["https://apify.com/sitemap.xml"],
  "maxUrls": 5000,
  "checkStatus": false,
  "concurrency": 3
}
```

### Input Examples

#### Example: Single sitemap audit

```json
{
  "sitemapUrls": [
    "https://www.cloudflare.com/sitemap.xml"
  ],
  "maxUrls": 100
}
```

#### Example: Bulk competitor sitemap snapshot

```json
{
  "sitemapUrls": [
    "https://apify.com/sitemap.xml",
    "https://www.cloudflare.com/sitemap.xml"
  ],
  "maxUrls": 500,
  "concurrency": 2
}
```

#### Example: Dead-link check on a small sample

```json
{
  "sitemapUrls": [
    "https://www.cloudflare.com/sitemap.xml"
  ],
  "maxUrls": 20,
  "checkStatus": true
}
```

### Output

One dataset row per sitemap URL.

| Field | Type | Description |
|-------|------|-------------|
| `sitemapUrl` | string | Sitemap you supplied |
| `finalUrl` | string | URL after redirects |
| `status` | string | `ok` or an error class |
| `analysis` | object | `type`, `totalUrls`, `truncated`, `structure` (top directories, depth distribution), `updateFrequency` (changefreq, lastmod range and by month), `priority`, `deadLinks` |
| `error` | string or null | Fetch / parse error, if any |
| `checkedAt` | timestamp | When the sitemap was read |

#### Output Example

Row from a real run on https://apify.com/sitemap.xml with `maxUrls: 100` (2026-10-18, top directories shortened):

```json
{
  "sitemapUrl": "https://apify.com/sitemap.xml",
  "finalUrl": "https://apify.com/sitemap.xml",
  "status": "ok",
  "analysis": {
    "type": "urlset",
    "totalUrls": 100,
    "truncated": true,
    "structure": {
      "topDirectories": [
        {
          "path": "/api",
          "count": 65,
          "percentage": 65
        },
        {
          "path": "/alternatives",
          "count": 28,
          "percentage": 28
        },
        {
          "path": "/ai-agents",
          "count": 2,
          "percentage": 2
        }
      ],
      "depthDistribution": {
        "0": 1,
        "1": 7,
        "2": 60,
        "3": 32
      },
      "extensions": null
    },
    "updateFrequency": {
      "changefreq": {},
      "lastModRange": {
        "oldest": "",
        "newest": ""
      },
      "lastModByMonth": [],
      "urlsWithLastmod": 0,
      "urlsWithChangefreq": 0
    },
    "priority": {},
    "deadLinks": null
  },
  "error": null,
  "checkedAt": "2026-10-18T11:48:22.531Z"
}
```

### API Usage

Run this actor programmatically using the Apify API. Replace `YOUR_API_TOKEN` with your token from [Apify Console → Settings → Integrations](https://console.apify.com/account/integrations).

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/taroyamada~sitemap-analyzer/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "sitemapUrls": ["https://apify.com/sitemap.xml"], "maxUrls": 5000, "checkStatus": false, "concurrency": 3 }'
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("taroyamada/sitemap-analyzer").call(run_input={
  "sitemapUrls": ["https://apify.com/sitemap.xml"],
  "maxUrls": 5000,
  "checkStatus": false,
  "concurrency": 3
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### JavaScript / Node.js

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('taroyamada/sitemap-analyzer').call({
  "sitemapUrls": ["https://apify.com/sitemap.xml"],
  "maxUrls": 5000,
  "checkStatus": false,
  "concurrency": 3
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Tips & Limitations

- Keep concurrency ≤ 5 when auditing production sites to avoid WAF rate-limit triggers.
- Use webhook delivery for recurring cron runs — push only deltas to downstream systems.
- Enable `dryRun` for cheap validation before committing to a paid cron schedule.
- Results are dataset-first; use Apify API `run-sync-get-dataset-items` for instant JSON in CI pipelines.
- Run a tiny URL count first, review the sample, then scale up — pay-per-event means you only pay for what you use.

### See also (SEO audit cluster)

- [Structured Data Scraper & Validator](https://apify.com/taroyamada/structured-data-validator) — Validate JSON-LD / Microdata / RDFa on URLs surfaced from the sitemap.

### FAQ

**Is there a rate limit?**

Built-in concurrency throttling keeps requests polite. For most public APIs this actor can run 1–10 parallel requests without issues.

**What happens when the input URL is unreachable?**

The actor records an error row with the failure reason — successful URLs keep processing.

**Can I schedule recurring runs?**

Yes — use Apify Schedules to run this actor on a cron (hourly, daily, weekly). Combine with webhook delivery for change alerts.

**Does this actor respect robots.txt?**

Yes — requests use a standard User-Agent and honor site rate limits. For aggressive audits, set a higher `concurrency` only on your own properties.

**Can I integrate with Google Sheets or Airtable?**

Use webhook delivery with a Zapier/Make/n8n catcher, or call the Apify REST API from Apps Script / Airtable automations.

### Related Actors

URL/Link Tools cluster — explore related Apify tools:

- [🔗 URL Health Checker](https://apify.com/taroyamada/bulk-url-health-checker) — Bulk-check HTTP status codes, redirects, SSL validity, and response times for thousands of URLs.
- [🔗 Broken Link Checker](https://apify.com/taroyamada/broken-link-checker) — Crawl websites to find broken links, 404 errors, and dead URLs.
- [🔗 URL Unshortener](https://apify.com/taroyamada/url-shortener-resolver) — Expand bit.
- [🏷️ Meta Tag Analyzer](https://apify.com/taroyamada/meta-tag-analyzer) — Analyze meta tags, Open Graph, Twitter Cards, JSON-LD, and hreflang for any URL.
- [📚 Wayback Machine Checker](https://apify.com/taroyamada/wayback-machine-checker) — Check if URLs are archived on the Wayback Machine and find closest snapshots by date.
- [Schema.org Validator API | JSON-LD + Microdata](https://apify.com/taroyamada/structured-data-validator) — Validate JSON-LD and Microdata across multiple pages, score markup quality, and flag missing or malformed Schema.
- [Site Governance Monitor | Robots, Sitemap & Schema](https://apify.com/taroyamada/site-governance-monitor) — Recurring robots.
- [RDAP Domain Monitor API | Ownership + Expiry](https://apify.com/taroyamada/rdap-domain-monitor) — Monitor domain registration data via RDAP and track expiry, registrar, nameserver, and ownership changes in structured rows.
- [Domain Security Audit API | SSL Expiry, DMARC, Domain Expiry](https://apify.com/taroyamada/domain-trust-monitor) — Summary-first portfolio monitor for SSL expiry, DMARC/SPF/DKIM, domain expiry/ownership, and security headers with remediation-ready outputs.

### Cost

**Pay Per Event** (current Store prices):

- Actor start: $0.001 per run
- Result sitemap row: $0.004 per sitemap row written to the default dataset

**Example**: 1,000 sitemap rows = $0.001 + (1,000 × $0.004) = **$4.00**

No subscription required — you only pay for what you use.

### ⭐ Was this helpful?

If this actor saved you time, please [**leave a ★ rating**](https://apify.com/taroyamada/sitemap-analyzer/reviews) on Apify Store. It takes 10 seconds, helps other developers discover it, and keeps updates free.

Bug report or feature request? Open an issue on the [Issues tab](https://apify.com/taroyamada/sitemap-analyzer/issues) of this actor.

# Actor input Schema

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

Leave the 1 prefilled sitemap URL and click Start for the first run. Or paste sitemap.xml URLs or domains to analyze site structure.

## `maxUrls` (type: `integer`):

Maximum number of URLs to process from each sitemap. Empty falls back to 1.

## `checkStatus` (type: `boolean`):

Send HEAD requests to check if URLs return 200. Slower but finds dead links.

## `delivery` (type: `string`):

How to deliver results. 'dataset' saves to Apify Dataset (recommended), 'webhook' sends to a URL.

## `webhookUrl` (type: `string`):

Webhook URL to send results to (only used when delivery is 'webhook'). Works with Slack, Discord, or any HTTP endpoint.

## `concurrency` (type: `integer`):

Maximum number of parallel requests. Higher = faster but may trigger rate limits.

## `dryRun` (type: `boolean`):

If true, runs without saving results or sending webhooks. Useful for testing.

## Actor input object example

```json
{
  "sitemapUrls": [
    "https://apify.com/sitemap.xml"
  ],
  "maxUrls": 1,
  "checkStatus": false,
  "delivery": "dataset",
  "concurrency": 1,
  "dryRun": 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 = {
    "sitemapUrls": [
        "https://apify.com/sitemap.xml"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/sitemap-analyzer").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 = { "sitemapUrls": ["https://apify.com/sitemap.xml"] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/sitemap-analyzer").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 '{
  "sitemapUrls": [
    "https://apify.com/sitemap.xml"
  ]
}' |
apify call taroyamada/sitemap-analyzer --silent --output-dataset

```

## MCP server setup

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

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/wJILhGwhAXWPfqBA2/builds/EI2lQuSNupYBH99J1/openapi.json
