[{"data":1,"prerenderedAt":1100},["ShallowReactive",2],{"blog-post-en-json-validation-syntax-vs-schema":3,"surround-\u002Fen\u002Fblog\u002Fjson-validation-syntax-vs-schema":1093},{"id":4,"title":5,"author":6,"body":7,"category":1068,"date":1069,"description":1070,"draft":1071,"extension":1072,"h1":5,"image":1073,"lastmod":1069,"locales":1074,"meta":1077,"navigation":1078,"path":1079,"promo":1080,"seo":1084,"stem":1085,"tags":1086,"__hash__":1092},"blog\u002Fen\u002Fblog\u002Fjson-validation-syntax-vs-schema.md","JSON Validation Explained: Syntax Checks vs JSON Schema Validation","JSON Toolbox Team",{"type":8,"value":9,"toc":1018},"minimark",[10,14,18,25,28,33,40,50,56,90,93,97,103,108,113,145,152,156,159,165,172,178,181,209,213,223,231,242,246,254,258,261,265,274,293,296,300,312,318,322,427,430,474,482,505,509,515,520,523,614,622,626,629,633,678,681,685,688,699,703,709,713,719,729,733,739,743,749,752,756,759,763,769,773,779,783,789,792,796,800,805,809,816,820,826,830,846,850,853,857,860,864,867,908,912,916,926,930,939,943,946,953,962,966,1009,1012],[11,12,5],"h1",{"id":13},"json-validation-explained-syntax-checks-vs-json-schema-validation",[15,16,17],"p",{},"A JSON string can be parsed without errors and still break your API.",[15,19,20,24],{},[21,22,23],"code",{},"JSON.parse()"," only checks whether text follows JSON grammar. It does not check whether required fields exist, whether values match expected types, or whether extra fields should be rejected. For that, you need schema validation and, beyond that, business-rule validation.",[15,26,27],{},"This guide explains the three layers of JSON validation and shows how to implement each one in JavaScript.",[29,30,32],"h2",{"id":31},"the-short-answer-valid-json-is-not-always-valid-data","The Short Answer: Valid JSON Is Not Always Valid Data",[15,34,35,36,39],{},"Consider this payload sent to a ",[21,37,38],{},"POST \u002Fusers"," endpoint:",[41,42,48],"pre",{"className":43,"code":45,"language":46,"meta":47},[44],"language-json","{\n  \"email\": \"not-an-email\",\n  \"age\": -3,\n  \"role\": \"superadmin\",\n  \"marketingOptIn\": \"yes\",\n  \"debug\": true\n}\n","json","",[21,49,45],{"__ignoreMap":47},[15,51,52,53,55],{},"This is valid JSON — ",[21,54,23],{}," will succeed. But the data violates nearly every rule your API should enforce:",[57,58,59,66,72,78,84],"ul",{},[60,61,62,65],"li",{},[21,63,64],{},"email"," is not a valid email address.",[60,67,68,71],{},[21,69,70],{},"age"," is negative.",[60,73,74,77],{},[21,75,76],{},"role"," is not one of the allowed values.",[60,79,80,83],{},[21,81,82],{},"marketingOptIn"," should be a boolean, not a string.",[60,85,86,89],{},[21,87,88],{},"debug"," is an unknown field that should not be accepted.",[15,91,92],{},"This is why validation must go beyond syntax.",[29,94,96],{"id":95},"layer-1-syntax-validation-can-the-text-be-parsed","Layer 1: Syntax Validation — Can the Text Be Parsed?",[15,98,99,100,102],{},"Syntax validation checks whether a string conforms to the JSON grammar defined in RFC 8259. The simplest way to perform it in JavaScript is ",[21,101,23],{},".",[104,105,107],"h3",{"id":106},"what-jsonparse-checks","What JSON.parse() checks",[15,109,110,112],{},[21,111,23],{}," verifies that the text is structurally valid JSON:",[57,114,115,126,129,132,135,138],{},[60,116,117,118,121,122,125],{},"Strings use double quotes (",[21,119,120],{},"\"",", not ",[21,123,124],{},"'",").",[60,127,128],{},"Keys are double-quoted.",[60,130,131],{},"No trailing commas.",[60,133,134],{},"No comments.",[60,136,137],{},"Brackets and braces are balanced.",[60,139,140,141,144],{},"Numbers, booleans, and ",[21,142,143],{},"null"," are in correct form.",[15,146,147,148,151],{},"If any of these rules are violated, JavaScript throws a ",[21,149,150],{},"SyntaxError",". Common problems include trailing commas from JavaScript object literals, single-quoted strings, and unquoted keys.",[104,153,155],{"id":154},"common-syntax-errors","Common syntax errors",[15,157,158],{},"This JSON looks reasonable but fails to parse:",[41,160,163],{"className":161,"code":162,"language":46,"meta":47},[44],"{\n  \"email\": \"ada@example.com\",\n  \"age\": 36,\n}\n",[21,164,162],{"__ignoreMap":47},[15,166,167,168,171],{},"The trailing comma after ",[21,169,170],{},"36"," makes it invalid. Fix:",[41,173,176],{"className":174,"code":175,"language":46,"meta":47},[44],"{\n  \"email\": \"ada@example.com\",\n  \"age\": 36\n}\n",[21,177,175],{"__ignoreMap":47},[15,179,180],{},"Other frequent mistakes:",[57,182,183,190,196,203],{},[60,184,185,186,189],{},"Single quotes instead of double quotes: ",[21,187,188],{},"{ 'name': 'Ada' }"," → invalid.",[60,191,192,193,189],{},"Comments: ",[21,194,195],{},"{ \"name\": \"Ada\" \u002F\u002F developer note }",[60,197,198,199,202],{},"Unquoted keys: ",[21,200,201],{},"{ name: \"Ada\" }"," → invalid in JSON (valid in JavaScript object literals).",[60,204,205,206,189],{},"Unclosed brackets: ",[21,207,208],{},"{ \"items\": [1, 2, 3",[104,210,212],{"id":211},"a-safe-syntax-check-helper","A safe syntax-check helper",[15,214,215,216,218,219,222],{},"Instead of wrapping ",[21,217,23],{}," in a bare ",[21,220,221],{},"try\u002Fcatch",", return a structured result so callers can display meaningful error messages:",[41,224,229],{"className":225,"code":227,"language":228,"meta":47},[226],"language-ts","export type JsonSyntaxResult =\n  | { valid: true; value: unknown }\n  | { valid: false; error: string }\n\nexport function parseJsonSafely(text: string): JsonSyntaxResult {\n  try {\n    return { valid: true, value: JSON.parse(text) }\n  } catch (error) {\n    return {\n      valid: false,\n      error: error instanceof Error ? error.message : 'Invalid JSON',\n    }\n  }\n}\n","ts",[21,230,227],{"__ignoreMap":47},[15,232,233,234,236,237,102],{},"This only verifies JSON syntax. It does not verify required fields, types, allowed values, or application rules. If ",[21,235,23],{}," throws before you can inspect the data, start with our guide to ",[238,239,241],"a",{"href":240},"\u002Fblog\u002Fjson-parse-error-debug","debugging common JSON parse errors in API responses",[104,243,245],{"id":244},"when-to-use-an-online-json-validator","When to use an online JSON Validator",[15,247,248,249,253],{},"For quick checks during development or when reviewing API responses from logs, paste the raw text into a ",[238,250,252],{"href":251},"\u002Ftools\u002Fformat\u002Fjson-editor","JSON syntax validator"," to see whether it parses and where errors occur. This is especially useful when the JSON is minified or comes from an unfamiliar source.",[29,255,257],{"id":256},"layer-2-schema-validation-does-the-data-have-the-expected-shape","Layer 2: Schema Validation — Does the Data Have the Expected Shape?",[15,259,260],{},"Syntax validation tells you the text is JSON. Schema validation tells you the data matches the structure your application expects.",[104,262,264],{"id":263},"what-json-schema-validates","What JSON Schema validates",[15,266,267,273],{},[238,268,272],{"href":269,"rel":270},"https:\u002F\u002Fjson-schema.org\u002Fdocs",[271],"nofollow","JSON Schema"," is a declarative vocabulary for describing the structure, constraints, and data types of JSON documents. A schema can specify:",[57,275,276,281,284,287,290],{},[60,277,278,279,102],{},"The expected type: object, array, string, number, boolean, or ",[21,280,143],{},[60,282,283],{},"Which fields are required.",[60,285,286],{},"Allowed values for each field.",[60,288,289],{},"Numeric ranges, string patterns, and array lengths.",[60,291,292],{},"Whether extra fields are permitted.",[15,294,295],{},"The schema is itself a JSON document, which makes it portable across languages and tools.",[104,297,299],{"id":298},"the-user-creation-schema","The user creation schema",[15,301,302,303,305,306,311],{},"Here is a JSON Schema for the ",[21,304,38],{}," payload. It uses ",[238,307,310],{"href":308,"rel":309},"https:\u002F\u002Fjson-schema.org\u002Fdraft\u002F2020-12\u002Fschema",[271],"Draft 2020-12",":",[41,313,316],{"className":314,"code":315,"language":46,"meta":47},[44],"{\n  \"$schema\": \"https:\u002F\u002Fjson-schema.org\u002Fdraft\u002F2020-12\u002Fschema\",\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"required\": [\"email\", \"age\", \"role\", \"marketingOptIn\"],\n  \"properties\": {\n    \"email\": {\n      \"type\": \"string\",\n      \"format\": \"email\"\n    },\n    \"age\": {\n      \"type\": \"integer\",\n      \"minimum\": 0,\n      \"maximum\": 150\n    },\n    \"role\": {\n      \"type\": \"string\",\n      \"enum\": [\"user\", \"editor\", \"admin\"]\n    },\n    \"marketingOptIn\": {\n      \"type\": \"boolean\"\n    }\n  }\n}\n",[21,317,315],{"__ignoreMap":47},[104,319,321],{"id":320},"how-to-read-this-schema","How to read this schema",[323,324,325,338],"table",{},[326,327,328],"thead",{},[329,330,331,335],"tr",{},[332,333,334],"th",{},"Keyword",[332,336,337],{},"What it enforces",[339,340,341,352,362,372,382,398,411],"tbody",{},[329,342,343,349],{},[344,345,346],"td",{},[21,347,348],{},"type: \"object\"",[344,350,351],{},"The root value must be a JSON object.",[329,353,354,359],{},[344,355,356],{},[21,357,358],{},"required",[344,360,361],{},"These fields must be present.",[329,363,364,369],{},[344,365,366],{},[21,367,368],{},"properties",[344,370,371],{},"Defines the expected shape for each field.",[329,373,374,379],{},[344,375,376],{},[21,377,378],{},"format: \"email\"",[344,380,381],{},"Declares the expected format. Enforcement depends on the validator (see below).",[329,383,384,393],{},[344,385,386,389,390],{},[21,387,388],{},"minimum"," \u002F ",[21,391,392],{},"maximum",[344,394,395,396,102],{},"Numeric boundaries for ",[21,397,70],{},[329,399,400,405],{},[344,401,402],{},[21,403,404],{},"enum",[344,406,407,408,410],{},"Restricts ",[21,409,76],{}," to the listed values.",[329,412,413,418],{},[344,414,415],{},[21,416,417],{},"additionalProperties: false",[344,419,420,421,423,424,102],{},"Rejects any field not declared in ",[21,422,368],{}," or ",[21,425,426],{},"patternProperties",[15,428,429],{},"Two details that often cause confusion:",[431,432,433,454],"ol",{},[60,434,435,441,442,444,445,447,448,450,451,453],{},[436,437,438,440],"strong",{},[21,439,368],{}," does not make fields required."," Listing a field in ",[21,443,368],{}," only defines its schema. You must also list it in ",[21,446,358],{}," to make it mandatory. A field can appear in ",[21,449,368],{}," but be absent from ",[21,452,358],{},", making it optional.",[60,455,456,462,463,466,467,470,471,473],{},[436,457,458,461],{},[21,459,460],{},"additionalProperties"," defaults to allowing extra fields."," If you do not set it to ",[21,464,465],{},"false",", an object with unexpected fields like ",[21,468,469],{},"\"debug\": true"," will pass validation. Only an explicit ",[21,472,417],{}," rejects undeclared fields.",[104,475,477,478,481],{"id":476},"the-format-keyword-caveat","The ",[21,479,480],{},"format"," keyword caveat",[15,483,477,484,486,487,492,493,500,501,504],{},[21,485,480],{}," keyword communicates an intended format, but whether it is enforced depends on the JSON Schema validator and its configuration. For example, ",[238,488,491],{"href":489,"rel":490},"https:\u002F\u002Fajv.js.org\u002Fapi.html",[271],"Ajv"," v7+ provides common format validators through the optional ",[238,494,497],{"href":495,"rel":496},"https:\u002F\u002Fajv.js.org\u002Fguide\u002Fformats.html",[271],[21,498,499],{},"ajv-formats"," package. Without it, ",[21,502,503],{},"\"format\": \"email\""," is treated as an annotation, not a validation rule. Always verify your validator's configuration before relying on format checks in production.",[104,506,508],{"id":507},"a-valid-json-document-that-fails-schema-validation","A valid JSON document that fails schema validation",[15,510,511,512,514],{},"The payload from the introduction passes ",[21,513,23],{}," but fails the schema:",[41,516,518],{"className":517,"code":45,"language":46,"meta":47},[44],[21,519,45],{"__ignoreMap":47},[15,521,522],{},"A schema validator would report these errors:",[323,524,525,535],{},[326,526,527],{},[329,528,529,532],{},[332,530,531],{},"Path",[332,533,534],{},"Problem",[339,536,537,549,566,579,596],{},[329,538,539,544],{},[344,540,541],{},[21,542,543],{},"\u002Femail",[344,545,546,547,102],{},"Value does not match format ",[21,548,64],{},[329,550,551,556],{},[344,552,553],{},[21,554,555],{},"\u002Fage",[344,557,558,559,562,563,102],{},"Value ",[21,560,561],{},"-3"," is less than minimum ",[21,564,565],{},"0",[329,567,568,573],{},[344,569,570],{},[21,571,572],{},"\u002Frole",[344,574,558,575,578],{},[21,576,577],{},"superadmin"," is not one of the allowed enum values.",[329,580,581,586],{},[344,582,583],{},[21,584,585],{},"\u002FmarketingOptIn",[344,587,588,589,592,593,102],{},"Expected ",[21,590,591],{},"boolean",", got ",[21,594,595],{},"string",[329,597,598,603],{},[344,599,600],{},[21,601,602],{},"\u002Fdebug",[344,604,605,606,608,609,611,612,102],{},"Property ",[21,607,88],{}," is not allowed when ",[21,610,460],{}," is ",[21,613,465],{},[15,615,616,617,621],{},"You can test this interactively with the ",[238,618,620],{"href":619},"\u002Ftools\u002Fformat\u002Fjson-schema-validator","JSON Schema Validator"," — paste the payload and the schema side by side to see the errors.",[29,623,625],{"id":624},"layer-3-business-validation-can-your-application-accept-this-data","Layer 3: Business Validation — Can Your Application Accept This Data?",[15,627,628],{},"Schema validation is powerful, but it cannot express rules that depend on your system's state. Business validation handles those cases with application logic.",[104,630,632],{"id":631},"examples-json-schema-cannot-fully-decide","Examples JSON Schema cannot fully decide",[57,634,635,645,655,664,675],{},[60,636,637,638,641,642,644],{},"The email address ",[21,639,640],{},"ada@example.com"," is syntactically valid and matches the ",[21,643,64],{}," format, but it may already exist in your database.",[60,646,647,648,650,651,654],{},"An ",[21,649,70],{}," of 200 passes the ",[21,652,653],{},"minimum: 0"," check but may be rejected by a business rule capping realistic ages.",[60,656,657,658,660,661,102],{},"A user's ",[21,659,76],{}," may be valid per the enum, but the authenticated caller may not have permission to assign ",[21,662,663],{},"admin",[60,665,666,667,670,671,674],{},"A ",[21,668,669],{},"startDate"," and ",[21,672,673],{},"endDate"," may both be valid ISO 8601 strings, but the start may fall after the end.",[60,676,677],{},"A product ID may exist in the schema, but the product may be out of stock.",[15,679,680],{},"These checks require querying a database, verifying permissions, or running application-specific logic. No JSON Schema can replace them.",[104,682,684],{"id":683},"client-side-versus-server-side-validation","Client-side versus server-side validation",[15,686,687],{},"Run schema validation on both the client and the server when it improves user feedback. But always validate again on the backend. Client-side checks:",[57,689,690,693,696],{},[60,691,692],{},"Can be bypassed by modifying network requests.",[60,694,695],{},"Cannot safely enforce permissions or database constraints.",[60,697,698],{},"Should be treated as a UX convenience, not a security measure.",[29,700,702],{"id":701},"how-to-validate-json-in-javascript","How to Validate JSON in JavaScript",[15,704,705,706,708],{},"Here is a complete validation pipeline for the ",[21,707,38],{}," endpoint.",[104,710,712],{"id":711},"step-1-syntax-validation","Step 1: Syntax validation",[41,714,717],{"className":715,"code":716,"language":228,"meta":47},[226],"import Ajv from 'ajv'\nimport addFormats from 'ajv-formats'\n\nconst ajv = new Ajv({ allErrors: true, strict: true })\naddFormats(ajv)\n\nconst createUserSchema = {\n  type: 'object',\n  additionalProperties: false,\n  required: ['email', 'age', 'role', 'marketingOptIn'],\n  properties: {\n    email: { type: 'string', format: 'email' },\n    age: { type: 'integer', minimum: 0, maximum: 150 },\n    role: { type: 'string', enum: ['user', 'editor', 'admin'] },\n    marketingOptIn: { type: 'boolean' },\n  },\n} as const\n\nconst validateCreateUser = ajv.compile(createUserSchema)\n",[21,718,716],{"__ignoreMap":47},[15,720,721,722,725,726,102],{},"Ajv compiles the schema into a reusable validation function. It supports multiple JSON Schema drafts and reports all errors when ",[21,723,724],{},"allErrors"," is set to ",[21,727,728],{},"true",[104,730,732],{"id":731},"step-2-schema-validation","Step 2: Schema validation",[41,734,737],{"className":735,"code":736,"language":228,"meta":47},[226],"export function validateCreateUserPayload(value: unknown) {\n  const valid = validateCreateUser(value)\n  return {\n    valid: Boolean(valid),\n    errors: validateCreateUser.errors ?? [],\n  }\n}\n",[21,738,736],{"__ignoreMap":47},[104,740,742],{"id":741},"step-3-the-full-pipeline","Step 3: The full pipeline",[41,744,747],{"className":745,"code":746,"language":228,"meta":47},[226],"export function validateIncomingUserJson(text: string) {\n  \u002F\u002F Layer 1: Syntax\n  const parsed = parseJsonSafely(text)\n  if (!parsed.valid) {\n    return { ok: false as const, stage: 'syntax' as const, errors: [parsed.error] }\n  }\n\n  \u002F\u002F Layer 2: Schema\n  const schemaResult = validateCreateUserPayload(parsed.value)\n  if (!schemaResult.valid) {\n    return { ok: false as const, stage: 'schema' as const, errors: schemaResult.errors }\n  }\n\n  \u002F\u002F Layer 3: Business (example — you would implement this with your DB\u002Flogic)\n  \u002F\u002F if (await emailAlreadyExists(parsed.value.email)) {\n  \u002F\u002F   return { ok: false, stage: 'business', errors: ['Email is already registered'] }\n  \u002F\u002F }\n\n  return { ok: true as const, value: parsed.value }\n}\n",[21,748,746],{"__ignoreMap":47},[15,750,751],{},"This function runs the cheapest check first. If syntax fails, there is no point running schema validation. If schema fails, there is no point querying the database.",[29,753,755],{"id":754},"api-error-response-design","API Error Response Design",[15,757,758],{},"A well-designed API returns different error shapes depending on which validation layer failed.",[104,760,762],{"id":761},"syntax-error-400-bad-request","Syntax error → 400 Bad Request",[41,764,767],{"className":765,"code":766,"language":46,"meta":47},[44],"{\n  \"error\": {\n    \"code\": \"INVALID_JSON\",\n    \"message\": \"Request body is not valid JSON.\"\n  }\n}\n",[21,768,766],{"__ignoreMap":47},[104,770,772],{"id":771},"schema-error-422-unprocessable-entity","Schema error → 422 Unprocessable Entity",[41,774,777],{"className":775,"code":776,"language":46,"meta":47},[44],"{\n  \"error\": {\n    \"code\": \"VALIDATION_FAILED\",\n    \"message\": \"Request data does not match the expected schema.\",\n    \"fields\": [\n      { \"path\": \"\u002Femail\", \"message\": \"must match format \\\"email\\\"\" },\n      { \"path\": \"\u002Fage\", \"message\": \"must be >= 0\" },\n      { \"path\": \"\u002FmarketingOptIn\", \"message\": \"must be boolean\" }\n    ]\n  }\n}\n",[21,778,776],{"__ignoreMap":47},[104,780,782],{"id":781},"business-rule-error-409-conflict-or-422","Business-rule error → 409 Conflict or 422",[41,784,787],{"className":785,"code":786,"language":46,"meta":47},[44],"{\n  \"error\": {\n    \"code\": \"EMAIL_ALREADY_EXISTS\",\n    \"message\": \"An account already uses this email address.\"\n  }\n}\n",[21,788,786],{"__ignoreMap":47},[15,790,791],{},"Many APIs use 400 for malformed JSON and 422 for structurally valid data that fails validation, but your API should follow one documented and consistent convention.",[29,793,795],{"id":794},"common-json-validation-mistakes","Common JSON Validation Mistakes",[104,797,799],{"id":798},"mistake-1-treating-jsonparse-success-as-api-validation","Mistake 1: Treating JSON.parse() success as API validation",[15,801,802,804],{},[21,803,23],{}," succeeding only means the text is valid JSON. It says nothing about whether the data matches your API contract. Always run schema validation after parsing.",[104,806,808],{"id":807},"mistake-2-relying-on-content-type-alone","Mistake 2: Relying on Content-Type alone",[15,810,811,812,815],{},"A request with ",[21,813,814],{},"Content-Type: application\u002Fjson"," header may still contain a body that is not valid JSON. Always parse and validate the body, not just the header.",[104,817,819],{"id":818},"mistake-3-allowing-unknown-fields-accidentally","Mistake 3: Allowing unknown fields accidentally",[15,821,822,823,825],{},"If your schema does not include ",[21,824,417],{},", unexpected fields pass through silently. This can leak internal debug data into your system or cause subtle bugs when clients send fields you did not expect.",[104,827,829],{"id":828},"mistake-4-coercing-values-without-documenting-it","Mistake 4: Coercing values without documenting it",[15,831,832,833,836,837,423,840,836,843,845],{},"Some frameworks silently convert ",[21,834,835],{},"\"42\""," to ",[21,838,839],{},"42",[21,841,842],{},"\"true\"",[21,844,728],{},". If your API does this, document it clearly. Silent coercion can hide client bugs and make debugging harder. When in strict mode, Ajv rejects type mismatches rather than coercing them.",[104,847,849],{"id":848},"mistake-5-validating-only-in-the-browser","Mistake 5: Validating only in the browser",[15,851,852],{},"Client-side validation improves UX but can be bypassed. Every request that modifies data must be validated again on the server.",[104,854,856],{"id":855},"mistake-6-logging-raw-invalid-payloads-with-secrets","Mistake 6: Logging raw invalid payloads with secrets",[15,858,859],{},"When logging validation failures, strip or redact sensitive fields like tokens, passwords, and API keys before writing to logs.",[29,861,863],{"id":862},"a-practical-api-validation-workflow","A Practical API Validation Workflow",[15,865,866],{},"For each incoming JSON request:",[431,868,869,875,884,890,896,902],{},[60,870,871,874],{},[436,872,873],{},"Enforce a body-size limit."," Reject payloads that exceed your expected maximum before parsing.",[60,876,877,880,881,883],{},[436,878,879],{},"Parse the JSON."," Use ",[21,882,23],{}," or an equivalent. If it fails, return a 400 error with the parse error message.",[60,885,886,889],{},[436,887,888],{},"Validate against a schema."," Check required fields, types, ranges, and additional properties. If it fails, return a 422 error with the list of schema violations.",[60,891,892,895],{},[436,893,894],{},"Apply business rules."," Check database constraints, permissions, and application logic. If it fails, return a 409 or 422 error with a specific error code.",[60,897,898,901],{},[436,899,900],{},"Return structured errors."," Include a machine-readable error code, a human-readable message, and field-level details for schema errors.",[60,903,904,907],{},[436,905,906],{},"Log safely."," Redact sensitive fields before writing to logs.",[29,909,911],{"id":910},"faq","FAQ",[104,913,915],{"id":914},"does-jsonparse-validate-json-schema","Does JSON.parse() validate JSON Schema?",[15,917,918,919,921,922,925],{},"No. ",[21,920,23],{}," only checks whether a string follows JSON syntax and converts it into a JavaScript value. It does not check whether required fields exist, whether values have expected types, or whether extra fields are allowed. Use a schema validator like ",[238,923,491],{"href":489,"rel":924},[271]," for that.",[104,927,929],{"id":928},"is-valid-json-always-safe-to-use-as-api-data","Is valid JSON always safe to use as API data?",[15,931,932,933,935,936,938],{},"No. A payload may be syntactically valid JSON but still fail your API contract. For example, an ",[21,934,70],{}," field may be negative, a required field may be missing, or a ",[21,937,76],{}," may not be one of the allowed values. Syntax validation is only the first layer.",[104,940,942],{"id":941},"should-i-validate-json-in-the-frontend-or-backend","Should I validate JSON in the frontend or backend?",[15,944,945],{},"Validate on both when it improves user feedback, but always validate again on the backend. Client-side checks can be bypassed and cannot safely enforce permissions, database constraints, or other server-side business rules.",[104,947,949,950,952],{"id":948},"does-format-email-always-validate-email-addresses","Does ",[21,951,503],{}," always validate email addresses?",[15,954,955,956,961],{},"Not necessarily. JSON Schema validators differ in how they implement and enable format checks. With Ajv, common formats are provided through the ",[238,957,959],{"href":495,"rel":958},[271],[21,960,499],{}," package, so confirm your validator configuration before relying on format validation in production.",[29,963,965],{"id":964},"whats-next","What's Next?",[57,967,968,978,987,998],{},[60,969,970,973,974,977],{},[436,971,972],{},"Already have a broken payload?"," Start with ",[238,975,976],{"href":240},"JSON Parse Failed: 10 Common API Errors and How to Debug Them"," to find and fix the syntax error.",[60,979,980,983,984,986],{},[436,981,982],{},"Need to validate JSON against a schema?"," Use the ",[238,985,620],{"href":619}," to paste your data and schema side by side.",[60,988,989,992,993,997],{},[436,990,991],{},"Want to inspect complex JSON structure?"," ",[238,994,996],{"href":995},"\u002Ftools\u002Fformat\u002Fjson-path-tester","View your JSON as an interactive tree"," to explore nested fields.",[60,999,1000,1003,1004,1008],{},[436,1001,1002],{},"Building an API from scratch?"," Read our guide to ",[238,1005,1007],{"href":1006},"\u002Fblog\u002Fjson-best-practices","JSON best practices"," for error handling, validation, and response design.",[1010,1011],"hr",{},[15,1013,1014],{},[1015,1016,1017],"em",{},"All tools on JSON Toolbox run entirely in your browser. Your data never leaves your device.",{"title":47,"searchDepth":1019,"depth":1019,"links":1020},2,[1021,1022,1029,1037,1041,1046,1051,1059,1060,1067],{"id":31,"depth":1019,"text":32},{"id":95,"depth":1019,"text":96,"children":1023},[1024,1026,1027,1028],{"id":106,"depth":1025,"text":107},3,{"id":154,"depth":1025,"text":155},{"id":211,"depth":1025,"text":212},{"id":244,"depth":1025,"text":245},{"id":256,"depth":1019,"text":257,"children":1030},[1031,1032,1033,1034,1036],{"id":263,"depth":1025,"text":264},{"id":298,"depth":1025,"text":299},{"id":320,"depth":1025,"text":321},{"id":476,"depth":1025,"text":1035},"The format keyword caveat",{"id":507,"depth":1025,"text":508},{"id":624,"depth":1019,"text":625,"children":1038},[1039,1040],{"id":631,"depth":1025,"text":632},{"id":683,"depth":1025,"text":684},{"id":701,"depth":1019,"text":702,"children":1042},[1043,1044,1045],{"id":711,"depth":1025,"text":712},{"id":731,"depth":1025,"text":732},{"id":741,"depth":1025,"text":742},{"id":754,"depth":1019,"text":755,"children":1047},[1048,1049,1050],{"id":761,"depth":1025,"text":762},{"id":771,"depth":1025,"text":772},{"id":781,"depth":1025,"text":782},{"id":794,"depth":1019,"text":795,"children":1052},[1053,1054,1055,1056,1057,1058],{"id":798,"depth":1025,"text":799},{"id":807,"depth":1025,"text":808},{"id":818,"depth":1025,"text":819},{"id":828,"depth":1025,"text":829},{"id":848,"depth":1025,"text":849},{"id":855,"depth":1025,"text":856},{"id":862,"depth":1019,"text":863},{"id":910,"depth":1019,"text":911,"children":1061},[1062,1063,1064,1065],{"id":914,"depth":1025,"text":915},{"id":928,"depth":1025,"text":929},{"id":941,"depth":1025,"text":942},{"id":948,"depth":1025,"text":1066},"Does \"format\": \"email\" always validate email addresses?",{"id":964,"depth":1019,"text":965},"json_tools","2026-09-03T00:00:00.000Z","Learn the difference between JSON syntax validation and JSON Schema validation. Understand three validation layers with practical JavaScript examples for validating API data safely.",false,"md","\u002Fblog\u002Fcover\u002Fen\u002Fjson-validation-syntax-vs-schema-cover.svg",[1075,1076],"en","zh",{},true,"\u002Fen\u002Fblog\u002Fjson-validation-syntax-vs-schema",{"slug":1081,"text":1082,"btn":1083},"json-schema-validator","Validate your JSON data against a JSON Schema:","Open JSON Schema Validator",{"title":5,"description":1070},"en\u002Fblog\u002Fjson-validation-syntax-vs-schema",[1087,1088,272,1089,1090,1091],"JSON","JSON Validation","JavaScript","API Validation","Data Validation","ZVmiUdPnjatrK0u75M9aYD2o6oxI2AkNmzhzFuX_CVs",[1094,1097],{"path":1095,"title":1096},"\u002Fen\u002Fblog\u002Ffree-realistic-json-test-data","Free Realistic JSON Test Data for Development and Performance Testing",{"path":1098,"title":1099},"\u002Fzh\u002Fblog\u002Fjson-validation-syntax-vs-schema","JSON 校验详解：语法校验、JSON Schema 与业务规则的区别",1791273861901]