/api/json/schema/validate
MCP tool json_schema_validate Validates instance against schema with @cfworker/json-schema (an interpreter: no code generation). The draft comes from draft, else from the schema's $schema, else 2020-12. Returns valid and, for an invalid instance, each error with the instance location and keyword location as JSON Pointers, the location of the keyword in the schema document (after following $ref), and a message; leaf: false marks summary errors (from properties, items, $ref, anyOf, …) that are followed by the specific errors beneath them. An invalid instance is a successful response with valid: false. Before validating, the schema is checked for usability (keyword types, regular expressions, unresolved references); problems are a 422 error. Only local references resolve: $ref to a remote URL is never fetched (the server makes no network requests); embed such schemas under $defs with their $id. format is asserted for the formats listed in the docs. $dynamicRef is not supported. At most 1000 errors are returned.
Browser version (runs locally): JSON Schema Validator.
Try it
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
schema required | string (≤ 100000 chars) | — | The JSON Schema, as JSON text (an object or a boolean). |
instance required | string (≤ 200000 chars) | — | The JSON document to validate, as JSON text. |
draft | auto | 2020-12 | 2019-09 | 7 | 4 | auto | auto uses the draft named by the schema's $schema (draft 6 is validated as 7) and 2020-12 if there is none. Otherwise 2020-12, 2019-09, 7 or 4 overrides $schema. |
all_errors | boolean | true | true reports every error. false stops at the first failing keyword (faster; valid is the same either way). |
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 the instance satisfies the schema. |
draft | "2020-12" | "2019-09" | "7" | "4" | The draft used. |
draftSource | "parameter" | "$schema" | "default" | Where the draft came from. |
errorCount | integer | Total number of errors, including any beyond the listed maximum. |
errors | array of object | Errors in evaluation order (at most 1000). |
errors[].instanceLocation | string | JSON Pointer to the failing value in the instance; "" is the whole document. |
errors[].keyword | string | The schema keyword that failed, e.g. type, required, minimum; false for a false schema. |
errors[].keywordLocation | string | Evaluation path through the schema as a JSON Pointer; a $ref segment marks a followed reference. |
errors[].schemaLocation | string | null | JSON Pointer to the keyword in the schema document, after following $ref; null if it cannot be resolved ($recursiveRef). |
errors[].message | string | What is wrong. |
errors[].leaf | boolean | False for a summary error that is followed by the more specific errors that caused it. |
warnings | array of object | Things that did not stop validation but may not do what you expect. |
warnings[].source | "schema" | "instance" | Which document the warning is about. |
warnings[].pointer | string | JSON Pointer in that document. |
warnings[].message | string | Ignored or unknown keywords, unchecked formats, draft mismatches, duplicate keys, lossy numbers. |
Text output (format=text, text/plain): valid, or invalid followed by one line per leaf error: <instanceLocation or /> <message>.
Errors
Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.
| Status | Code | When |
|---|---|---|
422 | unprocessable_input | schema or instance is not valid JSON (the message gives line, column and offset), or the schema is not usable: a keyword has the wrong type, a regular expression does not compile, a $ref does not resolve locally, the draft is 3, or $ref cycles never reach the instance. |
400 | invalid_parameter | schema or instance exceeds its length limit, or draft 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.
An instance with several errors
curl -X POST 'https://util.caruana.me/api/json/schema/validate' \
-H 'content-type: application/json' \
-d '{"schema":"{\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"type\":\"object\",\"required\":[\"id\",\"email\"],\"properties\":{\"id\":{\"type\":\"integer\",\"minimum\":1},\"email\":{\"type\":\"string\",\"format\":\"email\"},\"tags\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"uniqueItems\":true}},\"additionalProperties\":false}","instance":"{\"id\":0,\"tags\":[\"a\",\"a\"],\"extra\":true}"}'
Response 200
{
"valid": false,
"draft": "2020-12",
"draftSource": "$schema",
"errorCount": 7,
"errors": [
{
"instanceLocation": "",
"keyword": "required",
"keywordLocation": "/required",
"schemaLocation": "/required",
"message": "Instance does not have required property \"email\".",
"leaf": true
},
{
"instanceLocation": "",
"keyword": "properties",
"keywordLocation": "/properties",
"schemaLocation": "/properties",
"message": "Property \"id\" does not match schema.",
"leaf": false
},
{
"instanceLocation": "/id",
"keyword": "minimum",
"keywordLocation": "/properties/id/minimum",
"schemaLocation": "/properties/id/minimum",
"message": "0 is less than 1.",
"leaf": true
},
{
"instanceLocation": "",
"keyword": "properties",
"keywordLocation": "/properties",
"schemaLocation": "/properties",
"message": "Property \"tags\" does not match schema.",
"leaf": false
},
{
"instanceLocation": "/tags",
"keyword": "uniqueItems",
"keywordLocation": "/properties/tags/uniqueItems",
"schemaLocation": "/properties/tags/uniqueItems",
"message": "Duplicate items at indexes 0 and 1.",
"leaf": true
},
{
"instanceLocation": "",
"keyword": "additionalProperties",
"keywordLocation": "/additionalProperties",
"schemaLocation": "/additionalProperties",
"message": "Property \"extra\" does not match additional properties schema.",
"leaf": false
},
{
"instanceLocation": "/extra",
"keyword": "false",
"keywordLocation": "/additionalProperties",
"schemaLocation": "/additionalProperties",
"message": "The schema here is false: no value is allowed at this location.",
"leaf": true
}
],
"warnings": []
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "json_schema_validate",
"arguments": {
"schema": "{\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"type\":\"object\",\"required\":[\"id\",\"email\"],\"properties\":{\"id\":{\"type\":\"integer\",\"minimum\":1},\"email\":{\"type\":\"string\",\"format\":\"email\"},\"tags\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"uniqueItems\":true}},\"additionalProperties\":false}",
"instance": "{\"id\":0,\"tags\":[\"a\",\"a\"],\"extra\":true}"
}
}
}Valid, with a local $ref
curl -X POST 'https://util.caruana.me/api/json/schema/validate' \
-H 'content-type: application/json' \
-d '{"schema":"{\"$defs\":{\"port\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":65535}},\"type\":\"array\",\"items\":{\"$ref\":\"#/$defs/port\"}}","instance":"[80, 443]"}'
Response 200
{
"valid": true,
"draft": "2020-12",
"draftSource": "default",
"errorCount": 0,
"errors": [],
"warnings": []
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "json_schema_validate",
"arguments": {
"schema": "{\"$defs\":{\"port\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":65535}},\"type\":\"array\",\"items\":{\"$ref\":\"#/$defs/port\"}}",
"instance": "[80, 443]"
}
}
}