JSON Input

CSV Output

CSV appears here

Paste a JSON array in the panel on the left and the rows are built as you go.

What a JSON to CSV converter has to get right

An API hands you a JSON array and the person who needs the data works in a spreadsheet. The conversion itself is not the interesting part — three lines of JavaScript will do something that looks like CSV. What separates a converter you can trust from one that quietly loses data is how it answers two questions: which columns exist, and what gets quoted.

On columns, the naive answer is to read the keys of the first record. That is wrong on real exports, where fields appear part-way through: given [{"msisdn":"447700900112"}, {"msisdn":"447700900187","roaming":true}], a first-record converter emits one column and the roaming flag is simply gone — no error, no warning. This page takes the union of keys across every record, so that file comes out with both columns and an empty cell where the first record had nothing.

On quoting, RFC 4180 only requires quotes around fields containing a comma, a quote or a newline. Every field here is quoted anyway, which is also legal and deliberate: a leading-zero reference code or a 19-digit ICCID written bare is re-typed as a number the moment a spreadsheet opens it, and 0044 becomes 44. Quoting everything costs a few bytes and stops that.

How to use the JSON to CSV converter

  1. Paste a JSON array – The input has to be an array — it starts with [ and holds objects. A single object needs square brackets around it first; a wrapper like {"results": [...]} needs the inner array pulled out.
  2. Watch the columns settle – Conversion runs about 300ms after you stop typing. The header row is the union of every key seen in every record, in the order they first appear, so a field that only shows up in record 400 still gets a column.
  3. Check the nested fields – A nested object is flattened with a dot: {"device": {"model": "Pixel 9"}} becomes a device.model column. Nesting can be any depth — a.b.c is a perfectly ordinary header here.
  4. Copy or download – Copy puts the text on your clipboard for a paste into Excel or Sheets; Download saves it as a .csv. Line endings are LF.
  5. Or load a file – Upload reads one .json file from your machine, re-indents it in the input pane and converts it. Nothing is sent anywhere — the file is read with FileReader in the page.

Pro Tip: Open the result in a text editor once before you send it to anyone. Spreadsheets hide quoting, so a field that came out as "[""n78"",""n28""]" looks tidy in Excel and is a JSON fragment in a cell — which is usually the moment you decide to flatten that array in the source data instead.

A worked example

Two SIM provisioning records. The nested device object becomes device.model and device.os, and every field is quoted — which is what keeps the 19-digit ICCIDs from being re-typed as numbers when the file is opened.

JSON array → CSV Convert
sims.jsonJSON · 2 records
[
  {
    "iccid": "8944501012345678901",
    "msisdn": "447700900142",
    "plan": "Unlimited 5G",
    "device": {
      "model": "Pixel 9",
      "os": "Android 15"
    }
  },
  {
    "iccid": "8944501019876543210",
    "msisdn": "447700900458",
    "plan": "Business 200GB",
    "device": {
      "model": "iPhone 17",
      "os": "iOS 19"
    }
  }
]
sims.csvCSV · 3 lines · 5 columns
"iccid","msisdn","plan","device.model","device.os"
"8944501012345678901","447700900142","Unlimited 5G","Pixel 9","Android 15"
"8944501019876543210","447700900458","Business 200GB","iPhone 17","iOS 19"

When you would reach for this

Handing API data to someone who lives in a spreadsheet

An analyst asks for "the numbers" and what you have is a paginated JSON response. Paste the array, download the CSV, send that. The one thing to check before you press send: open the file in a text editor and look at the header row. If a column you expected is missing it is not there in the data either — every key in every record gets a column here, so an absent header means an absent field.

Preparing a bulk import

MySQL's LOAD DATA INFILE, PostgreSQL's COPY and most admin tools take CSV. Two things bite on the way in. Quoted fields need the loader told about them — FIELDS ENCLOSED BY '"' in MySQL, which is not the default. And an empty cell is ambiguous: a JSON null and a key that simply was not present both come out as "", so if your table distinguishes NULL from empty string you will want to set that explicitly in the load statement rather than hope.

Getting log records into something you can pivot

Structured logs are objects, and objects are awful to eyeball in bulk. Converting a day's worth to CSV lets you sort by a field and see the shape of the data in about ten seconds. If the records are one-JSON-object-per-line rather than a single array, that is JSON Lines and our NDJSON to Table page reads it directly instead of asking you to wrap it in brackets first.

What it actually does

  • Columns are the union of every record – not the keys of record zero. A field that first appears half way down the file still gets a column, with empty cells above it.
  • Nested objects flatten with dots{"device":{"model":"Pixel 9"}} becomes a device.model column, at any depth.
  • Every field is quoted – legal under RFC 4180 and deliberate: it stops a leading-zero code or a 19-digit identifier being re-typed as a number by the receiving spreadsheet.
  • Long integers stay exact8944501012345678901 reaches the CSV with all 19 digits rather than the 8944501012345678000 a JavaScript number would give you.
  • Quoting matches the rest of the site – the same writer backs the CSV, Excel and HTML table exports, so two files from two pages escape identically.
  • The failure is specific – a syntax error reports its line and column with a jump-to link; a document that parses but is not an array says so rather than emitting an empty file.
  • Nothing is uploaded – the parse, the flatten and the download all happen in the page.

Questions people actually ask

Does my JSON need to be an array?

Yes — the top level has to be [ ... ]. A single object needs brackets around it. A wrapper such as {"results": [ ... ]}, which is how most paginated APIs answer, needs the inner array pulled out first; the page will tell you it is not an array rather than guessing which key you meant.

Why is every field wrapped in quotes?

Because unquoted CSV loses data on exactly the values developers care about. 0044 opens as 44, an ICCID becomes scientific notation, and 2026-05-12 becomes a date serial. Quoting every field is valid under RFC 4180 and is the cheapest defence against all three. The underlying reason a long identifier cannot survive a numeric round trip is the 53-bit mantissa MDN documents for JavaScript numbers; spreadsheets have their own version of the same limit. Note that Excel still ignores quoting on paste in some versions — importing the file rather than pasting it is the reliable route.

What if a value is itself an array?

It is serialised as JSON into the cell, then quoted like any other field. {"bands": ["n78","n28"]} comes out as "[""n78"",""n28""]" — the doubled quotes are RFC 4180's escaping, and a spreadsheet displays it as ["n78","n28"]. This is deliberate rather than a limitation: joining the items with commas would be indistinguishable from two separate values and unparseable on the way back. If you want one column per element, flatten the array in your source data first.

How large a file can I convert?

The conversion is linear and fast; what gets uncomfortable is the editor rendering a very large document while you scroll it. If you are working with an export big enough to notice, converting it with a script is the better tool — this page is for the ones you want to look at.

What happens to null and to missing keys?

Both become an empty cell. CSV has no way to say "absent" as distinct from "empty", so the information genuinely cannot survive the format. If the distinction matters, keep the JSON — JSON to Table shows the same data as a grid without flattening it into a format that cannot hold the difference.

Is my data safe?

Yes. The parse and the conversion both run in your browser; nothing is sent to a server, cached or logged. You can confirm it by watching the network panel while you type.

Related Tools

Useful Resources

  • JSON.org – Official JSON specification and documentation
  • RFC 4180 – The CSV memo. Short, and section 2 is the whole quoting rule.
  • MDN JSON Guide – Reference for parsing and serialising JSON in JavaScript.