JSON Formatter
Format, beautify and minify JSON in the browser. Paste a raw API response or webhook payload and get indented output plus the exact line and character of any syntax error.

{
"name": "automation",
"steps": [
1,
2,
3
],
"active": true
}Paste raw, minified or broken JSON and get back formatted output with syntax highlighting and a clear error message pointing at the exact character that failed. Works with objects, arrays, deep nesting and Unicode.
What this tool is for
You have a wall of JSON on one line — a webhook payload, an API response, a config file someone exported — and you need to read it, find one field in it, or work out why a parser is rejecting it. Paste it above. You get indented output, colour-coded types, collapsible nodes, and a minify toggle for when you need to paste it back into code.
It runs in your browser. Nothing is uploaded, which matters when the payload you are debugging contains a customer's email address or a bearer token.

A worked example: finding the path to a field
Here is the sort of thing a form webhook actually sends:
{"event":"form.submitted","data":{"contact":{"id":"cnt_8812","email":"jo@example.com","custom_fields":[{"key":"budget","value":"5000"},{"key":"timeline","value":"Q4"}]}},"ts":1754870400}Formatted, it becomes:
{
"event": "form.submitted",
"data": {
"contact": {
"id": "cnt_8812",
"email": "jo@example.com",
"custom_fields": [
{ "key": "budget", "value": "5000" },
{ "key": "timeline", "value": "Q4" }
]
}
},
"ts": 1754870400
}Now the path is obvious. The email is data.contact.email. The budget is not data.contact.budget — it is data.contact.custom_fields[0].value, and only while budget happens to be first in the array. That distinction is the single most common reason a mapping works in testing and breaks in production: arrays are ordered by the sender, not by you. If the field you want lives in an array of key/value pairs, look it up by its key rather than trusting the index.
Two other things worth reading off the formatted view. "5000" is a string, not a number, so any arithmetic on it needs an explicit conversion. And 1754870400 is a Unix timestamp in seconds; JavaScript's Date expects milliseconds, so it needs multiplying by 1000 before it means anything.
What counts as valid JSON
JSON is defined by RFC 8259 and it is far stricter than the JavaScript object syntax it grew out of. A formatter is really a parser with pretty output, so anything it rejects, your automation platform will reject too.
Valid JSON allows exactly six value types: object, array, string, number, true/false, and null. Strings must use double quotes. Keys must be quoted strings. There are no comments, no trailing commas, no single quotes, no undefined, no NaN or Infinity, and no leading zeros or leading + on numbers. The grammar is in section 2 of the RFC, and JSON5 is the separate, deliberately relaxed superset that allows the things JSON forbids.
| Written as | JSON | JavaScript | JSON5 | YAML |
|---|---|---|---|---|
{'a': 1} — single quotes |
Invalid | Valid | Valid | Valid |
{a: 1} — unquoted key |
Invalid | Valid | Valid | Valid |
{"a": 1,} — trailing comma |
Invalid | Valid | Valid | n/a |
// comment |
Invalid | Valid | Valid | Valid (#) |
NaN, Infinity |
Invalid | Valid | Valid | .nan, .inf |
{"a": 1, "a": 2} — duplicate key |
Allowed, last wins in most parsers | Last wins | Last wins | Usually an error |
The duplicate key row is the dangerous one. The spec only says names should be unique and states plainly that when they are not, the behaviour of the receiving software is unpredictable — many implementations report the last pair only, and no tool will warn you. If two systems merge into one payload upstream, you can lose a field without ever seeing an error.
Mistakes this tool will catch, and the ones it will not
It catches: trailing commas, unquoted keys, single-quoted strings, unclosed brackets, unescaped control characters inside strings, and stray text outside the top-level value. The error message gives the character position, which is usually more useful than the line number when the input is one long line — format first, then re-read the error against the formatted version.
It will not catch these, because they are valid JSON:
- Double-encoded JSON. A field whose value is
"{\"id\":7}"is a string that looks like JSON, not an object. It parses cleanly and then every path into it returns nothing. You have to parse it a second time. This is endemic in webhook payloads that pass data through an intermediary. - Large integers. Any ID above 9,007,199,254,740,991 —
Number.MAX_SAFE_INTEGER, and the exact bound the RFC calls interoperable — loses precision the moment a JavaScript-based parser touches it.12345678901234567890quietly becomes12345678901234567000. Senders that know this send big IDs as strings; senders that do not will corrupt your records. - A Python dictionary pasted by mistake.
True,FalseandNoneare not JSON. The error will point at the capital T, which reads as nonsense until you notice where the text came from. - Smart quotes. Text round-tripped through Word or Google Docs has
"in place of". It looks right and parses as a syntax error at a position that seems arbitrary. - A byte order mark. An invisible BOM at the start of a file exported from Excel breaks parsing at character zero. The RFC forbids senders from adding one and only permits parsers to ignore it, so whether it works is down to whose parser you hit.
Frequently Asked Questions
Is my JSON uploaded anywhere?
No. Formatting happens in your browser, so the payload never leaves your machine. That is deliberate — the JSON people most need to format is usually the JSON they least want to paste into a stranger's server, because it contains live customer data or an API token.
What is the difference between this and the JSON Validator?
This tool is for reading: it formats, highlights and folds so you can navigate a payload. The JSON Validator is for checking: it reports on structure and conformance when you need a yes or no rather than a pretty view. In practice you format while you are debugging and validate when you are wiring something into a pipeline.
Why does my JSON fail here but work in my code?
Almost always because your code is not parsing JSON. eval, a JavaScript module import, or a Python ast.literal_eval will happily accept trailing commas, single quotes and unquoted keys — and the RFC explicitly warns against parsing JSON with eval for exactly the reason you would expect. JSON.parse is the strict path. The moment that data crosses a network boundary into a real JSON parser, it fails. Treating this tool as the stricter reference is the point.
Can I use it on a very large file?
Large payloads work, but everything runs in the browser tab, so a file in the tens of megabytes will make the page sluggish and folding will feel slow. For anything at that size you are better off with a streaming parser such as jq on the command line. This tool is built for the payload you are debugging right now, not for bulk processing.
How do I get a value out of a nested array?
Find the item first, then read the field, rather than counting positions. In the worked example above, the reliable way to reach the budget is to search custom_fields for the entry whose key equals "budget" and take its value. Index-based access such as [0] only holds until the sender changes the order, which they will do without telling you.
Next steps
If you are formatting JSON because a webhook mapping is not behaving, the two guides that cover this end to end are the Make.com Webhook Tutorial and the n8n Webhook Tutorial — both walk through reading a real payload and mapping it without guessing. To fire test requests at an endpoint and inspect what comes back, use the API Request Tester.
If the payload is fighting you because the integration behind it was never built properly, I do this work as a freelancer — you can start a project on Fiverr or hire me on Upwork.

Want this built against your real numbers?
A 30-minute call to scope the workflow, agent, or automation you actually need.
More developer tools
All tools
.env Manager
Validate environment variable names and values before they reach production. Env Manager checks names against POSIX rules, flags values that different .env parsers read differently, and shows which entries are secrets that should not sit in a file.

.gitignore Generator
Build a .gitignore for your stack in seconds. Covers dependencies, build output, IDE files and the .env patterns that keep secrets out of a public repository.

API Mock Server
Create a live mock REST endpoint with your own path, method, status code, headers, delay and JSON body — so you can build and test a frontend or automation before the real API is ready.

API Request Tester
Send REST API requests from your browser with custom headers, auth and a JSON body, and inspect the status, headers and response. Includes a guide to reading status codes and diagnosing CORS.

Base64 Encoder
Convert text, JSON or files to Base64 in the browser, with nothing sent to a server. Covers the padding rules, the exact 33% size increase, and the non-canonical strings that decode to identical bytes.

Cron Expression Generator
Build cron expressions visually and get the correct string for crontab, GitHub Actions, EventBridge, Kubernetes, Make or n8n — with a field reference and the common gotchas explained.
Have a workflow that's burning hours every week?
Bring me one real bottleneck. I'll tell you whether it's worth automating, and what it would take.