# JSONL / NDJSON to CSV — streaming converter (`stellar_ballet_0bu/jsonl-to-csv`) Actor

Stream a JSONL/NDJSON document (inline text or public URL) into a CSV. Auto-discovers columns from the union of all keys in document order of first appearance. No scraping required when text is provided inline.

- **URL**: https://apify.com/stellar\_ballet\_0bu/jsonl-to-csv.md
- **Developed by:** [Nikita S](https://apify.com/stellar_ballet_0bu) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## JSONL / NDJSON to CSV Converter

Stream a JSONL/NDJSON document (inline text or public URL) into a CSV. Auto-discovers columns from the union of all keys in document order of first appearance, with optional explicit column list and stable ordering. Pure data utility, no HTTP scraping required when text is provided inline.

- **Inputs**: `text` (inline JSONL) or `textUrl` (public JSONL file), `columns` (optional explicit list), `delimiter` (default `,`), `maxRows`, `maxChars`, `includeSummary`.
- **Per-row output**:
  - `_kind: "header"` — first dataset row, with the CSV header line and resolved `columns` array.
  - `_kind: "row"` — one dataset row per data row of the converted CSV.
  - `_kind: "summary"` (optional) — columns, counts, and a 5-line CSV preview.
- **Output** (`SUMMARY`): `columns`, `counts` (parsed, bad, written, lines). `OUTPUT` key-value store holds the full CSV body.

### Quick start

```bash
apify call stellar_ballet_0bu/jsonl-to-csv -i '{
  "text": "{\"id\":1,\"name\":\"alice\",\"email\":\"a@x.com\"}\n{\"id\":2,\"name\":\"bob\",\"team\":\"ops\"}\n{\"id\":3,\"name\":\"carol\",\"email\":\"c@x.com\",\"team\":\"sales\"}\n",
  "columns": ["id","name","email","team"],
  "includeSummary": true
}'
````

The default dataset will have ~5 items: 1 header + 3 row + 1 summary. `OUTPUT` key-value record holds the full CSV text.

### Inputs

- `text` — inline JSONL/NDJSON body. If set, `textUrl` is ignored.
- `textUrl` — public URL of a JSONL/NDJSON file. Used only if `text` is empty.
- `columns` — optional explicit column list. If empty, columns are auto-discovered from the union of all keys in document order of first appearance.
- `delimiter` — CSV delimiter character (default `,`).
- `includeSummary` — if true, push a `_kind: "summary"` row with totals + column list.
- `maxRows` — stop after this many converted rows. `0` means unlimited.
- `maxChars` — truncate the input body at this many characters before parsing. Default 5,000,000.

### Use cases

- **Convert a JSONL API export into CSV for Google Sheets / Airtable / Supabase** (one line per dataset row, plus the full CSV in the `OUTPUT` key-value record).
- **Pre-process logs** before loading into a warehouse or feeding into `csv-join-enricher` or `csv-statistical-summary`.
- **Materialise a flattened JSON dataset as CSV** after `json-flatten-normalizer`.
- **Cleanup step for `apify-dataset-export-batch`** when the source platform only emits JSONL.

### API notes

- Pure data utility, no scraping when `text` is supplied inline.
- Blank lines and lines starting with `#` are skipped (comment-aware).
- Lines that fail to parse are counted as `bad` and skipped, not crashed on.
- CSV escaping: fields containing the delimiter, a quote, or a newline are quoted and embedded quotes are doubled (`""`).
- Header row is the resolved `columns` array; for a row missing a key, the cell is empty.
- Nested objects/arrays in the JSONL are stringified to JSON for the CSV cell (no flattening here — use `json-flatten-normalizer` first if you need a flat schema).

### Pricing (Pay per event)

| Event | Description | USD |
|---|---|---|
| `apify-actor-start` | Built-in start charge, per Apify platform usage | per pricing tier |
| `row_converted` | One charge per converted data row (skips blank lines and `#` comments). | $0.0001 |
| `apify-actor-start` is auto-charged by Apify platform; `row_converted` is the only domain-specific event. |

`currentPricingInfo` activates on `2026-07-22T00:00:00Z`. The Actor's code calls `Actor.charge({ eventName: 'row_converted', count })` only for successfully converted data rows.

### Cost expectations

A 100k-line JSONL input will cost roughly $10 of usage credits on top of the standard start charge. Set `maxRows` to cap the run if you only need a preview.

### FAQ

**Does it preserve key ordering?** Yes — columns are emitted in document order of first appearance, or in the explicit order you pass via `columns`.

**What happens if a row is missing a key present in another row?** The cell is left empty. No crash, no implicit `null` placeholder.

**What happens if a row has a key not present in other rows?** That key is added to the resolved `columns` list at the position of its first appearance.

**Can I split a big JSONL file into chunks?** Yes — run this Actor N times with `maxRows: <chunk-size>` and chain via `apify-dataset-export-batch` for downstream consumers.

**What about arrays/objects in cells?** They are stringified to JSON. Use `json-flatten-normalizer` first if you need each array element as its own column.

**Does the output CSV escape special characters?** Yes — RFC 4180: fields containing the delimiter, a quote, or a newline are wrapped in quotes; embedded quotes are doubled.

### Limits

- Best for inputs up to ~5M characters per run. For larger inputs, split into chunks or fetch via `textUrl` (subject to the platform's fetch limits).
- Single-pass streaming: the entire input is held in memory while parsing. For multi-GB JSONL, run in shards.

### Related Actors

- `json-flatten-normalizer` — flatten nested objects before CSV conversion
- `jsonl-stream-validator` — validate a JSONL stream against a JSON Schema before conversion
- `json-schema-validator` — validate an array of records against a schema
- `csv-join-enricher` — join the resulting CSV with another CSV by key
- `csv-quality-scorecard` — score the resulting CSV's quality
- `csv-dedupe-normalizer` — dedupe the resulting CSV
- `csv-statistical-summary` — column-level stats on the resulting CSV
- `apify-dataset-export-batch` — batch export multiple Apify datasets to JSON/JSONL/CSV

### Support

- Source: hidden (paid Actor pattern; not exposed by default).
- Issues / feature requests: open a thread on the public Apify Store Actor page (button on the right of the Store listing) or message the maintainer through the Apify Console.
- For paid-pilot bulk runs (multi-GB JSONL files, scheduled conversion pipelines, custom output formats), contact the maintainer via the Apify Console.

### License

MIT-style Apify Actor Source-Available License. You may use the public Actor output and integrate the public results; you may not re-host the Actor source or re-publish it as a competing Actor.

# Actor input Schema

## `text` (type: `string`):

JSONL/NDJSON body. One JSON object per line. If set, `textUrl` is ignored.

## `textUrl` (type: `string`):

Public URL of a JSONL/NDJSON file. Used only if `text` is empty.

## `columns` (type: `array`):

Optional explicit column list. If empty, columns are auto-discovered from the union of all keys in document order of first appearance.

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

CSV delimiter character (default comma).

## `includeSummary` (type: `boolean`):

If true, push a `_kind: summary` row with totals + column list.

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

Stop after this many converted rows. 0 means unlimited.

## `maxChars` (type: `integer`):

Truncate the input body at this many characters before parsing.

## Actor input object example

```json
{
  "text": "",
  "textUrl": "",
  "columns": [],
  "delimiter": ",",
  "includeSummary": true,
  "maxRows": 0,
  "maxChars": 5000000
}
```

# Actor output Schema

## `csvRows` (type: `string`):

Default dataset items: one row of the converted CSV per item with \_kind='row' and \_line, plus header/summary/error items.

## `summary` (type: `string`):

Run summary with ok, columns, counts (rows, valid, invalid, columns).

## `outputCsv` (type: `string`):

Full converted CSV as text (header + all input rows).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("stellar_ballet_0bu/jsonl-to-csv").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 = {}

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

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

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

```

## CLI example

```bash
echo '{}' |
apify call stellar_ballet_0bu/jsonl-to-csv --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=stellar_ballet_0bu/jsonl-to-csv",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "JSONL / NDJSON to CSV — streaming converter",
        "description": "Stream a JSONL/NDJSON document (inline text or public URL) into a CSV. Auto-discovers columns from the union of all keys in document order of first appearance. No scraping required when text is provided inline.",
        "version": "0.2",
        "x-build-id": "BDPBBtAfwzHO57USK"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stellar_ballet_0bu~jsonl-to-csv/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stellar_ballet_0bu-jsonl-to-csv",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/stellar_ballet_0bu~jsonl-to-csv/runs": {
            "post": {
                "operationId": "runs-sync-stellar_ballet_0bu-jsonl-to-csv",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/stellar_ballet_0bu~jsonl-to-csv/run-sync": {
            "post": {
                "operationId": "run-sync-stellar_ballet_0bu-jsonl-to-csv",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "text": {
                        "title": "Inline JSONL text",
                        "type": "string",
                        "description": "JSONL/NDJSON body. One JSON object per line. If set, `textUrl` is ignored.",
                        "default": ""
                    },
                    "textUrl": {
                        "title": "JSONL URL",
                        "type": "string",
                        "description": "Public URL of a JSONL/NDJSON file. Used only if `text` is empty.",
                        "default": ""
                    },
                    "columns": {
                        "title": "Columns",
                        "type": "array",
                        "description": "Optional explicit column list. If empty, columns are auto-discovered from the union of all keys in document order of first appearance.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "delimiter": {
                        "title": "Delimiter",
                        "type": "string",
                        "description": "CSV delimiter character (default comma).",
                        "default": ","
                    },
                    "includeSummary": {
                        "title": "Include summary row",
                        "type": "boolean",
                        "description": "If true, push a `_kind: summary` row with totals + column list.",
                        "default": true
                    },
                    "maxRows": {
                        "title": "Max rows",
                        "type": "integer",
                        "description": "Stop after this many converted rows. 0 means unlimited.",
                        "default": 0
                    },
                    "maxChars": {
                        "title": "Max input chars",
                        "type": "integer",
                        "description": "Truncate the input body at this many characters before parsing.",
                        "default": 5000000
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
