Anonymous endpoint · JSON in, CSV out
Developer API · v1
Move JSON into deterministic CSV pipelines.
Send JSON or NDJSON to the same loss-aware normalization service behind the jsonnorm converter. Get a CSV response or compact conversion metadata, with stable fields, explicit errors, and no account setup.
Endpoint
Post one JSON document, NDJSON stream, or multipart file upload. jsonnorm detects null and missing fields separately, but the default CSV representation renders both as empty cells. The default plan discovers a union schema, preserves field order deterministically, and writes standards-compliant CSV.
POST https://jsonnorm.com/api/v1/convert
Content-Type: application/json
[{"id":1,"name":"Ada"}]
The endpoint accepts JSON, NDJSON, or a multipart file upload. Add ?response=metadata to receive JSON with row, column, input, and output counts instead of the CSV body.
Quickstarts
curl
output="$(mktemp)"
if curl --fail-with-body --silent --show-error \
-X POST https://jsonnorm.com/api/v1/convert \
-H 'Content-Type: application/json' \
--data-binary @orders.json \
--output "$output"; then
mv "$output" orders.csv
else
cat "$output" >&2
rm -f "$output"
exit 1
fi
curl · NDJSON
curl --fail-with-body --silent --show-error \
-X POST https://jsonnorm.com/api/v1/convert \
-H 'Content-Type: application/x-ndjson' \
--data-binary @orders.ndjson
curl · multipart file
curl --fail-with-body --silent --show-error \
-X POST https://jsonnorm.com/api/v1/convert \
-F '[email protected];type=application/json'
curl · metadata
curl --fail-with-body --silent --show-error \
-X POST 'https://jsonnorm.com/api/v1/convert?response=metadata' \
-H 'Content-Type: application/json' \
--data-binary @orders.json
Python
import requests
with open("orders.json", "rb") as source, open("orders.csv", "wb") as target:
with requests.post(
"https://jsonnorm.com/api/v1/convert",
headers={"Content-Type": "application/json"},
data=source,
stream=True,
) as response:
response.raise_for_status()
for chunk in response.iter_content(chunk_size=1024 * 1024):
if chunk:
target.write(chunk)
Node.js / TypeScript
import { createWriteStream } from "node:fs";
import { readFile } from "node:fs/promises";
import { Readable } from "node:stream";
import { pipeline } from "node:stream/promises";
const response = await fetch("https://jsonnorm.com/api/v1/convert", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: await readFile("orders.json"),
});
if (!response.ok) throw new Error(response.status + ": " + await response.text());
if (!response.body) throw new Error("The API returned no response body.");
await pipeline(
Readable.fromWeb(response.body),
createWriteStream("orders.csv"),
);
PowerShell 7
Invoke-WebRequest -Uri 'https://jsonnorm.com/api/v1/convert' -Method Post -ContentType 'application/json' -InFile .\orders.json -OutFile .\orders.csv
Invoke-RestMethod -Uri 'https://jsonnorm.com/api/v1/convert?response=metadata' -Method Post -ContentType 'application/json' -InFile .\orders.json
Fair-use limits
Automated abuse protection, fair-use limits, input and output budgets, and concurrency safeguards apply to every request. If you reach a limit, the API returns 429 with a Retry-After value. These safeguards protect availability and keep retries from becoming an accidental request storm.
Plan for bounded requests and retry with backoff.
If the service is temporarily unavailable, retry after the Retry-After delay and use backoff.
Errors
Failures use a JSON envelope with error.code, error.message, and an optional privacy-safe warning.
| Status | Codes | Meaning |
|---|---|---|
| 400 | JSON_PARSE_ERROR, TOKEN_TOO_LARGE, KEY_TOO_LARGE, DEPTH_LIMIT_EXCEEDED, COLUMN_LIMIT_EXCEEDED, ROW_LIMIT_EXCEEDED, GENERATED_CELL_LIMIT_EXCEEDED, PLAN_VALIDATION_ERROR, or INVALID_INPUT | The JSON/NDJSON content or conversion options are invalid. |
| 408 | DEADLINE_EXCEEDED | The bounded conversion deadline elapsed. |
| 413 | INPUT_TOO_LARGE or OUTPUT_LIMIT_EXCEEDED | The input or generated CSV exceeds a bounded size. |
| 415 | UNSUPPORTED_MEDIA_TYPE | Use application/json, application/x-ndjson, or multipart/form-data. |
| 429 | RATE_LIMITED or CONCURRENCY_LIMIT_EXCEEDED | A fair-use or concurrency safeguard asked you to wait. |
| 500 | INTERNAL_ERROR | An unexpected failure occurred. Retry later. |
| 503 | SERVICE_UNAVAILABLE | The service is temporarily busy. Retry after the delay in Retry-After. |
Privacy by default
Request payloads are processed temporarily. jsonnorm keeps no conversion history and does not log payload contents or CSV output.