XML to JSON
XML documents carry meaning in places JSON was never designed to hold — attributes, namespaces, mixed text nodes — and a naive converter throws that meaning away. This endpoint keeps it, mapping attributes into a predictable, documented shape instead of silently dropping them.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
The part every quick script gets wrong
Ask a developer to write a five-minute XML-to-JSON converter and you'll get one that handles element text just fine and then quietly discards every attribute, because most XML parsers treat attributes as metadata rather than data. But in real documents — SOAP envelopes, RSS feeds, SVG markup, config files inherited from a decade-old system — the attributes often carry the fields that actually matter: an id, a type, a currency code, a version number sitting on the tag instead of inside it. data.xml_to_json keeps those attributes, consistently prefixed so they never collide with sibling element names.
What you send and what comes back
POST your XML to /data/xml-to-json, receive a task_id immediately, and let the conversion run in the background. The result — clean JSON with attributes, nested elements and repeated tags mapped into arrays — arrives through a signed webhook call or waits behind a signed link valid for 24 hours, whichever your system is set up to poll or receive.
Why XML still shows up in 2026
JSON won the API-payload war years ago, but XML never left: it still runs SOAP services, RSS and Atom feeds, Office document internals, SVG graphics, Android resource files, and a long tail of enterprise systems where a schema-validated, self-describing format was the right call when it was built. Teams building modern integrations don't get to choose the format on the other end of a legacy feed — they get to choose how quickly they normalize it once it arrives, and that's the job this endpoint does.
Fitting into a normalization pipeline
A common pattern is an ingestion layer that accepts whatever a partner or legacy system sends, converts it to JSON immediately, and lets every downstream service — validation, storage, transformation — work against one predictable shape instead of writing custom XML parsing for every source. Because the task is async and priced per request, a nightly batch of a few thousand partner feeds costs the same per document whether it runs at 3am unattended or one file at a time during business hours, and nothing is billed unless the conversion actually succeeds.
What you can do with it
SOAP response normalization
An integration layer converts SOAP XML responses from a legacy partner API to JSON before handing them to a modern microservice that only speaks JSON.
RSS and Atom feed ingestion
A content aggregator converts incoming RSS and Atom XML feeds to JSON to store and query them alongside data already coming from JSON APIs.
Legacy config migration
A platform migrating off an old XML-based configuration system converts each config file to JSON once, preserving every attribute needed for the new format.
SVG metadata extraction
A design tool converts SVG files to JSON to read viewBox, id and style attributes programmatically without writing a custom XML parser.
FAQ
How do I convert XML to JSON with the API?
POST your XML document to /data/xml-to-json, save the returned task_id, and receive the converted JSON by webhook or a signed link valid for 24 hours.
Is the XML to JSON API free?
No, there is no free tier or trial; it costs $0.002 per request, and a failed conversion is never charged.
Are XML attributes preserved in the JSON output?
Yes, attributes are preserved and consistently prefixed in the resulting JSON so they never collide with element names of the same tag.
What happens to XML namespaces?
Namespace prefixes are kept on the element and attribute names they belong to, so downstream code can still tell which namespace a field came from.
Can it handle repeated tags and nested elements?
Yes, repeated sibling tags are mapped into JSON arrays and nested elements become nested objects, matching the document's original structure.
How large a file can I convert?
The endpoint is built for typical document, feed and config-file sizes; very large exports are best split into multiple requests submitted in parallel.
Can I convert files in bulk?
Yes, submit one async task per document and collect each result by webhook as it completes, which is the pattern most batch integrations use.
Is my XML data stored after conversion?
No, source files and 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/data/xml-to-json \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/data/xml-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/data/xml-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/data/xml-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/data/xml-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": "data.xml_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.
Limits
max_mb | 25 |
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. |