---
seo_title: JSON to XML API for Converting JSON Files to XML | EnConvert
meta_desc: Convert JSON to XML with POST /v1/convert/json-to-xml. Objects map to <root> children, arrays to <item> elements. Direct download or presigned URL response.
keywords: json to xml api, convert json to xml rest api, json to xml converter api, json file to xml api, json array to xml conversion, api to transform json into xml, json to xml endpoint, upload json convert to xml
---

# JSON to XML API

Convert a JSON file to XML with a single request to `POST /v1/convert/json-to-xml`. JSON objects become direct children of `<root>`, arrays are wrapped in `<root><item>` elements, and scalar values in `<root><value>`. By default the response is raw XML bytes; set `direct_download=false` to receive JSON metadata with a presigned download URL instead.

---

## Endpoint

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

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

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

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

---

## 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 `.json` file to convert. Must be UTF-8 encoded. |
| `output_filename` | `string` | No | Input filename | Custom output filename. The `.xml` extension is added automatically. |
| `direct_download` | `boolean` | No | `true` | When `true`, returns raw XML bytes. When `false`, returns JSON metadata with a presigned download URL. |

---

## Conversion Rules

- **JSON object** `{"name": "Alice", "age": 30}` becomes:
  ```xml
  <root>
    <name>Alice</name>
    <age>30</age>
  </root>
  ```

- **JSON array** `[{"id": 1}, {"id": 2}]` becomes:
  ```xml
  <root>
    <item>
      <id>1</id>
    </item>
    <item>
      <id>2</id>
    </item>
  </root>
  ```

- **Scalar value** `"hello"` becomes:
  ```xml
  <root>
    <value>hello</value>
  </root>
  ```

The root element is always `<root>`. Output is pretty-printed with single-space indentation.

---

## Response

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

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

Returns raw XML bytes.

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

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

---

## Code Examples

### Python

```python
import requests

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

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

### Node.js

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

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

const xml = await response.text();
```

### PHP

```php
$ch = curl_init("https://api.enconvert.com/v1/convert/json-to-xml");
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.json", "application/json")]
]);
$xml = curl_exec($ch);
curl_close($ch);
file_put_contents("data.xml", $xml);
```

### Go

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

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/json-to-xml", 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 `.json` file |
| `400 Bad Request` | Invalid JSON content |
| `400 Bad Request` | JSON to XML conversion failed |
| `401 Unauthorized` | Missing or invalid API key / JWT token |
| `402 Payment Required` | Monthly ops allowance exhausted |
| `402 Payment Required` | Storage limit reached |
| `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 JSON to XML with a REST API?

Send a `multipart/form-data` POST request to `/v1/convert/json-to-xml` with your `.json` file in the `file` field and authenticate with an `X-API-Key` header or a JWT `Authorization: Bearer` token. The response is the converted XML.

### How are JSON arrays converted to XML?

Each array element is wrapped in an `<item>` element under the `<root>` element, so `[{"id": 1}, {"id": 2}]` becomes `<root><item><id>1</id></item><item><id>2</id></item></root>`. The root element is always `<root>`.

### Can I get a download URL instead of raw XML bytes?

Yes. Set `direct_download=false` to receive a JSON metadata response containing a `presigned_url`, `object_key`, `filename`, `file_size`, and `conversion_time_seconds` instead of the raw XML.

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

A `400` is returned when the uploaded file is not a `.json` file, the content is not valid JSON, or the conversion itself fails. Files larger than your plan's maximum size return `413 Payload Too Large` instead.
