API reference

Convert JSON to CSV

Convert a JSON array of objects or of arrays to CSV, with the union of keys as the header.

GET POST /api/convert/json-to-csv MCP tool json_to_csv

Parses input strictly as JSON. An array of objects becomes one row per object, with a header made of every key in first-seen order (a missing key gives an empty cell); a single object becomes one row. An array of arrays becomes one row per array, with no header. Strings are written as they are, numbers exactly as written in the JSON (1.0 and 20-digit integers survive), booleans as true/false, null as an empty cell, and nested objects or arrays as compact JSON text (listed in notes). Values are quoted per quoting.

Browser version (runs locally): CSV Validate & Format.

Try it

Credentials
Remember these credentials

Not saved: you will paste them again next time.

No credentials yet? Get a client ID and secret. They are sent only to this site, in an Authorization: Basic header.

POST /api/convert/json-to-csv with a JSON body

Parameters

Parameter Type Default Description
input required string (≤ 200000 chars) — The JSON text: an array of objects, an array of arrays, or one object. Send it as a string field or as a raw text/plain POST body.
delimiter comma | semicolon | tab | pipe comma Delimiter for the output: comma, semicolon, tab or pipe.
header boolean true Write the header row (arrays of objects only).
quoting minimal | all | nonnumeric minimal minimal quotes only values that need it (a delimiter, quote or line break, or leading/trailing whitespace); all quotes every value; nonnumeric quotes everything except numbers.
line_ending lf | crlf lf Line break written after every row. crlf is what RFC 4180 specifies; lf is what most tools write, and every reader accepts both.

Also accepted on every endpoint: format (json | text). Parameters may come from the query string, a JSON object body, an urlencoded or multipart form, or (for input) a text/plain body.

Global parameters
Parameter Type Default Description
format json | text json json returns the documented object. text returns only the primary value as text/plain (see "Text output").

Response 200 application/json

Field Type Description
csv string The CSV text, ending with a line break (empty for an empty array).
header array of string | null The header row; null when there is none.
rowCount integer Data rows written.
columnCount integer Columns (the longest row, for arrays of arrays).
notes array of string What was adapted: nested values written as JSON, missing keys, ragged arrays.

Text output (format=text, text/plain): The CSV text.

Errors

Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.

Status Code When
422 unprocessable_input input is not valid JSON (line and column given), or is not an array of objects, an array of arrays, or an object.
400 invalid_parameter input is longer than 200,000 characters, or an option is not a listed value.
400 missing_parameter A required parameter is absent.
400 unknown_parameter A parameter name is not in the table above (typos are rejected, not ignored).
413 payload_too_large The request body exceeds 1 MiB.
405 method_not_allowed A method other than GET, POST or OPTIONS.

Behaviour

  • Idempotent: the same arguments always return the same result.
  • Requires a client ID and secret (authentication). Each call is recorded as one metadata row against your client ID; inputs and outputs are never stored or logged. Responses carry cache-control: no-store.
  • CORS: any origin may call this endpoint from a browser, using your credentials.

Examples

Responses below were produced by running each request through this code at build time. Long strings are shortened.

Objects with different keys and a nested value

curl -X POST 'https://util.caruana.me/api/convert/json-to-csv' \
  -H 'content-type: application/json' \
  -d '{"input":"[{\"id\":1,\"name\":\"Widget, large\",\"price\":9.99},{\"id\":2,\"name\":\"Say \\\"hi\\\"\",\"tags\":[\"a\",\"b\"]},{\"id\":12345678901234567890,\"name\":null}]"}'

Response 200

{
  "csv": "id,name,price,tags\n1,\"Widget, large\",9.99,\n2,\"Say \"\"hi\"\"\",,\"[\"\"a\"\",\"\"b\"\"]\"\n12345678901234567890,,,\n",
  "header": [
    "id",
    "name",
    "price",
    "tags"
  ],
  "rowCount": 3,
  "columnCount": 4,
  "notes": [
    "3 objects lack some keys; those cells are empty.",
    "Nested objects or arrays were written as JSON text in column tags."
  ]
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "json_to_csv",
    "arguments": {
      "input": "[{\"id\":1,\"name\":\"Widget, large\",\"price\":9.99},{\"id\":2,\"name\":\"Say \\\"hi\\\"\",\"tags\":[\"a\",\"b\"]},{\"id\":12345678901234567890,\"name\":null}]"
    }
  }
}

Arrays to semicolon-separated CSV with CRLF

curl -X POST 'https://util.caruana.me/api/convert/json-to-csv' \
  -H 'content-type: application/json' \
  -d '{"input":"[[\"x\",\"y\"],[1,2],[3,4]]","delimiter":"semicolon","line_ending":"crlf"}'

Response 200

{
  "csv": "x;y\r\n1;2\r\n3;4\r\n",
  "header": null,
  "rowCount": 3,
  "columnCount": 2,
  "notes": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "json_to_csv",
    "arguments": {
      "input": "[[\"x\",\"y\"],[1,2],[3,4]]",
      "delimiter": "semicolon",
      "line_ending": "crlf"
    }
  }
}