StediDOCS

Converter

Updated June 28, 2022

The Converter API provides a convenient way of converting between file formats. We currently support the following conversions.

  • CSV to JSON
  • JSON to CSV
  • XML to JSON

The information on this page is written for software developers. We assume you‘re familiar with calling HTTP API endpoints.

Starter Kit

We provide an example TypeScript project to get you started: converter-axios-example

Authentication

Before you can get started with the API, you need an API key. If you already have an API key for another Stedi product, you can use that here as well; you don‘t need a separate key for Converter.

Once you have the key, include it in every call to the API as part of the Authorization header.

Authorization: Key $STEDI_API_KEY

If you‘d like more information about this, take a look at our Authentication guide.

Using the API

The Converter API calls are initiated from your infrastructure/system through an HTTP client and must provide a payload and options for the target format. Keep the below mental model in mind as you read the following sections.

Convert CSV or XML to JSON using Stedi Converter.

Converters

CSV to JSON

This converter uses the headers in the CSV as keys in the JSON. The result is a list with an object for each row, where the object has a field for each column. So, if you have a CSV like this…

participant,mood,favorite adjective
Iliana,rambunctious,onomatopoetic
Dragomir,morose,megalomaniacal

…the resulting JSON looks like this.

[
  {
    "participant": "Iliana",
    "mood": "rambunctious",
    "favorite adjective": "onomatopoetic"
  },
  {
    "participant": "Dragomir",
    "mood": "morose",
    "favorite adjective": "megalomaniacal"
  }
]

Alternatively, you can ask the converter to produce a two-dimensional list. In that case, the result looks like this.

[
  ["participant", "mood", "favorite adjective"],
  ["Iliana", "rambunctious", "onomatopoetic"],
  ["Dragomir", "morose", "megalomaniacal"]
]

Basic request

You convert a CSV by POSTing it to https://converter.stedi.com/2021-10-01/csv_to_json.

POST https://converter.stedi.com/2021-10-01/csv_to_json HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json

{
  "input": "participant,mood,favorite adjective\nIliana,rambunctious,onomatopoetic\nDragomir,morose,megalomaniacal"
}

The response looks as follows.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "output": [
    {
      "participant": "Iliana",
      "mood": "rambunctious",
      "favorite adjective": "onomatopoetic"
    },
    {
      "participant": "Dragomir",
      "mood": "morose",
      "favorite adjective": "megalomaniacal"
    }
  ]
}

Output a two-dimensional list

If you prefer a two-dimensional list as output, you can set the has_header option to false.

POST https://converter.stedi.com/2021-10-01/csv_to_json HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json

{
  "input": "participant,mood,favorite adjective\nIliana,rambunctious,onomatopoetic\nDragomir,morose,megalomaniacal",
  "options": {
    "has_header": false
  }
}

The response looks as follows.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "output": [
    [ "participant", "mood", "favorite adjective" ],
    [ "Iliana", "rambunctious", "onomatopoetic" ],
    [ "Dragomir", "morose", "megalomaniacal" ]
  ]
}

Delimiters, quotes, and newlines

CSVs come with a wide variety of special characters, so you have the option to specify which delimiter, quote, and newline character to use. Say your CSV looks like this and uses \r\n at the end of each line (as is standard on Windows).

participant;mood;favorite adjectives
Iliana;rambunctious;onomatopoetic,whimsical
Dragomir;morose;`megalomaniacal;ephemeral`

You can then provide the following options to make sure the converter interprets this the right way.

{
  "options": {
    "delimiter": ";",
    "quote": "`",
    "newline": "\r\n"
  }
}

The resulting JSON looks as follows.

[
  {
    "participant": "Iliana",
    "mood": "rambunctious",
    "favorite adjectives": "onomatopoetic,whimsical"
  },
  {
    "participant": "Dragomir",
    "mood": "morose",
    "favorite adjectives": "megalomaniacal;ephemeral"
  }
]

Duplicate headers

By default, duplicate headers are treated as an error, because it‘s unclear how you want them to end up in the output. However, if you want them to be numbered, then you‘re in luck: there‘s an option for that. Here‘s an example of a CSV that has the header adjective twice.

participant,adjective,adjective
Iliana,rambunctious,onomatopoetic
Dragomir,morose,megalomaniacal

You can have the headers numbered by settings on_duplicate_headers to number.

"options": {
  "on_duplicate_headers": "number"
}

The result will look like this.

[
  {
    "participant": "Iliana",
    "adjective": "rambunctious",
    "adjective_1": "onomatopoetic"
  },
  {
    "participant": "Dragomir",
    "adjective": "morose",
    "adjective_1": "megalomaniacal"
  }
]

Other options

Additionally, the converter provides the following options.

  • trim removes whitespace at the beginning and end of each value.
  • convert_types turns values into numbers and booleans where possible.

Suppose you have a CSV that looks as follows.

participant, attempts, winner
Iliana, 5, true
Dragomir, 7.3, false

By default, with both options set to false, the result looks like this.

[
  {
    "participant": "Iliana",
    " attempts": " 5",
    " winner": " true"
  },
  {
    "participant": "Dragomir",
    " attempts": " 7.3",
    " winner": " false"
  }
]

With both options set to true, the result looks like this.

[
  {
    "participant": "Iliana",
    "attempts": 5,
    "winner": true
  },
  {
    "participant": "Dragomir",
    "attempts": 7.3,
    "winner": false
  }
]

JSON to CSV

This converter uses the keys in JSON to create headers in CSV and then turns every object into a row. So, if you have JSON like this…

[
  {
    "participant": "Iliana",
    "mood": "rambunctious",
    "favorite adjective": "onomatopoetic"
  },
  {
    "participant": "Dragomir",
    "mood": "morose",
    "favorite adjective": "megalomaniacal"
  }
]

…the resulting CSV will look like this.

participant,mood,favorite adjective
Iliana,rambunctious,onomatopoetic
Dragomir,morose,megalomaniacal

Alternatively, you can get the same result by providing a two-dimensional list in JSON.

[
  ["participant", "mood", "favorite adjective"],
  ["Iliana", "rambunctious", "onomatopoetic"],
  ["Dragomir", "morose", "megalomaniacal"]
]

The JSON fields must have scalar values; nested objects and arrays aren‘t supported.

Basic request

You convert JSON by POSTing it to https://converter.stedi.com/2021-10-01/json_to_csv.

POST https://converter.stedi.com/2021-10-01/json_to_csv HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json

{
  "input": [
    {
      "participant": "Iliana",
      "mood": "rambunctious",
      "favorite adjective": "onomatopoetic"
    },
    {
      "participant": "Dragomir",
      "mood": "morose",
      "favorite adjective": "megalomaniacal"
    }
  ]
}

The response looks as follows.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "output": "participant,mood,favorite adjective\r\nIliana,rambunctious,onomatopoetic\r\nDragomir,morose,megalomaniacal"
}

Delimiters and newlines

CSVs come with a wide variety of special characters, so you have the option to specify which delimiter and newline character to use. Say you have JSON like this…

[
  {
    "participant": "Iliana",
    "mood": "rambunctious",
    "favorite adjectives": "onomatopoetic,whimsical"
  },
  {
    "participant": "Dragomir",
    "mood": "morose",
    "favorite adjectives": "megalomaniacal;ephemeral"
  }
]

…and you want your CSV to look as follows, using \n at the end of each line (as is standard on Linux and Mac)…

participant;mood;favorite adjectives
Iliana;rambunctious;onomatopoetic,whimsical
Dragomir;morose;"megalomaniacal;ephemeral"

…you can send the following request.

POST https://converter.stedi.com/2021-10-01/json_to_csv HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json

{
  "input": [
    {
      "participant": "Iliana",
      "mood": "rambunctious",
      "favorite adjectives": "onomatopoetic,whimsical"
    },
    {
      "participant": "Dragomir",
      "mood": "morose",
      "favorite adjectives": "megalomaniacal;ephemeral"
    }
  ],
  "options": {
    "delimiter": ";",
    "newline": "\n"
  }
}

Other options

Additionally, the converter provides the option include_header to produce CSV without headers.

Suppose you have JSON that looks as follows.

[
  {
    "participant": "Iliana",
    "mood": "rambunctious",
    "favorite adjective": "onomatopoetic"
  },
  {
    "participant": "Dragomir",
    "mood": "morose",
    "favorite adjective": "megalomaniacal"
  }
]

With include_header set to false, the output looks like this.

Iliana,rambunctious,onomatopoetic
Dragomir,morose,megalomaniacal

XML to JSON

This converter uses the element names in the XML as keys in the JSON. So, if you have XML like this…

<participants>
  <participant>
    <name>Iliana</name>
    <mood>rambunctious</mood>
    <favoriteAdjective>onomatopoetic</favoriteAdjective>
  </participant>

  <participant>
    <name>Dragomir</name>
    <mood>morose</mood>
    <favoriteAdjective>megalomaniacal</favoriteAdjective>
  </participant>
</participants>

…the resulting JSON looks like this.

"participants": {
  "participant": [
    {
      "name": "Iliana",
      "mood": "rambunctious",
      "favoriteAdjective": "onomatopoetic"
    },
    {
      "name": "Dragomir",
      "mood": "morose",
      "favoriteAdjective": "megalomaniacal"
    }
  ]
}

If multiple elements on the same level have the same name, they‘ll be turned into an array, as you can see with the <participant> elements in the example above. You can nest the data as deeply as you like.

Basic request

You convert XML by POSTing it to https://converter.stedi.com/2021-10-01/xml_to_json.

POST https://converter.stedi.com/2021-10-01/xml_to_json HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json

{
  "input": "<participants><participant><name>Iliana</name><mood>rambunctious</mood><favoriteAdjective>onomatopoetic</favoriteAdjective></participant><participant><name>Dragomir</name><mood>morose</mood><favoriteAdjective>megalomaniacal</favoriteAdjective></participant></participants>"
}

The response looks as follows.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "output": {
    "participants": {
      "participant": [
        {
          "name": "Iliana",
          "mood": "rambunctious",
          "favoriteAdjective": "onomatopoetic"
        },
        {
          "name": "Dragomir",
          "mood": "morose",
          "favoriteAdjective": "megalomaniacal"
        }
      ]
    }
  }
}

Attributes

By default, attributes in the XML are ignored, but you can change this by setting the ignore_attributes option to false. In that case, if an element has one or more attributes, the resulting JSON will be an object with a field for each attribute plus a field called #text for the inner text of the element. The keys of the attribute fields will have the prefix @_. Say you have the following XML.

<participants>
  <participant mood="rambunctious" favoriteAdjective="onomatopoetic">
    Iliana
  </participant>
  <participant mood="morose" favoriteAdjective="megalomaniacal">
    Dragomir
  </participant>
</participants>

You can send the following request to convert it.

POST https://converter.stedi.com/2021-10-01/xml_to_json HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json

{
  "input": "<participants><participant mood=\"rambunctious\" favoriteAdjective=\"onomatopoetic\">Iliana</participant><participant mood=\"morose\" favoriteAdjective=\"megalomaniacal\">Dragomir</participant></participants>",
  "options": {
    "ignore_attributes": false
  }
}

The response looks like this.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "output": {
    "participants": {
      "participant": [
        {
          "#text": "Iliana",
          "@_mood": "rambunctious",
          "@_favoriteAdjective": "onomatopoetic"
        },
        {
          "#text": "Dragomir",
          "@_mood": "morose",
          "@_favoriteAdjective": "megalomaniacal"
        }
      ]
    }
  }
}

There are two additional options that allow you to change the names the converter uses when dealing with attributes.

  • attribute_name_prefix specifies which character to put before the attribute name, instead of the default @_.
  • text_node_name specifies which name to use for the field that holds the inner text of an element, instead of the default #text.

With the following options…

"options": {
  "ignore_attributes": false,
  "attribute_name_prefix": "attribute.",
  "text_node_name": "name"
}

…the previous example results in the following JSON.

"participants": {
  "participant": [
    {
      "name": "Iliana",
      "attribute.mood": "rambunctious",
      "attribute.favoriteAdjective": "onomatopoetic"
    },
    {
      "name": "Dragomir",
      "attribute.mood": "morose",
      "attribute.favoriteAdjective": "megalomaniacal"
    }
  ]
}

Other options

Additionally, the converter provides the following options.

  • convert_node_types turns the inner text of elements into numbers and booleans where possible.
  • convert_attribute_types turns the values of attributes into numbers and booleans where possible.

Suppose you have XML that looks as follows.

<participants>
  <participant winner="true">
    <name>Iliana</name>
    <attempts>5</attempts>
  </participant>

  <participant winner="false">
    <name>Dragomir</name>
    <attempts>7.3</attempts>
  </participant>
</participants>

By default, with both options set to false, the result looks like this.

"participants": {
  "participant": [
    {
      "name": "Iliana",
      "attempts": "5",
      "@_winner": "true"
    },
    {
      "name": "Dragomir",
      "attempts": "7.3",
      "@_winner": "false"
    }
  ]
}

With both options set to true, the result looks like this.

"participants": {
  "participant": [
    {
      "name": "Iliana",
      "attempts": 5,
      "@_winner": true
    },
    {
      "name": "Dragomir",
      "attempts": 7.3,
      "@_winner": false
    }
  ]
}

Error handling

If you send input that Converter can‘t process, it will respond with a 422 Unprocessable Entity. The response body will contain more information about the error. For example, in the following CSV, not every row has the same amount of columns.

participant,mood,favorite adjective
Iliana,rambunctious,onomatopoetic,whimsical
Dragomir,morose

If you try to convert this to JSON, the response looks as follows.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "message": "Conversion failed due to errors parsing the input.",
  "errors": [
    {
      "code": "too_many_fields",
      "message": "Invalid input CSV.",
      "mitigation": "Line 2 in the input csv has too many fields.",
      "line": 2
    },
    {
      "code": "too_few_fields",
      "message": "Invalid input CSV.",
      "mitigation": "Line 3 in the input csv needs more fields.",
      "line": 3
    }
  ]
}

Every error contains a code that allows computers to process the error in code, and a message tells humans what‘s going on. Even though the response can include multiple errors, the converter may stop processing before it has found all the errors in the input.

Sending requests

Compression

Requests and responses aren‘t allowed to be larger than 6 MB. If you‘re dealing with large documents, you can use gzip compression and the limit will apply to the compressed data.

Converter will compress the response body if you include the Accept-Encoding in your request.

POST https://converter.stedi.com/2021-10-01/csv_to_json HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/json
Accept-Encoding: gzip

{
  "input": "participant,mood,favorite adjective\nIliana,rambunctious,onomatopoetic\nDragomir,morose,megalomaniacal"
}

To send a compressed request, you gzip the entire request body and set the Content-Type header to application/gzip.

POST https://converter.stedi.com/2021-10-01/csv_to_json HTTP/1.1
Authorization: Key $STEDI_API_KEY
Content-Type: application/gzip

<gzipped body>

Check out our code sample for help with implementing this.

Character encoding

Converter only supports UTF-8, so if your input is in any other character encoding, you will need to convert it to UTF-8 first. If your input is XML, then don‘t forget to update the encoding attribute in the XML header and set it to utf-8.

API Reference