{
  "openapi": "3.1.1",
  "info": {
    "title": "Structured Output Validator API",
    "version": "1.0.0",
    "summary": "Validate AI JSON output against a JSON Schema: parse errors with line/column, plain-language fixes.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://structuredoutputvalidator.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Validate AI JSON output against a JSON Schema: parse errors with line/column, plain-language fixes.",
        "description": "Paste a JSON Schema (or an OpenAI/Anthropic/MCP wrapper around one) and the model's output. The tool extracts the JSON from markdown code fences or surrounding prose, reports syntax errors with exact line and column, validates against a draft 2020-12 subset (types, required, additionalProperties, enum, const, ranges, lengths, patterns, items, anyOf/oneOf/allOf, local $ref and more) with human explanations and hints for typical LLM mistakes, and suggests a repaired JSON only for trivial issues such as code fences or trailing commas.\n\nMethodology:\n- Extraction: raw JSON if the output starts with { or [; otherwise the first ```json (or JSON-looking) code fence; otherwise the first balanced {…} / […] in the prose.\n- Parsing uses a strict RFC 8259 parser that reports the first error with line and column in your original text (single quotes, unquoted keys, NaN/None/True, trailing commas, unescaped line breaks are named explicitly).\n- Repair is attempted only for trivial issues – removing code fences/prose and trailing commas. Anything else is reported, never guessed. Validation then runs on the repaired JSON and says so.\n- Validation implements the draft 2020-12 core used by structured-output APIs: type, enum, const, properties, required, additionalProperties, patternProperties, propertyNames, min/maxProperties, items, prefixItems, contains, min/maxItems, uniqueItems, minimum/maximum (incl. exclusive), multipleOf, min/maxLength, pattern, anyOf, oneOf, allOf, not, if/then/else, dependentRequired and local $ref. format is checked for common formats and reported as a warning. Unknown keywords are listed as not checked.\n- Wrappers (OpenAI response_format/json_schema, Responses text.format, function tools, Anthropic input_schema, MCP inputSchema) are unwrapped; with strict: true the OpenAI strict-mode rules (closed objects, all properties required) are checked too.",
        "tags": [
          "ai-infra"
        ],
        "x-mcp-tool": "structured_output_validator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StructuredOutputValidatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Fenced output with trailing comma, string number and unknown property",
                  "value": {
                    "schema": "{\n  \"type\": \"json_schema\",\n  \"json_schema\": {\n    \"name\": \"order\",\n    \"strict\": true,\n    \"schema\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"customer\",\n        \"items\",\n        \"status\"\n      ],\n      \"properties\": {\n        \"customer\": {\n          \"$ref\": \"#/$defs/customer\"\n        },\n        \"items\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"items\": {\n            \"type\": \"object\",\n            \"additionalProperties\": false,\n            \"required\": [\n              \"sku\",\n              \"qty\",\n              \"price\"\n            ],\n            \"properties\": {\n              \"sku\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[A-Z]{3}-\\\\d{4}$\"\n              },\n              \"qty\": {\n                \"type\": \"integer\",\n                \"minimum\": 1\n              },\n              \"price\": {\n                \"type\": \"number\",\n                \"minimum\": 0\n              }\n            }\n          }\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"pending\",\n            \"paid\",\n            \"shipped\"\n          ]\n        }\n      },\n      \"$defs\": {\n        \"customer\": {\n          \"type\": \"object\",\n          \"additionalProperties\": false,\n          \"required\": [\n            \"name\",\n            \"email\"\n          ],\n          \"properties\": {\n            \"name\": {\n              \"type\": \"string\",\n              \"minLength\": 1\n            },\n            \"email\": {\n              \"type\": \"string\",\n              \"format\": \"email\"\n            }\n          }\n        }\n      }\n    }\n  }\n}",
                    "output": "Sure! Here is the order:\n```json\n{\n  \"customer\": {\"name\": \"Ada Lovelace\", \"email\": \"ada@example.com\"},\n  \"items\": [\n    {\"sku\": \"ABC-1234\", \"qty\": 2, \"price\": \"19.99\"},\n    {\"sku\": \"xyz-9\", \"qty\": 0, \"price\": 5, \"note\": \"gift\"},\n  ],\n  \"status\": \"Paid\"\n}\n```\nLet me know if you need anything else."
                  }
                },
                "example2": {
                  "summary": "Broken JSON (missing comma) – exact error position",
                  "value": {
                    "schema": "{\"type\":\"object\",\"required\":[\"title\",\"tags\"],\"properties\":{\"title\":{\"type\":\"string\"},\"tags\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}",
                    "output": "{\n  \"title\": \"Release notes\"\n  \"tags\": [\"ai\", \"json\"]\n}"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StructuredOutputValidatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "StructuredOutputValidatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "schema": {
            "title": "JSON Schema",
            "description": "Plain schema or a response_format / function-tool wrapper.",
            "type": "string",
            "maxLength": 500000
          },
          "output": {
            "title": "AI output",
            "description": "Raw model output; code fences and prose around the JSON are handled.",
            "type": "string",
            "maxLength": 1000000
          },
          "maxErrors": {
            "title": "Maximum errors listed",
            "type": "integer",
            "minimum": 1,
            "maximum": 500,
            "default": 50
          }
        },
        "required": [
          "schema",
          "output"
        ]
      },
      "StructuredOutputValidatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "extraction",
              "parse",
              "valid",
              "errors",
              "warnings",
              "repaired",
              "schemaInfo"
            ],
            "properties": {
              "extraction": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "method",
                  "startLine",
                  "note"
                ],
                "properties": {
                  "method": {
                    "type": "string",
                    "enum": [
                      "raw",
                      "code-fence",
                      "embedded"
                    ]
                  },
                  "startLine": {
                    "type": "integer"
                  },
                  "note": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "parse": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "ok",
                  "okAfterRepair",
                  "error",
                  "line",
                  "column",
                  "context"
                ],
                "properties": {
                  "ok": {
                    "type": "boolean",
                    "description": "The extracted text parses as-is."
                  },
                  "okAfterRepair": {
                    "type": "boolean",
                    "description": "Parses after trivial repairs (trailing commas)."
                  },
                  "error": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "line": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "column": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "context": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "valid": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "null when the JSON could not be parsed."
              },
              "errors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "path",
                    "keyword",
                    "message",
                    "line",
                    "column"
                  ],
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "keyword": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "line": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "column": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  }
                }
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "repaired": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "label",
                  "changes",
                  "json"
                ],
                "properties": {
                  "label": {
                    "type": "string"
                  },
                  "changes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "json": {
                    "type": "string"
                  }
                }
              },
              "schemaInfo": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wrapper",
                  "strict",
                  "unsupportedKeywords",
                  "strictModeIssues"
                ],
                "properties": {
                  "wrapper": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "strict": {
                    "type": "boolean"
                  },
                  "unsupportedKeywords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "strictModeIssues": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}