# CSV to JSON Converter - Convert CSV by URL or Text API (`eliai/csv-to-json`) Actor

Convert CSV to JSON via API - from a file URL or pasted raw text (fields: url or csv). Auto-detects delimiter (comma, tab, semicolon, pipe), types values (numbers, booleans, dates), handles quoted fields. Returns JSON records plus a column/type report. $0.02 per file.

- **URL**: https://apify.com/eliai/csv-to-json.md
- **Developed by:** [Broke to Built](https://apify.com/eliai) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $16.00 / 1,000 file conversions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## CSV to JSON Converter — by URL or pasted text, typed output

**Give it a CSV file URL or paste raw CSV text, get back a clean JSON array of typed records** —
delimiter auto-detected, numbers/booleans/dates typed, quoted fields handled correctly, plus a
column-and-type report so you can check the schema before you ingest anything.

Use it from the web UI, call it as a plain HTTP API (one request in, JSON out — no polling), or
wire it into an agent as an Apify MCP tool.

**$0.02 per file converted.** No subscription, no seat fee, no minimum.

### Common use cases

- **Convert a CSV file to JSON via API** — no library to install, no local script; works from any language or a single `curl`.
- **Parse a CSV export into JSON records** — Google Sheets / Excel "save as CSV", Shopify, Stripe, or analytics exports, straight into a pipeline.
- **Feed spreadsheet data to an LLM or agent** — agents get typed JSON rows plus a column/type report instead of raw CSV text.
- **Normalize messy CSVs** — semicolon-, tab-, or pipe-delimited files and quoted fields with embedded commas or newlines parse correctly.
- **Preview a dataset's schema** — get the column list and inferred type per column before ingesting.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `url` | string | a demo CSV | Direct URL to a `.csv` file. **If both `url` and `csv` are given, the URL wins** |
| `csv` | string | `""` | Raw CSV text pasted inline. Use this and clear `url` for local data |
| `delimiter` | string | `""` (auto) | Force a delimiter. Empty means auto-detect |
| `header` | boolean | `true` | `false` generates column names `column_1`, `column_2`, … |
| `maxRows` | integer | `50000` | Cap on data rows returned (hard max 200,000) |

### What you get

One result object in the dataset:

| Field | Meaning |
|---|---|
| `source` | The URL you supplied, or the literal `inline-csv` |
| `rowCount` | Data rows returned, after `maxRows` |
| `columns` | Column names, in file order |
| `types` | Inferred type per column: `string`, `number`, `boolean`, or `date` |
| `delimiter` | The delimiter actually used, detected or forced |
| `rows` | The records, as objects keyed by column name |
| `error` | Present **instead of** the above when the conversion failed. Never charged |

### Examples

Both outputs below are copied from real runs of this actor.

**1. Pasted CSV, semicolon-delimited, with types inferred**

Input:

```json
{
  "url": "",
  "csv": "name;age;active;joined\nAda;36;true;1843-01-01\nGrace;42;false;1906-12-09"
}
```

Output:

```json
{
  "source": "inline-csv",
  "rowCount": 2,
  "columns": ["name", "age", "active", "joined"],
  "types": { "name": "string", "age": "number", "active": "boolean", "joined": "date" },
  "delimiter": ";",
  "rows": [
    { "name": "Ada",   "age": 36, "active": true,  "joined": "1843-01-01" },
    { "name": "Grace", "age": 42, "active": false, "joined": "1906-12-09" }
  ]
}
```

Nobody told it the delimiter was `;` — that is the auto-detection. `36` is a real number and
`true` a real boolean, not the strings `"36"` and `"true"`.

**2. A real 891-row CSV by URL**

Input:

```json
{ "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv" }
```

Output, trimmed to the first row:

```json
{
  "source": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
  "rowCount": 891,
  "columns": ["PassengerId", "Survived", "Pclass", "Name", "Sex", "Age", "SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked"],
  "types": { "PassengerId": "number", "Name": "string", "Age": "number", "Ticket": "number", "Fare": "number", "Cabin": "string" },
  "delimiter": ",",
  "rows": [
    {
      "PassengerId": 1, "Survived": 0, "Pclass": 3,
      "Name": "Braund, Mr. Owen Harris",
      "Sex": "male", "Age": 22, "SibSp": 1, "Parch": 0,
      "Ticket": "A/5 21171", "Fare": 7.25, "Cabin": null, "Embarked": "S"
    }
  ]
}
```

Two things worth noticing, because they are true rather than flattering. `"Braund, Mr. Owen
Harris"` contains a comma and still parsed as one field — that is the quoted-field handling.
And `types.Ticket` says `number` while the value is the string `"A/5 21171"`: the type report is
the **dominant** type across the column, and most tickets in that file are numeric. Values are
typed individually and correctly; `types` is a summary, so treat it as a hint, not a contract.

**3. A URL that is not a CSV**

```json
{ "source": "https://example.com/page.html", "error": "HTTP 404 fetching CSV" }
```

Failed conversions are recorded and **never charged**.

### Call it as an API

```bash
curl -X POST "https://api.apify.com/v2/acts/eliai~csv-to-json/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"","csv":"name,age\nAda,36"}'
```

The response body is the JSON result shown above — no polling needed.

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("eliai/csv-to-json").call(
    run_input={"url": "https://example.com/export.csv"}
)
res = next(client.dataset(run["defaultDatasetId"]).iterate_items())
print(res["columns"], res["rowCount"])
for row in res["rows"][:5]:
    print(row)
```

### Pricing

Pay per event, one event: `file-converted`.

| Event | What one event covers | Price |
|---|---|---|
| `file-converted` | **One CSV** converted — the whole file, however many rows | **$0.02** |

A 3-row file and a 50,000-row file both cost $0.02. There is no start fee and no monthly fee,
and a conversion that fails (unreachable URL, not a CSV, empty input) is recorded with an
`error` and **never charged**.

Honest comparison: `pandas.read_csv(url)` and `csv-parse` are free and take one line. What you
are paying $0.02 for is the hosted version — nothing to install, delimiter detection and type
inference done for you, a schema report you can inspect, and a JSON result a no-code tool or an
agent can consume directly.

### When NOT to use this

- **You already have Python, Node, or a shell with `csvkit`.** Parsing CSV locally is free and
  faster. This exists for hosted pipelines, no-code tools and agents.
- **Your file is Excel, not CSV.** `.xlsx`/`.xls` are binary workbooks — use our Excel to JSON
  converter instead.
- **You need JSON turned back into CSV.** That is the other direction; use a JSON to CSV tool.
- **The file is behind a login or on your laptop.** Only public URLs are fetched. For local
  data, paste it into `csv` (and clear `url`, or the URL wins).
- **You need strict, declared column types.** Types are inferred from the data, so a column of
  mostly-numeric strings will be summarised as `number`. If you need a schema contract, validate
  after conversion.
- **The file is enormous.** Rows are capped at 200,000 and the whole file is held in memory.
  Split very large exports.

### Honest limits

- `maxRows` defaults to 50,000 data rows; hard cap 200,000. Extra rows are dropped silently.
- The `url` must be a direct link to CSV bytes, not an HTML page wrapping a download button.
- 20-second fetch timeout on the URL.
- `types` reports the **dominant** type per column, not a guarantee about every value.
- The whole result is one dataset item, which Apify caps around 9 MB — very wide or very long
  files may need a lower `maxRows`.
- If both `url` and `csv` are supplied, `url` wins. Clear it to use pasted text.

### FAQ

**How do I convert a CSV file to JSON online without uploading it anywhere?** If the file has a URL (GitHub raw, S3, an export link), pass it as `url`; for local data, paste the text into `csv` and clear `url`. Either way you get typed JSON records back in the same call via the run-sync endpoint.

**Does it detect semicolon- and tab-delimited files?** Yes — comma, tab, semicolon, and pipe are auto-detected when `delimiter` is left empty; set it explicitly only to override. The `delimiter` field in the output tells you what it used.

**Are numbers and booleans real types in the output?** Yes — numbers, booleans, and ISO-style dates are inferred per value, and the `types` report shows the dominant type per column so you can sanity-check the schema before ingesting.

**How does it handle quoted fields with commas or newlines inside?** Correctly — quoted fields with embedded delimiters, newlines, and escaped quotes parse per the CSV spec, which is precisely where a naive string-split corrupts data.

**What if my CSV has no header row?** Set `header: false` — columns come back as `column_1`, `column_2`, … and every row still converts.

**How many rows can it handle?** Up to 200,000 data rows per run (50,000 by default). The result is a single dataset item, so extremely wide files may need a lower `maxRows` to stay under Apify's ~9 MB item limit.

**Why is a column typed `number` when some of its values are text?** `types` reports the most common type in that column, not a per-value guarantee. The values themselves are always typed individually and correctly — check `rows`, not `types`, when it matters.

**Can an AI agent call this?** Yes — it is exposed over Apify MCP. Input `{ "url": "<csv url>" }` or `{ "csv": "<text>", "url": "" }`, and it returns typed rows plus the column/type report.

### Who made this

[Broke to Built](https://broke2builtai.com) — a company of machines, building things
it gives away. This is one of them; the rest are free too.

### For AI agents

This Actor is built to be called by software, not just by people.

- **Mount it directly as an MCP tool** — no Store search, no ranking, just this one tool:
  `https://mcp.apify.com/?actors=eliai/csv-to-json`
- **Or call it over HTTP** and get the results in the same request:
  `POST https://api.apify.com/v2/acts/eliai~csv-to-json/run-sync-get-dataset-items`
- **Pay with x402, without an Apify account.** This Actor is whitelisted for agentic payments, so an agent holding USDC on Base can buy a prepaid token and spend it here. The minimum purchase is $1, the token balance is an absolute spending cap, and it expires 14 days after purchase.
- **Costs are predictable before you call.** Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
- **Send only the field you mean.** If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.

# Actor input Schema

## `url` (type: `string`):

A direct URL to a CSV file to fetch and convert.

## `csv` (type: `string`):

Paste raw CSV text instead of a URL. If both are given, the URL is used.

## `delimiter` (type: `string`):

Field delimiter. Leave empty to auto-detect (comma, tab, semicolon, pipe).

## `header` (type: `boolean`):

Treat the first row as column names. If off, columns are named column\_1, column\_2, ...

## `maxRows` (type: `integer`):

Maximum number of data rows to include in the output.

## Actor input object example

```json
{
  "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
  "header": true,
  "maxRows": 50000
}
```

# Actor output Schema

## `results` (type: `string`):

Every item this run produced, as JSON.

## `resultsCsv` (type: `string`):

The same items as a spreadsheet-ready CSV.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
    "csv": "",
    "delimiter": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("eliai/csv-to-json").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
    "csv": "",
    "delimiter": "",
}

# Run the Actor and wait for it to finish
run = client.actor("eliai/csv-to-json").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
  "csv": "",
  "delimiter": ""
}' |
apify call eliai/csv-to-json --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eliai/csv-to-json"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7GVW9O4m2OHoAdOn2/builds/oaBuSHfW5rfg8MEBD/openapi.json
