API reference

Lint and format YAML

Check YAML against yamllint’s rules (same rule IDs) and return the findings with positions, plus a comment-preserving formatted copy.

GET POST /api/yaml/format MCP tool yaml_format

Parses input as YAML 1.2 (core schema) and reports every finding with its rule, severity, line, column and offset. Rules follow yamllint's default set and names: syntax, key-duplicates, anchors, braces, brackets, colons, commas, comments, comments-indentation, document-start, empty-lines, empty-values, hyphens, indentation, line-length, new-line-at-end-of-file, new-lines, octal-values, quoted-strings, trailing-spaces, truthy, byte-order-mark. Errors (syntax, key-duplicates, an alias without an anchor) make the document invalid; everything else is a warning or info. An invalid document is still a 200 response, with valid: false, the findings, and formatted and value set to null. When the YAML is valid, formatted is the document re-written with the chosen indentation, one space after colons and hyphens, no padding inside {}/[], at most one blank line in a row, LF line breaks and a final newline. Comments, anchors, tags, key order, block scalars and the text of numbers are kept; quotes are removed only where the plain form means the same string in YAML 1.2 and 1.1 ("yes", "0755", "null" stay quoted). The formatted text is re-parsed and compared with the input before it is returned, so it always has the same value. value is the data as JSON: the first document's value, or an array of all documents when there are several (merge keys applied, at most 1,000 alias expansions).

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

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/yaml/format with a JSON body

Parameters

Parameter Type Default Description
input required string (≤ 15000 chars) — The YAML text, as a string field or a raw text/plain POST body.
indent 2 | 4 2 Spaces per indentation level, for the indentation rule and the formatted output.
indent_sequences consistent | indented | flush consistent How a sequence under a mapping key is indented: indented (key: then - item), flush (- item at the key’s column), or consistent (either, as long as the whole file does the same; the first one decides). yamllint’s indent-sequences.
max_line_length integer (0–1000) 120 Longest allowed line, in characters, for the line-length rule; 0 turns the rule off. The default is 120 (yamllint’s is 80, which most Kubernetes and CI files exceed).
document_start ignore | require | forbid ignore require: every document starts with ---. forbid: the first document has no ---. ignore: either. Applies to the findings and the formatted output.
quote_style any | single | double any single or double: quoted values should use that quote character (quoted-strings rule), and the formatter converts them. any: no check, and the formatter removes quotes that are not needed.

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 True when there are no error findings: the YAML parses, has no duplicate keys and every alias has an anchor.
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.
documents integer Number of YAML documents in the input (0 for an empty or comment-only input).
formatted string | null The formatted YAML, ending with a newline (empty for an empty input); null when the YAML is invalid.
value any The data as JSON: the first document’s value, or an array of every document’s value when there are several; null when invalid. Integers beyond 2^53 − 1 lose precision; .inf and .nan become null.

Text output (format=text, text/plain): The formatted YAML; when the YAML is invalid, one finding per line (line:column severity rule message).

Errors

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

Status Code When
400 invalid_parameter input is longer than 15,000 characters (use the page for larger files), 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.

yamllint-style findings

curl -X POST 'https://util.caruana.me/api/yaml/format' \
  -H 'content-type: application/json' \
  -d '{"input":"server :\n    host: example.com\n    port:  8080\n    enabled: yes\n    mode: 0755\nlist: [ a,b ]\nempty:\n#no space\nname: x   \n"}'

Response 200

{
  "valid": true,
  "summary": {
    "valid": true,
    "errors": 0,
    "warnings": 10,
    "infos": 1
  },
  "diagnostics": [
    {
      "rule": "colons",
      "severity": "warning",
      "message": "Too many spaces before colon (1; expected 0).",
      "line": 1,
      "column": 7,
      "offset": 6,
      "endLine": 1,
      "endColumn": 8,
      "endOffset": 7
    },
    {
      "rule": "indentation",
      "severity": "warning",
      "message": "Wrong indentation: expected 2 spaces but found 4.",
      "line": 2,
      "column": 1,
      "offset": 9,
      "endLine": 2,
      "endColumn": 5,
      "endOffset": 13
    },
    {
      "rule": "colons",
      "severity": "warning",
      "message": "Too many spaces after colon (2; expected 1).",
      "line": 3,
      "column": 11,
      "offset": 41,
      "endLine": 3,
      "endColumn": 12,
      "endOffset": 42
    },
    {
      "rule": "truthy",
      "severity": "warning",
      "message": "yes is the string \"yes\" in YAML 1.2 but a boolean in YAML 1.1. Write true or false for a boolean, or quote it for a string.",
      "line": 4,
      "column": 14,
      "offset": 60,
      "endLine": 4,
      "endColumn": 17,
      "endOffset": 63
    },
    {
      "rule": "octal-values",
      "severity": "warning",
      "message": "0755 is the decimal 755 in YAML 1.2 but octal (493) in YAML 1.1. Write 0o755 for octal, 755 for decimal, or quote it for a string.",
      "line": 5,
      "column": 11,
      "offset": 74,
      "endLine": 5,
      "endColumn": 15,
      "endOffset": 78
    },
    {
      "rule": "brackets",
      "severity": "warning",
      "message": "Too many spaces inside brackets (1; expected 0).",
      "line": 6,
      "column": 8,
      "offset": 86,
      "endLine": 6,
      "endColumn": 9,
      "endOffset": 87
    },
    {
      "rule": "commas",
      "severity": "warning",
      "message": "Too few spaces after comma (0; expected 1).",
      "line": 6,
      "column": 11,
      "offset": 89
    },
    {
      "rule": "brackets",
      "severity": "warning",
      "message": "Too many spaces inside brackets (1; expected 0).",
      "line": 6,
      "column": 12,
      "offset": 90,
      "endLine": 6,
      "endColumn": 13,
      "endOffset": 91
    },
    {
      "rule": "empty-values",
      "severity": "info",
      "message": "Empty value for key \"empty\": it is null. Write null or ~ to make that explicit, or give it a value.",
      "line": 7,
      "column": 6,
      "offset": 98,
      "endLine": 7,
      "endColumn": 7,
      "endOffset": 99
    },
    {
      "rule": "comments",
      "severity": "warning",
      "message": "Missing space after \"#\" at the start of the comment.",
      "line": 8,
      "column": 2,
      "offset": 101
    },
    {
      "rule": "trailing-spaces",
      "severity": "warning",
      "message": "Trailing whitespace.",
      "line": 9,
      "column": 8,
      "offset": 117,
      "endLine": 9,
      "endColumn": 11,
      "endOffset": 120
    }
  ],
  "documents": 1,
  "formatted": "server:\n  host: example.com\n  port: 8080\n  enabled: yes\n  mode: 0755\nlist: [a, b]\nempty:  #no space\n\nname: x\n",
  "value": {
    "server": {
      "host": "example.com",
      "port": 8080,
      "enabled": "yes",
      "mode": 755
    },
    "list": [
      "a",
      "b"
    ],
    "empty": null,
    "name": "x"
  }
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "yaml_format",
    "arguments": {
      "input": "server :\n    host: example.com\n    port:  8080\n    enabled: yes\n    mode: 0755\nlist: [ a,b ]\nempty:\n#no space\nname: x   \n"
    }
  }
}

Format with comments kept, 4-space indent

curl -X POST 'https://util.caruana.me/api/yaml/format' \
  -H 'content-type: application/json' \
  -d '{"input":"# Service settings\nservice:\n  name: \"web\"   # quotes are not needed here\n  replicas: 3\n  ports:\n  - 80\n  - 443\n  country: \"no\" # stays quoted: YAML 1.1 reads no as false\n","indent":4,"indent_sequences":"indented"}'

Response 200

{
  "valid": true,
  "summary": {
    "valid": true,
    "errors": 0,
    "warnings": 3,
    "infos": 0
  },
  "diagnostics": [
    {
      "rule": "indentation",
      "severity": "warning",
      "message": "Wrong indentation: expected 4 spaces but found 2.",
      "line": 3,
      "column": 1,
      "offset": 28,
      "endLine": 3,
      "endColumn": 3,
      "endOffset": 30
    },
    {
      "rule": "indentation",
      "severity": "warning",
      "message": "Wrong indentation: expected 6 spaces but found 2.",
      "line": 6,
      "column": 1,
      "offset": 96,
      "endLine": 6,
      "endColumn": 3,
      "endOffset": 98
    },
    {
      "rule": "comments",
      "severity": "warning",
      "message": "Too few spaces before an inline comment (1; expected at least 2).",
      "line": 8,
      "column": 16,
      "offset": 126,
      "endLine": 8,
      "endColumn": 17,
      "endOffset": 127
    }
  ],
  "documents": 1,
  "formatted": "# Service settings\nservice:\n    name: web  # quotes are not needed here\n    replicas: 3\n    ports:\n        - 80\n        … (68 more characters)",
  "value": {
    "service": {
      "name": "web",
      "replicas": 3,
      "ports": [
        80,
        443
      ],
      "country": "no"
    }
  }
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "yaml_format",
    "arguments": {
      "input": "# Service settings\nservice:\n  name: \"web\"   # quotes are not needed here\n  replicas: 3\n  ports:\n  - 80\n  - 443\n  country: \"no\" # stays quoted: YAML 1.1 reads no as false\n",
      "indent": 4,
      "indent_sequences": "indented"
    }
  }
}

Invalid YAML: duplicate key and a syntax error

curl -X POST 'https://util.caruana.me/api/yaml/format' \
  -H 'content-type: application/json' \
  -d '{"input":"name: a\nname: b\nlist: [1, 2\nnext: 3\n"}'

Response 200

{
  "valid": false,
  "summary": {
    "valid": false,
    "errors": 2,
    "warnings": 0,
    "infos": 0
  },
  "diagnostics": [
    {
      "rule": "key-duplicates",
      "severity": "error",
      "message": "Duplicate key \"n\": keys in a mapping must be unique.",
      "line": 2,
      "column": 1,
      "offset": 8,
      "endLine": 2,
      "endColumn": 2,
      "endOffset": 9
    },
    {
      "rule": "syntax",
      "severity": "error",
      "message": "Flow sequence in block collection must be sufficiently indented and end with a ].",
      "line": 4,
      "column": 1,
      "offset": 28,
      "endLine": 4,
      "endColumn": 2,
      "endOffset": 29
    }
  ],
  "documents": 1,
  "formatted": null,
  "value": null
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "yaml_format",
    "arguments": {
      "input": "name: a\nname: b\nlist: [1, 2\nnext: 3\n"
    }
  }
}

Strict house style: --- required, double quotes

curl -X POST 'https://util.caruana.me/api/yaml/format' \
  -H 'content-type: application/json' \
  -d '{"input":"a: '\''single'\''\n---\nb: 1\n","document_start":"require","quote_style":"double"}'

Response 200

{
  "valid": true,
  "summary": {
    "valid": true,
    "errors": 0,
    "warnings": 2,
    "infos": 0
  },
  "diagnostics": [
    {
      "rule": "document-start",
      "severity": "warning",
      "message": "Missing document start \"---\".",
      "line": 1,
      "column": 1,
      "offset": 0
    },
    {
      "rule": "quoted-strings",
      "severity": "warning",
      "message": "String uses single quotes; use double quotes.",
      "line": 1,
      "column": 4,
      "offset": 3,
      "endLine": 1,
      "endColumn": 12,
      "endOffset": 11
    }
  ],
  "documents": 2,
  "formatted": "---\na: \"single\"\n---\nb: 1\n",
  "value": [
    {
      "a": "single"
    },
    {
      "b": 1
    }
  ]
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "yaml_format",
    "arguments": {
      "input": "a: 'single'\n---\nb: 1\n",
      "document_start": "require",
      "quote_style": "double"
    }
  }
}