# Small Sitemap Inventory (`sapph1re/small-sitemap-inventory`) Actor

Build a bounded same-host URL inventory from small public HTTPS sitemaps with explicit completeness and source receipts.

- **URL**: https://apify.com/sapph1re/small-sitemap-inventory.md
- **Developed by:** [Roman V](https://apify.com/sapph1re) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 unique sitemap urls

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

## Small Sitemap Inventory

Build a bounded inventory of URLs declared by small public HTTPS sitemaps. Each dataset row is one unique URL with sitemap provenance. The run receipt tells you whether the inventory is complete, partial, empty or failed.

Use this Actor when you already know a sitemap or sitemap-index URL and want a compact, auditable URL list. It reads sitemap files only. It does not discover sitemaps through `robots.txt`, open the declared pages, check page status, download page content or cross the input root's exact host.

### Quick start

The default input is a bounded documentation sample:

```json
{}
```

It resolves to `https://docs.apify.com/sitemap_base.xml` with a maximum of 100 unique URL rows. This is a useful sample, not a promise to inventory every URL on a site. If the sitemap contains more than 100 accepted URLs, the Actor returns the first 100 unique rows and marks the result `PARTIAL` with an explicit exclusion count.

For a 25-row example that also demonstrates the source limit:

```json
{
  "startUrls": [{"url": "https://docs.apify.com/sitemap.xml"}],
  "maxDepth": 2,
  "maxSources": 2,
  "maxRequests": 4,
  "maxQueuedSources": 20,
  "maxUrls": 25,
  "maxDeclarations": 1000,
  "maxProvenancePerUrl": 5,
  "maxProvenancePerSource": 5,
  "maxDiagnosticsPerSource": 10,
  "maxOutputBytes": 262144,
  "timeoutSeconds": 10,
  "maxRedirects": 1
}
```

If the index declares more sitemap files than `maxSources` allows, those sources are not fetched. Their receipts use `SKIPPED_SOURCE_LIMIT`, and the overall result remains `PARTIAL`.

### Input contract

Provide one to ten public HTTPS sitemap or sitemap-index URLs. Each input root creates an independent exact-host boundary. Child sitemaps, redirects and declared page URLs must stay on that host.

Important defaults and maxima:

| Setting | Default | Maximum | Meaning |
| --- | ---: | ---: | --- |
| `maxDepth` | 2 | 3 | Child sitemap depth below each input root |
| `maxSources` | 20 | 50 | Sitemap files attempted after validation |
| `maxRequests` | 40 | 100 | HTTP requests, including redirect hops |
| `maxQueuedSources` | 50 | 100 | Accepted and deduplicated sitemap sources |
| `maxUrls` | 100 | 5,000 | Unique dataset rows |
| `maxDeclarations` | 5,000 | 10,000 | XML sitemap and URL declarations examined |
| `maxOutputBytes` | 2 MiB | 8 MiB | Compact bytes represented by eligible rows |
| `timeoutSeconds` | 10 | 10 | End-to-end deadline for one sitemap source |
| `maxRedirects` | 2 | 3 | Same-host redirects for one source |

Inputs are strict. Unknown fields, booleans in integer fields, extra request-object fields and out-of-range values fail before transport. `maxSources` cannot exceed `maxQueuedSources`.

### Dataset rows

Each row includes:

- `url`, preserving a benign query string in its original order;
- `declarationCount` and `declarationCountComplete`;
- bounded `sourceUrls` and sitemap declaration provenance;
- explicit source and declaration provenance omission counters;
- sitemap `lastmod`, `changefreq` and `priority` values when present.

Sitemap `lastmod` is publisher-provided declaration metadata. It is not a verified page-change timestamp, and this Actor never presents it as one.

### Run receipt and completion

Open the `OUTPUT` record in the default key-value store for source receipts, request traces, aggregate counters, configured-limit exclusions, dataset delivery status and billing evidence.

- `COMPLETE`: at least one unique URL and no known gap.
- `EMPTY`: every accepted source was processed cleanly and declared no accepted URL.
- `PARTIAL`: useful rows or parsed sources exist, but a source, declaration, safety check, configured limit, provenance detail, output row or billing event was excluded.
- `FAILED`: no source parsed successfully, or dataset delivery failed before a valid result could be confirmed.
- `OUTPUT_ERROR`: source processing may have completed, but delivery or billing evidence is failed or ambiguous.

Platform run status and product completeness are different. A platform run can succeed while the inventory is correctly marked `PARTIAL`.

### Safety and deliberate limits

- HTTPS only, with certificate and hostname validation.
- Public DNS answers only, with numeric-address socket pinning and original-host TLS SNI.
- Exact-host validation on roots, redirects, child sitemaps and declared page URLs.
- No retries, implicit proxies, cookies, authorization headers or page requests.
- URL credentials, fragments, non-ASCII literals, local names, non-public IPs and common credential or signed-link query keys are rejected.
- Each source has a 2 MiB encoded entity limit and a 2 MiB decompressed limit.
- Each HTTP response has a 2.25 MiB application-reader cap covering initial headers, chunk sizes and extensions, payload and trailers. This is not a physical wire-byte measurement.
- XML DTDs and entities are rejected. XML structure, element count, depth and attributes are bounded before tree construction.
- Inventory bytes, source receipts, diagnostics and provenance are independently bounded. Any pruning makes completeness false.

These limits are intentionally stricter than the sitemap protocol. Large enterprise sitemaps, cross-host arrangements, authenticated sitemaps and workflows that need page fetching are outside this product's scope.

### Runtime and billing

The Actor uses 128 MB of memory and a 600-second outer run timeout, with restart-on-error disabled. This outer timeout is separate from the ten-second per-source deadline and is long enough for the advertised 50-source maximum. A caller may choose a shorter platform timeout, but an externally timed-out process may not get the chance to save its final receipt.

The Store price is `$0.001` for each emitted unique dataset row through the automatic `apify-default-dataset-item` event. At the 100-row default, nominal result charges cannot exceed `$0.10` before any lower user-selected charge cap. Source receipts, summaries, empty results, rejected declarations and failed sources are not result events. There is no start fee, source fee or custom success event.

Empty and failed runs have no result-event charge. A run can still consume platform resources before it finds no eligible rows or stops with a source error.

# Actor input Schema

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

One to ten public HTTPS sitemap or sitemap-index URLs. Credentials, fragments, sensitive query keys, cross-host declarations, and non-public addresses are rejected.

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

Maximum child sitemap depth below each input sitemap.

## `maxSources` (type: `integer`):

Hard ceiling on sitemap files attempted after URL validation.

## `maxRequests` (type: `integer`):

Hard ceiling including each redirect hop. There are no retries.

## `maxQueuedSources` (type: `integer`):

Bounds queued and deduplicated source metadata. Must be at least maxSources.

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

Hard default-dataset row ceiling before billing limits are applied.

## `maxDeclarations` (type: `integer`):

Bounds direct sitemap or URL entries examined across all source files.

## `maxProvenancePerUrl` (type: `integer`):

Maximum retained source and declaration details for one unique URL. Truncation makes completeness false.

## `maxProvenancePerSource` (type: `integer`):

Maximum retained parents or input positions for one deduplicated sitemap source.

## `maxDiagnosticsPerSource` (type: `integer`):

Maximum retained rejected-declaration samples per source; aggregate counters remain bounded separately.

## `maxOutputBytes` (type: `integer`):

Maximum compact JSON bytes represented by dataset-eligible inventory rows.

## `timeoutSeconds` (type: `integer`):

Deadline shared by DNS resolution, redirect hops, connection, and body reads for one sitemap source.

## `maxRedirects` (type: `integer`):

Only redirects to the exact root host are accepted and revalidated.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://docs.apify.com/sitemap_base.xml"
    }
  ],
  "maxDepth": 2,
  "maxSources": 20,
  "maxRequests": 40,
  "maxQueuedSources": 50,
  "maxUrls": 100,
  "maxDeclarations": 5000,
  "maxProvenancePerUrl": 5,
  "maxProvenancePerSource": 5,
  "maxDiagnosticsPerSource": 10,
  "maxOutputBytes": 2097152,
  "timeoutSeconds": 10,
  "maxRedirects": 2
}
```

# Actor output Schema

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

No description

## `runReceipt` (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("sapph1re/small-sitemap-inventory").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("sapph1re/small-sitemap-inventory").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 sapph1re/small-sitemap-inventory --silent --output-dataset

```

## MCP server setup

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

```

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/sVBnPsoAJc1tKRcZv/builds/5gaiqag4R0F1VtmAN/openapi.json
