/api/json/lint
MCP tool json_lint Parses input as strict RFC 8259 JSON and runs the lint rules: syntax, duplicate-keys, number-precision, string-encoding, indent-style, indent, trailing-spaces, final-newline, line-endings, byte-order-mark, line-length. Every finding has a rule ID, severity, message, line, column and offset. Invalid JSON is a 200 response with valid: false. Use json_format for the formatted output and statistics.
Browser version (runs locally): JSON Format & Validate.
Try it
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
input required | string (≤ 500000 chars) | — | JSON text, up to 500,000 characters. |
indent | 2 | 4 | tab | none | 2 | Expected indentation unit for the indent rule. |
max_line_length | integer (0–10000) | 120 | Limit for the line-length rule; 0 disables it. |
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 |
|---|---|---|
valid | boolean | No error findings. |
summary | object | |
summary.valid | boolean | True when there are no error findings. |
summary.errors | integer | Number of errors. |
summary.warnings | integer | Number of warnings. |
summary.infos | integer | Number of informational findings. |
diagnostics | array of object | Findings in document order. |
diagnostics[].rule | string | Rule ID, e.g. syntax, duplicate-keys, trailing-spaces. |
diagnostics[].severity | "error" | "warning" | "info" | error makes the document invalid; warning and info are style. |
diagnostics[].message | string | What is wrong and how to fix it. |
diagnostics[].line | integer | 1-based line where the problem starts. |
diagnostics[].column | integer | 1-based column (Unicode code points). |
diagnostics[].offset | integer | 0-based UTF-16 offset into the input. |
diagnostics[].endLine optional | integer | 1-based end line, when the problem spans a range. |
diagnostics[].endColumn optional | integer | 1-based end column. |
diagnostics[].endOffset optional | integer | 0-based end offset. |
Errors
Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.
| Status | Code | When |
|---|---|---|
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). |
400 | invalid_parameter | A value has the wrong type, is out of range, or is not an allowed value. |
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.
Duplicate key and a trailing space
curl -X POST 'https://util.caruana.me/api/json/lint' \
-H 'content-type: application/json' \
-d '{"input":"{\n \"id\": 1,\n \"id\": 2 \n}\n"}'
Response 200
{
"valid": false,
"summary": {
"valid": false,
"errors": 1,
"warnings": 1,
"infos": 0
},
"diagnostics": [
{
"rule": "duplicate-keys",
"severity": "error",
"message": "Duplicate key \"id\" at /id (first defined at line 2, column 3). Only the last value survives JSON.parse.",
"line": 3,
"column": 3,
"offset": 15
},
{
"rule": "trailing-spaces",
"severity": "warning",
"message": "Trailing whitespace.",
"line": 3,
"column": 10,
"offset": 22,
"endLine": 3,
"endColumn": 11,
"endOffset": 23
}
]
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "json_lint",
"arguments": {
"input": "{\n \"id\": 1,\n \"id\": 2 \n}\n"
}
}
}Syntax error
curl -X POST 'https://util.caruana.me/api/json/lint' \
-H 'content-type: application/json' \
-d '{"input":"{\"a\": [1, 2,]}"}'
Response 200
{
"valid": false,
"summary": {
"valid": false,
"errors": 1,
"warnings": 1,
"infos": 0
},
"diagnostics": [
{
"rule": "syntax",
"severity": "error",
"message": "Trailing comma before \"]\": JSON does not allow a comma after the last element. Remove it.",
"line": 1,
"column": 13,
"offset": 12
},
{
"rule": "final-newline",
"severity": "warning",
"message": "Missing line break at the end of the text.",
"line": 1,
"column": 15,
"offset": 14
}
]
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "json_lint",
"arguments": {
"input": "{\"a\": [1, 2,]}"
}
}
}