Free tool JSON to CSV converter, and CSV back to JSON
Paste an API response, a JSON Lines export or a spreadsheet. Nested objects are flattened into dotted column names, quoting follows RFC 4180, and when a row is broken you get the line number instead of a silent mess.
- Both directions
- Excel-friendly output
- Runs locally
Convert JSON and CSV
The sample is three events in JSON Lines, the format TapCub data exports use. Swap direction to send the CSV back to JSON, open a file from your computer, or paste your own data.
JSON: an array of objects, one object, or JSON Lines (one object per line). CSV: comma, tab, semicolon or pipe separated.
Rows
3
Data rows, header not counted.
Columns
15
After flattening, or from the header.
Size (bytes)
428
UTF-8 size of the result, including the BOM if added.
Checks
- NoteRead as JSON Lines: 3 record(s), one per line.
- Note3 row(s) lack some columns; those cells are empty.
- OKConverted 3 row(s) into 15 column(s).
ts,type,name,path,utm_source,utm_medium,country,device_type,props.order_id,props.amount,props.currency,props.items,props.plan,props.coupon,props
2026-11-09T14:03:21.512Z,event,order_paid,/checkout,newsletter,email,US,desktop,A8841,199,USD,"[{""sku"":""PRO-12"",""qty"":1}]",,,
2026-11-09T14:05:02.004Z,event,signup,/pricing,google,cpc,GB,mobile,,,,,pro,,
2026-11-09T14:07:45.230Z,pageview,,/blog/utm-guide,,,DE,desktop,,,,,,,Table preview
First 20 rows. Long values are shortened here only.
| ts | type | name | path | utm_source | utm_medium | country | device_type | props.order_id | props.amount | props.currency | props.items | props.plan | props.coupon | props |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-11-09T14:03:21.512Z | event | order_paid | /checkout | newsletter | US | desktop | A8841 | 199 | USD | [{"sku":"PRO-12","qty":1}] | — | — | — | |
| 2026-11-09T14:05:02.004Z | event | signup | /pricing | cpc | GB | mobile | — | — | — | — | pro | — | — | |
| 2026-11-09T14:07:45.230Z | pageview | — | /blog/utm-guide | — | — | DE | desktop | — | — | — | — | — | — | — |
Version v1.0Updated Update history
What the converter tells you
Besides the converted text you get three counts, a list of checks with line numbers and a table preview of the first rows.
Rows and columns
In the sample, three events become three rows and 15 columns. The columns are the union of every key in every record, so props.order_id exists even though only one event has it; the other rows leave that cell empty.
Line numbers
CSV problems point to the physical line in your input, not the record number. A quoted field can span several lines, as in the spreadsheet sample, so record 3 can start on line 5. JSON Lines errors point to the line that failed.
Notes versus warnings
Notes describe a decision the converter made for you, such as the detected delimiter or a value kept as text. Warnings mean the input breaks a rule, such as a row with the wrong number of fields, and the output may not be what you expect.
Size
The UTF-8 byte count of the result. Flattening JSON to CSV usually shrinks it because keys are written once in the header; the BOM adds three bytes.
CSV has no types: everything is text until something interprets it. "Convert numbers" applies a conservative rule (plain decimals only, no leading zeros, nothing beyond 2^53). Turn it off when you need every value exactly as written.
Three steps
Nothing to install and nothing to click to run.
-
1
Paste or open
Paste JSON or CSV, or open a
.json,.jsonl,.csvor.tsvfile. Files are read in the browser; UTF-8, UTF-16 and GB18030 are detected. -
2
Pick the direction and options
For JSON → CSV choose how arrays are written and the delimiter your spreadsheet expects. For CSV → JSON decide whether to convert types and expand dotted headers.
-
3
Check, then copy or download
Read the checks first; fix any errors at the line shown. Then copy the result, download it, or swap direction to round-trip it.
How CSV and JSON map onto each other
CSV is described by RFC 4180, a short informational spec from 2005. Spreadsheets and libraries differ on the details, so the converter reads loosely and writes strictly.
- Output uses CRLF line endings and quotes a field only when it contains the delimiter, a quote or a line break
- A quote inside a quoted field is written twice:
"Kai ""KJ"" Jones" - Nested objects are joined with dots; the same rule run backwards rebuilds them
- Keys are collected in first-seen order, so the first record decides the column order
| JSON | CSV cell | Back to JSON (with type conversion) |
|---|---|---|
"A8841" | A8841 | "A8841" |
199 | 199 | 199 |
"02108" | 02108 | "02108" (leading zero kept as text) |
true | true | true |
null | empty | null |
{"plan": "pro"} | column props.plan = pro | {"props": {"plan": "pro"}} with dotted headers expanded |
[{"sku": "PRO-12"}] | "[{""sku"":""PRO-12""}]" | the array again, with JSON cells parsed |
Three events, one table
The sample JSON Lines run through the converter with the default options. Each nested key becomes its own column.
| Column | order_paid | signup | pageview |
|---|---|---|---|
| name | order_paid | signup | (empty) |
| utm_medium | cpc | (empty) | |
| props | — | — | (empty: props was null) |
| props.order_id | A8841 | — | — |
| props.amount | 199 | — | — |
| props.items | [{"sku":"PRO-12","qty":1}] | — | — |
| props.plan | — | pro | — |
| props.coupon | — | (empty: null) | — |
— means the key did not exist in that record; (empty) means it existed with a null value. Both become an empty cell, which is why a CSV cannot tell them apart. If that difference matters, keep the data as JSON.
Why converted files look wrong
Most "broken CSV" reports come from the program opening it, not from the file.
Garbled accents or CJK text in Excel
Excel on Windows opens a CSV with the system code page unless the file starts with a BOM. Tick "Add a BOM", or use Data → From Text/CSV and pick UTF-8.
IDs turned into 2.03E+18
Excel stores numbers with 15 significant digits. Order numbers, phone numbers and 64-bit IDs lose their tail. Import those columns as Text.
Everything in one column
In many European locales Excel expects semicolons because the comma is the decimal separator. Choose the semicolon delimiter, or add a sep=, line.
Formulas from user input
A value such as =HYPERLINK(…) from a form or URL can run when the CSV is opened. OWASP calls this CSV injection; turn on formula protection for untrusted data.
Your event data, out in JSON Lines or CSV
Events reach TapCub from the web script, the platform SDKs and the server API, each with its own properties. When you need the raw rows elsewhere, data export and the open API hand them back.
Data export
On Pro, the open API exports events, sessions, people, interactions or consent records for a date range as gzip JSON Lines or CSV, downloadable for 48 hours.
Learn moreSDKs and server API
Web, app, mini-program and server events share one schema, so the columns you get are the same across platforms.
Learn moreData-quality checks
Unexpected event names, missing properties and wrong types are flagged on arrival, before they reach an export.
Learn moreJSON to CSV questions
Still have a question?
Chat with the team behind TapCub — we usually reply within a few hours on business days.
How do I convert JSON to CSV?
Paste the JSON, keep the direction on JSON → CSV and copy or download the result. An array of objects becomes one row per object with a column per key. Nested objects become dotted columns such as props.amount; arrays are kept as JSON in one cell unless you choose one column per item.
How do I convert CSV to JSON?
Switch the direction to CSV → JSON and paste the CSV. The delimiter is detected automatically and the first row is used as keys. Turn on type conversion to get numbers and booleans instead of strings, and dotted headers to rebuild nested objects.
Can it convert JSON Lines (NDJSON)?
Yes. If the input is not one JSON value but every line is, it is read as JSON Lines. TapCub data exports, many log pipelines and BigQuery exports use this format. Lines that fail are listed by line number and left out.
Why does my CSV show strange characters in Excel?
The file is UTF-8 but Excel opened it with a legacy code page. Download with "Add a BOM" ticked, or import through Data → From Text/CSV and choose UTF-8. Google Sheets and Numbers read UTF-8 without a BOM.
What happens to nested objects and arrays?
Objects are flattened: {"user": {"id": 7}} becomes a user.id column. Arrays have three options: the whole array as JSON text in one cell, one column per item (items.0.sku, items.1.sku), or simple values joined with semicolons.
Why did a number like 02108 or a long ID stay as text?
Because converting it would change it. 02108 would become 2108, and integers above 9,007,199,254,740,991 cannot be stored exactly in JavaScript. Values with a decimal point, such as 199.00, become 199.
Is there a size limit?
Files up to 10 MB can be opened; pasted text has no fixed limit but very large inputs make the page slow. The preview shows the first 20 rows; the output always contains every row.
Is my data uploaded?
No. Parsing and conversion happen in your browser, files are read locally, and the tool has no share link, so nothing you paste ends up on a server or in a URL.
Update history
New features, fixes and data refreshes for this tool, newest first.
-
· v1.0
LaunchedFirst release.
Missing something or found an error? Tell us — requests that come up often go into the next update. All tool updates
Collect events you can export cleanly
Connect your site or app, send events with consistent properties, and export the raw rows whenever another tool needs them.