---
seo_title: XML to JSON API for Converting XML Files to JSON | EnConvert
meta_desc: Convert XML to JSON with POST /v1/convert/xml-to-json. Attributes become @-prefixed keys, repeated elements become arrays, root wrappers auto-unwrap.
keywords: xml to json api, convert xml to json rest api, xml to json converter api, xml file to json api, parse xml to json online api, xml attributes to json, xml to json array conversion, upload xml convert to json
---

# XML to JSON API

Convert an XML file to JSON with a single request to `POST /v1/convert/xml-to-json`. The converter auto-unwraps `<root>` and `<root><item>` wrappers for clean output, represents XML attributes as `@attr` keys and text content as `#text`, and turns repeated sibling elements into JSON arrays. Responses return raw JSON bytes by default, or metadata with a presigned download URL when `direct_download=false`.

---

## Endpoint

```
POST /v1/convert/xml-to-json
```

**Content-Type:** `multipart/form-data`

**Accepted input:** `.xml` files (UTF-8 encoded)

**Output format:** `.json` (`application/json`)

---

## Authentication

Requires either a private API key or a JWT token from a public key.

```
X-API-Key: sk_your_private_key
```

Or:

```
Authorization: Bearer <jwt_token>
```

---

## Request Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `file` | file | Yes | -- | The `.xml` file to convert. Must be UTF-8 encoded. |
| `output_filename` | `string` | No | Input filename | Custom output filename. The `.json` extension is added automatically. |
| `direct_download` | `boolean` | No | `true` | When `true`, returns raw JSON bytes. When `false`, returns metadata with a presigned download URL. |

---

## Conversion Rules

- **Simple XML** -- auto-unwraps `<root>`:
  ```xml
  <root><name>Alice</name><age>30</age></root>
  ```
  Becomes:
  ```json
  {"name": "Alice", "age": "30"}
  ```

- **Repeated elements** become a JSON array (auto-unwraps `<root>` and `<item>`):
  ```xml
  <root><item><id>1</id></item><item><id>2</id></item></root>
  ```
  Becomes:
  ```json
  [{"id": "1"}, {"id": "2"}]
  ```

- **XML attributes** are prefixed with `@`:
  ```xml
  <user id="1" role="admin">Alice</user>
  ```
  Becomes:
  ```json
  {"@id": "1", "@role": "admin", "#text": "Alice"}
  ```

Output is pretty-printed JSON with 2-space indentation and unicode preserved. Repeated sibling elements with the same tag name become a JSON array automatically.

---

## Response

### Direct Download (`direct_download=true`, default)

```
HTTP 200 OK
Content-Type: application/json
Content-Disposition: inline; filename="data_20260405_123456789.json"
```

### Metadata Response (`direct_download=false`)

```json
{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/xml-to-json/data_20260405_123456789.json",
    "filename": "data_20260405_123456789.json",
    "file_size": 1234,
    "conversion_time_seconds": 0.05
}
```

---

## Code Examples

### Python

```python
import requests

with open("data.xml", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/xml-to-json",
        headers={"X-API-Key": "sk_your_private_key"},
        files={"file": ("data.xml", f, "application/xml")}
    )

with open("data.json", "wb") as out:
    out.write(response.content)
```

### Node.js

```javascript
const form = new FormData();
form.append("file", fs.createReadStream("data.xml"));

const response = await fetch("https://api.enconvert.com/v1/convert/xml-to-json", {
    method: "POST",
    headers: { "X-API-Key": "sk_your_private_key" },
    body: form
});

const json = await response.json();
```

### PHP

```php
$ch = curl_init("https://api.enconvert.com/v1/convert/xml-to-json");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_your_private_key"],
    CURLOPT_POSTFIELDS => ["file" => new CURLFile("data.xml", "application/xml")]
]);
$json = curl_exec($ch);
curl_close($ch);
```

### Go

```go
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "data.xml")
file, _ := os.Open("data.xml")
io.Copy(part, file)
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/xml-to-json", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_your_private_key")
resp, _ := http.DefaultClient.Do(req)
```

---

## Error Responses

| Status | Condition |
|--------|-----------|
| `400 Bad Request` | File is not a `.xml` file |
| `400 Bad Request` | XML to JSON conversion failed (invalid XML) |
| `401 Unauthorized` | Missing or invalid API key / JWT token |
| `402 Payment Required` | Monthly ops allowance exhausted |
| `413 Payload Too Large` | File exceeds plan's maximum file size |

---

## Limits

| Limit | Value |
|-------|-------|
| Max file size | Plan-dependent (Founding: 5 MB) |
| Input encoding | UTF-8 only |
| Monthly conversions | Plan-dependent |

## Frequently asked questions

### How do I convert XML to JSON with a REST API?

Send a `multipart/form-data` POST request to `/v1/convert/xml-to-json` with your `.xml` file in the `file` field, authenticated with an `X-API-Key` header or a JWT `Authorization: Bearer` token. The response is pretty-printed JSON with 2-space indentation.

### How are XML attributes represented in the JSON output?

Attributes are prefixed with `@` and element text content becomes a `#text` key, so `<user id="1" role="admin">Alice</user>` converts to `{"@id": "1", "@role": "admin", "#text": "Alice"}`.

### How are repeated XML elements converted to JSON?

Repeated sibling elements with the same tag name automatically become a JSON array, and `<root>` plus `<item>` wrappers are auto-unwrapped, so `<root><item>...</item><item>...</item></root>` becomes a top-level JSON array.

### Can I get a presigned download URL instead of the raw JSON?

Yes. Set `direct_download=false` to receive metadata with a `presigned_url`, `object_key`, `filename`, `file_size`, and `conversion_time_seconds` instead of raw JSON bytes.

### Why does the XML to JSON API return 400 Bad Request?

A `400` is returned when the file is not a `.xml` file or the XML is invalid and conversion fails. Oversized files return `413 Payload Too Large`, and exhausting your monthly ops allowance returns `402 Payment Required`.
