JSON to CSV
Turn a list of records into a spreadsheet-ready CSV: in the example, Ada and Alan become 2 rows under three columns, the note with a comma stays in one cell, and the values each record lacks are left blank. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
flatten to a spreadsheet, free online
From records to rows and columns
A spreadsheet is a grid: one record per line and one value per cell. This tool takes a list of records and gives each one its own row, and every name that appears in any record becomes a column, in the order it first shows up, so nothing is dropped when the records do not share all their fields. In the example, the records for Ada and Alan produce three columns, nombre, nota and extra. Ada has no extra value and Alan has no note, so those two cells stay empty, and the result also tells you how many rows and which columns were written.
Commas, separators and the shape of your data
A value that contains the separator, a double quote or a line break is wrapped in double quotes, so a note such as the one in the example stays in one cell instead of pushing the rest of the row one column to the right. The comma is the default separator, and you can choose another one, such as a semicolon, if that is what your spreadsheet expects. The tool works with flat records: a section nested inside a record is not unfolded into its own columns, so flatten nested data first. The finished file can go straight to a team that filters, sorts and reports in a spreadsheet.
What you can do with it
CRM data handoff
Turn nested customer records, including arrays of contacts or interactions, into a flat CSV a sales team can import into their existing tools.
FAQ
What happens when my records do not all have the same fields?
Every name that appears in any record becomes a column, and a record that lacks one simply gets an empty cell there. In the example, Alan has no note and Ada has no extra value, so each of those cells stays blank.
What happens to a value that contains a comma?
It is wrapped in double quotes so it stays in a single cell instead of spilling into the next column. The note in the example comes out quoted for that reason, and any double quote inside a value is doubled so the file still reads correctly.
In what order do the columns appear?
In the order the names first show up, reading the records from the top. In the example, the first record brings the name and the note, the second adds extra, so the header reads nombre, nota, extra.
What shape does my data need to have?
A list of flat records, one per future row. A section nested inside a record is not spread into separate columns, so if your data has nested parts, flatten them first and then convert the result.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/data/json-to-csv \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"rows":[{"nombre":"Ada","edad":36}]}'const res = await fetch("https://api.kit.forhosting.com/data/json-to-csv", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"rows": [
{
"nombre": "Ada",
"edad": 36
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/data/json-to-csv",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"rows": [
{
"nombre": "Ada",
"edad": 36
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/data/json-to-csv", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"rows":[{"nombre":"Ada","edad":36}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"rows":[{"nombre":"Ada","edad":36}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/data/json-to-csv", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"rows": [
{
"nombre": "Ada",
"edad": 36
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "data.json_to_csv",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
The moment your JSON has a nested object or an array inside a field, "just convert it to CSV" stops being trivial — a spreadsheet has no native concept of a document within a cell. This endpoint flattens nested JSON into consistent, well-named columns, so the file that comes out opens cleanly in any spreadsheet tool instead of showing a wall of unreadable bracket-and-brace text.
The mismatch between documents and rows
CSV has no way to express that — it is fundamentally a grid of rows and columns, one flat record per line. JSON is built to nest: an order can contain a customer object, which contains an address object, which contains an array of previous orders, each with its own line items. Anyone who has tried to hand-roll this conversion knows the usual failure mode: a naive tool just calls JSON.stringify on the nested part and dumps a blob of escaped curly braces into a single cell, which technically "works" but produces a spreadsheet nobody can filter, sort or open in a reporting tool.
How the flattening actually behaves
Send your JSON array or document to POST /data/json-to-csv and nested objects are unrolled into dot-notated columns — an address.city field sits next to address.country rather than being buried inside a single blob — while arrays of scalar values are joined predictably and arrays of objects are expanded according to a strategy suited to the shape of your data, so line items in an order become their own set of readable columns instead of an opaque string. Column headers are derived directly from the structure of your JSON, keeping the mapping between source field and output column obvious to anyone opening the file later.
Why this still matters when everything is an API
Finance teams reconcile in spreadsheets, operations teams build pivot tables from them, and plenty of business tools still only accept CSV as an import format. It would be easy to assume CSV is a legacy concern now that most systems exchange JSON natively, but the spreadsheet remains the interface non-technical stakeholders actually trust. Converting API output into CSV is less about technology and more about meeting people where they already work.
Handling irregular records without breaking the grid
The conversion reconciles differing shapes across records into a single consistent header row, filling absent fields rather than shifting columns out of alignment, which is the single most common way hand-written converters silently corrupt a spreadsheet. Real JSON collections are rarely perfectly uniform — one order has a discount field and the next does not, one customer record has three phone numbers and another has none.
Fitting into automated reporting
Because the task runs asynchronously, it works well at the end of a reporting pipeline: pull records from your application's API, convert the resulting JSON to CSV here, and deliver the file straight to an analyst's inbox or a shared drive without a script babysitting the transformation. You receive a task_id right away and the CSV lands by webhook, ready to attach or forward.
Integration use cases
Weekly finance export
Convert order or transaction JSON pulled from your API into a CSV that finance can open directly in a spreadsheet for reconciliation.
Analytics tool import
Flatten event or log JSON into CSV for business intelligence tools that only accept tabular import files.
Client deliverable
Package API results as a clean CSV attachment for a non-technical client instead of sending raw JSON they cannot open.
Technical questions
How does this JSON to CSV API handle nested objects?
Nested objects are flattened into dot-notated columns, such as address.city, so every value gets its own readable column instead of being embedded as raw JSON text.
What happens to arrays inside my JSON?
Arrays of simple values are joined predictably within a column, and arrays of objects, like order line items, are expanded into their own set of columns rather than collapsed into an unreadable string.
Can it handle JSON records with inconsistent fields?
Yes, the conversion reconciles differing record shapes into one consistent header row, filling missing fields so columns never shift out of alignment.
Is there a free trial for the JSON to CSV endpoint?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
Can I convert large JSON arrays with thousands of records?
Yes, submit the array as an async request and it processes as a single task; for very large or recurring exports, batching by date range or ID is a common pattern.
What if the JSON to CSV conversion fails?
It automatically retries up to three times; if it still fails, you get a clear error and are not charged for the attempt.
How do I retrieve the generated CSV file?
Via a signed webhook, recommended for pipelines, or a signed link valid for 24 hours if you want to download it manually.
How much does converting JSON to CSV cost?
$0.002 per request, billed only when the conversion completes successfully.