JSON to CSV Converter
Pricing
Pay per event
JSON to CSV Converter
Convert pasted JSON, public JSON files, and API responses into flattened CSV rows with configurable paths, columns, arrays, and delimiters.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Turn pasted JSON, public JSON files, and API responses into a clean CSV file with an Apify dataset summary for every converted source.
This JSON to CSV converter handles nested objects, record paths, arrays, selected columns, and spreadsheet-friendly delimiters without requiring Python or a local conversion tool.
Use it for one-off exports or schedule it as a repeatable step in a data pipeline.
What does JSON to CSV Converter do?
The Actor can:
- parse JSON pasted directly into the input;
- download JSON from up to 20 public HTTP(S) URLs;
- select records from nested responses with a dot or bracket path;
- flatten nested objects into columns such as
customer.name; - stringify, join, or expand arrays;
- preserve a requested column order;
- write comma, semicolon, tab, or pipe-delimited files;
- add a UTF-8 BOM for Excel;
- stop at a configured row limit;
- fail closed or skip individual invalid sources;
- save the finished file as
OUTPUT.csv; - push one dataset summary with a row preview for every converted source.
No browser or proxy is used.
Who is this converter for?
Data analysts
Convert API snapshots and vendor exports into CSV for Excel, Google Sheets, Power BI, or Tableau.
Developers
Replace a small JSON-to-CSV Python script with an API-callable Actor that has scheduling, logs, storage, and webhooks.
Operations teams
Normalize recurring JSON feeds into a predictable set of columns before importing them into a CRM or reporting workflow.
AI agents
Call the Actor through Apify MCP, then retrieve a CSV artifact or structured source summary for the next tool step.
Why use it on Apify?
A browser-only online converter is useful for a small manual file.
This Actor is designed for repeatable automation:
- inputs are saved as reusable Tasks;
- runs can be scheduled;
- results have stable API links;
- each converted source has a typed dataset summary and row preview;
- webhooks can trigger downstream systems;
- invalid inputs produce explicit run failures instead of silent partial files.
Input data is processed only for the run and stored in the run's Apify storage.
Getting started
- Open the Actor input page.
- Paste JSON into Paste JSON, or add one or more public JSON URLs.
- Set Record path when the records are nested inside an API envelope.
- Choose how nested objects and arrays should be handled.
- Optionally list the exact columns and their order.
- Set a safe Maximum output rows value.
- Click Start.
- Download OUTPUT.csv from the Output tab.
- Use the default dataset when a downstream integration needs source-level counts, columns, and row previews.
The prefilled input converts two real biographical names under the records path and succeeds without network access.
Input parameters
| Field | Type | Default | Description |
|---|---|---|---|
jsonText | string | prefilled JSON | JSON array, object, or response pasted as text. |
jsonUrls | array | empty | Up to 20 public HTTP(S) JSON file or API URLs. |
recordPath | string | records | Dot/bracket path to the records, such as data.items or [1]. Empty means the JSON root. |
flatten | boolean | true | Flatten nested objects into named columns. |
flattenSeparator | string | . | Separator between nested field names. |
arrayMode | string | stringify | Store arrays as JSON, join values, or expand them into rows. |
arrayJoinSeparator | string | ` | ` |
columns | string[] | all discovered | Ordered allowlist of output columns. |
delimiter | string | comma | comma, semicolon, tab, or pipe. |
includeBom | boolean | false | Add a UTF-8 BOM for Excel compatibility. |
maxRows | integer | 10000 | Global row limit from 1 to 100,000. |
onError | string | fail | Fail the run or skip bad sources. |
Provide at least one of jsonText or jsonUrls.
When both are provided, the inline JSON is processed first and every source uses the same conversion settings.
Selecting records with recordPath
Many APIs wrap records in an envelope.
Given:
{"meta": { "page": 1 },"data": {"items": [{ "id": 101, "status": "open" },{ "id": 102, "status": "closed" }]}}
Use:
{"recordPath": "data.items"}
Bracket notation is also supported:
[1]selects the second element of a top-level array;results[0].itemsselects a nested array;data["items"]selects a named property.
A missing path fails with the exact path segment that could not be resolved.
Flattening nested JSON
With flatten: true, this record:
{"id": 1,"customer": {"name": "Ada Lovelace","country": "GB"}}
becomes these CSV columns:
id,customer.name,customer.country
Change flattenSeparator to _ to produce customer_name instead.
With flattening disabled, nested objects are stored as JSON strings in their parent column.
Handling arrays
Stringify
stringify preserves the complete array as compact JSON in one cell.
This is the safest default for arrays of objects.
Join
join combines array values in one cell with arrayJoinSeparator.
Objects inside an array are JSON-encoded before joining.
Expand
expand creates one row per array value.
When several columns contain arrays, expansion produces their Cartesian combinations.
Use maxRows to bound that result.
A single source cannot expand beyond 100,000 intermediate rows.
Choosing and ordering columns
Leave columns empty to use every field in first-seen order.
Provide columns when a downstream system expects a stable schema:
{"columns": ["id","customer.name","status","updated_at"]}
Missing requested fields are written as empty CSV cells and null values in dataset row previews.
Extra source fields are omitted.
Output
Each successful run creates three outputs:
- CSV file —
OUTPUT.csvin the default key-value store; - source summaries — one item per converted source in the default dataset;
- run summary —
OUTPUTin the default key-value store.
A representative dataset item is:
{"source": "https://api.worldbank.org/v2/country/USA/indicator/NY.GDP.MKTP.CD?format=json&per_page=10","rowCount": 10,"columns": ["country.value", "indicator.value", "date", "value"],"preview": [{"country.value": "United States","indicator.value": "GDP (current US$)","date": "2025","value": 30769700000000}]}
| Output field | Meaning |
|---|---|
source | inline:jsonText or the public URL converted successfully. |
rowCount | Number of rows this source contributed to OUTPUT.csv. |
columns | Ordered CSV columns shared by the final file. |
preview | Up to three normalized rows from this source. |
The run summary includes total row and column counts, column names, input and converted source counts, skipped-source errors, and a direct CSV download URL.
CSV correctness and types
The renderer follows common RFC 4180 conventions:
- fields containing delimiters, quotes, or newlines are quoted;
- embedded quotes are doubled;
- rows use CRLF line endings;
nulland missing values become empty cells;- numbers and booleans remain typed in dataset row previews;
- the CSV file contains their textual form.
The downloadable filename is always OUTPUT.csv, including when tab or pipe is selected.
How much does it cost to convert JSON to CSV?
Pricing has one $0.0005 start event per run plus one event for each JSON source converted successfully.
Pasted jsonText counts as one source. Each successful jsonUrls entry counts as one source, regardless of how many rows it contains. Failed, empty, or skipped sources do not emit the source event.
Current source prices decrease by Apify subscription tier:
| Tier | Price per converted source |
|---|---|
| Free | $0.0184 |
| Bronze | $0.016 |
| Silver | $0.01248 |
| Gold | $0.0096 |
| Platinum | $0.0064 |
| Diamond | $0.00448 |
Examples before any Apify platform-usage tax:
| Sources in one run | Free tier | Bronze tier |
|---|---|---|
| 1 | $0.01890 | $0.01650 |
| 5 | $0.09250 | $0.08050 |
| 20 | $0.36850 | $0.32050 |
A 1,000-row file and a 10-row file each use one source event when converted successfully.
Public URL safety and limits
Only http:// and https:// URLs are accepted.
The Actor rejects:
- URLs containing embedded usernames or passwords;
- localhost and private-network destinations;
- redirects to private-network destinations;
- responses larger than 10 MB;
- more than five redirects;
- non-success HTTP responses;
- invalid JSON response bodies.
Each request has a 30-second timeout.
HTTP 429 and 5xx responses are retried twice with bounded backoff.
The Actor does not use an Apify proxy and cannot access authenticated or private APIs.
Error handling
The default onError: fail behavior is best for trustworthy pipelines.
The run fails when any source is invalid, unavailable, oversized, or missing the selected record path.
Use onError: skip only when partial output is acceptable.
Skipped source names and error messages are written to the OUTPUT summary.
If every source fails or produces no rows, the run fails even in skip mode.
No source event is emitted for failed, empty, or skipped input.
Scheduling recurring conversions
Create an Apify Task with a stable public API URL and fixed columns.
Then:
- set an hourly, daily, or weekly schedule;
- configure a webhook for
ACTOR.RUN.SUCCEEDED; - send the CSV download URL or source-summary dataset ID to your destination;
- retain run storage according to your Apify plan;
- compare successive datasets with your preferred diff workflow.
The Actor converts the current response on every run; it does not maintain change history or send alerts by itself.
Spreadsheet and data-pipeline workflows
Common patterns include:
- JSON API → scheduled Actor Task → Google Sheets integration;
- vendor JSON file →
OUTPUT.csv→ S3 or cloud drive; - webhook payload archive →
OUTPUT.csv→ data warehouse; - World Bank API → selected indicators → BI dashboard;
- GitHub issues API → joined labels → recurring operations report;
- Apify MCP → conversion run → CSV link returned to an AI assistant.
Use columns to prevent schema drift when an upstream API adds fields.
API usage with cURL
Start a run and wait for completion:
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~json-to-csv-converter/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"jsonUrls": [{"url": "https://api.github.com/repos/apify/apify-sdk-js/releases?per_page=5"}],"recordPath": "","columns": ["tag_name", "name", "published_at", "html_url"],"maxRows": 5}'
The synchronous dataset endpoint returns one source summary per successful input. Retrieve OUTPUT.csv for all normalized rows.
Use the run's default key-value store to retrieve OUTPUT.csv.
API usage with JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/json-to-csv-converter').call({jsonText: JSON.stringify({ records: [{ id: 1, status: 'active' }] }),recordPath: 'records',columns: ['id', 'status'],});const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT');console.log(summary.value.csvDownloadUrl);
API usage with Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("automation-lab/json-to-csv-converter").call(run_input={"jsonUrls": [{"url": "https://api.worldbank.org/v2/country/USA/indicator/NY.GDP.MKTP.CD?format=json&per_page=10"}],"recordPath": "[1]","columns": ["country.value", "date", "value"],"maxRows": 10,})record = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT.csv")with open("world-bank-gdp.csv", "wb") as file:file.write(record["value"])
Use with Apify MCP
Claude Code
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/json-to-csv-converter"
Claude Desktop, Cursor, and VS Code
Claude Desktop, Cursor, and VS Code clients can use this HTTP MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/json-to-csv-converter"}}}
Example prompts:
- “Convert this public World Bank JSON URL to CSV and keep country, date, and value.”
- “Flatten the pasted response at
data.items, join tags, and return the CSV download URL.” - “Create an Apify Task that exports these GitHub issues to CSV every Monday.”
Legality and responsible use
Only submit data that you are authorized to process.
For public URLs, respect the source's terms, access policies, rate limits, privacy requirements, and applicable law.
Do not use this Actor to bypass authentication or access controls.
Avoid placing secrets in URL query strings because run inputs and logs may be retained in your Apify account.
For sensitive inline JSON, configure appropriate storage retention and access controls.
Limitations
- JSON Lines / NDJSON is not supported; input must be one valid JSON document.
- Each inline or downloaded source is limited to 10 MB.
- A run accepts at most 20 URLs and 100,000 output rows.
- Input sources are processed sequentially.
- URLs must be publicly reachable without credentials.
expandcan multiply rows when several arrays exist in one record.- Object keys are used as column names; duplicate paths after custom separator changes may overwrite one another.
- CSV cannot preserve JSON type distinctions as fully as the typed values shown in dataset previews.
- The Actor does not write directly to Google Sheets or a database.
- The Actor does not monitor changes or send alerts without an Apify schedule and downstream integration.
Troubleshooting
“Provide jsonText or at least one jsonUrls entry”
Add pasted JSON or at least one public JSON URL.
“Record path was not found”
Inspect the response shape and set the path to the array or object containing records.
Use an empty path when the JSON root is already the desired array.
A URL works in my browser but fails here
Confirm it is public, returns JSON without cookies or authentication, stays below 10 MB, and does not redirect to a private address.
The CSV has one row instead of many
Set recordPath to the array inside the response rather than its parent object.
The CSV has too many rows
Switch array handling from expand to stringify or join, or lower maxRows.
Excel displays non-English characters incorrectly
Enable includeBom.
I need stable columns between runs
Supply an explicit ordered columns list.
FAQ
Can I convert a local JSON file?
Upload the file somewhere publicly reachable or paste its content into jsonText.
Apify key-value-store record URLs also work when they are publicly accessible.
Can I combine multiple JSON files?
Yes. Add up to 20 URLs. Their converted rows are appended in source order and share one CSV header.
Does it support a top-level JSON object?
Yes. A single object becomes one CSV row unless recordPath selects an array.
Does it preserve nested objects?
Yes. Flatten them into named columns or disable flattening to store them as JSON strings.
Are failed sources charged?
No source event is emitted for input that fails parsing or fetching, or produces no accepted rows.
The one-time run start event still applies.
Can it produce TSV?
Yes. Select the tab delimiter. The storage key remains OUTPUT.csv.
Can it infer and enforce data types?
Numbers and booleans remain typed in Apify dataset row previews, but this Actor does not infer a separate schema or validate business-level types.
Is a proxy required?
No. The Actor uses direct requests to public JSON URLs only.
Related Automation Lab Actors
- XML to JSON Converter for XML ingestion workflows.
- VCF Contact File Parser for contact-file normalization.
- CSV Diff Tool for comparing recurring tabular exports.
- Dataset Dedup for removing duplicate records in downstream datasets.
Choose JSON to CSV Converter when the source is already valid JSON and the goal is a normalized tabular export.