Sitemap to JSON
A sitemap index is rarely just a list. It is a tree of sub-sitemaps, sometimes nested three levels deep, mixing pages, images and news entries in ways that make a simple XML parser choke. This endpoint walks that tree for you and hands back a flat JSON array of URLs with their metadata, ready to loop over in any script.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Why sitemaps stop being simple
A single sitemap.xml file can hold at most 50,000 URLs, so any site larger than that splits itself into a sitemap index pointing at dozens or hundreds of child files. Parsing that by hand means recursively fetching each child, tracking which ones are themselves indexes, and reconciling different XML namespaces for images, video and news. Teams doing content audits, migrations or link-rot checks usually just want the final list of URLs — not the plumbing to get there.
What the request does
Send the root sitemap URL and the task fetches it, detects whether it is an index or a leaf sitemap, and recurses through every child automatically. It resolves relative paths, decodes HTML entities in the URLs, and captures the lastmod, changefreq and priority fields when the source includes them, so nothing is lost in translation from XML to JSON.
A short history worth knowing
The sitemap protocol was introduced by a search engine in 2005 and adopted jointly by the major engines the following year, precisely to solve the discovery problem for large or poorly linked sites. Two decades later the format is unchanged at its core, but real-world implementations vary wildly: some CMSs emit malformed XML, others gzip their files, others mix protocols. This task normalizes all of that quietly before it reaches your output.
Where it fits in a pipeline
Because the result is plain JSON, it drops straight into a crawl queue, a diffing script that compares this week's URL set against last week's, or a reporting job that counts how many pages a client's site actually exposes. The task is asynchronous: you submit it, get a task_id immediately, and receive the finished list through your webhook or a signed link once processing completes.
Reliability by design
If a child sitemap is unreachable or the XML is broken beyond repair, the task retries up to three times before failing cleanly with a specific error — and a failed task is never billed. You only pay for output you can actually use, which matters most on the exact days a sitemap is misbehaving and you need a trustworthy answer quickly.
What you can do with it
Site migration audits
Pull the full URL inventory from a legacy sitemap before a domain move, so nothing gets silently dropped in the redirect map.
Weekly crawl scoping
Feed the flattened list into a crawler as its seed set instead of re-discovering pages through internal links every run.
Content inventory for clients
Turn a messy multi-level sitemap index into a spreadsheet-ready JSON list during an SEO audit deliverable.
Change monitoring
Compare today's flattened URL list against last month's snapshot to spot sections of a site that grew or shrank unexpectedly.
FAQ
What does this parse sitemap API actually return?
A flat JSON array of every URL found across the sitemap and all of its child sitemaps, including lastmod, changefreq and priority when present in the source.
Does it handle sitemap index files with nested sub-sitemaps?
Yes, it recurses through indexes automatically, including multi-level nesting, and returns one combined list.
Is gzip-compressed sitemap.xml.gz supported?
Yes, compressed sitemap files are decompressed automatically before parsing.
Is there a free tier or trial?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
How much does it cost per call?
A flat $0.002 per request, regardless of how many URLs the sitemap contains.
How do I get the result?
Through a signed webhook call when the task finishes, or by fetching a signed link that stays valid for 24 hours.
What happens if a sitemap is broken or unreachable?
The task retries up to three times automatically; if it still fails, you get a clear error and are not charged.
Is my data used to train models?
No. Results are deleted after the retention window and are never used for training.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/seo/sitemap-to-json \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/seo/sitemap-to-json", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/seo/sitemap-to-json",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/seo/sitemap-to-json", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/seo/sitemap-to-json", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "seo.sitemap_to_json",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |