← Back to Blog2025-12-269 min read

JSON Schema validation: how to catch bad API payloads before they break you

A practical workflow for validating JSON payloads with JSON Schema: what it catches, how to read errors, and how to debug common failures.

By RawTools Teamjson schema validator

When “valid JSON” isn’t enough

A JSON payload can be syntactically valid and still break your app. The classic failure modes aren’t about missing commas; they’re about shape: a field is missing, a number arrives as a string, an array contains the wrong object type, or a nested field has a different name.

JSON Schema is a way to make the shape explicit. It gives you a contract you can validate against before a payload hits the business logic.

What JSON Schema validation actually catches

  • Required fields: missing properties that your code assumes exist.
  • Types: string vs number vs boolean vs object vs array.
  • Allowed values: enums for known states (e.g., "pending" | "paid" | "failed").
  • Formats and patterns: emails, URIs, regex patterns (with caveats).
  • Extra properties: optionally disallow unknown fields to catch typos early.

What it does not catch: whether an ID exists in your database, whether a SKU is sellable, or whether a timestamp is in the future. Schema is structural validation, not business validation.

A small schema example you can adapt

Here’s a realistic “create customer” payload example that covers the cases people trip over: required fields, nested objects, arrays, and optional metadata.

{
  "type": "object",
  "additionalProperties": false,
  "required": ["id", "email", "createdAt"],
  "properties": {
    "id": { "type": "string", "minLength": 1 },
    "email": { "type": "string", "format": "email" },
    "createdAt": { "type": "string", "format": "date-time" },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "default": []
    },
    "marketing": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "consent": { "type": "boolean" },
        "source": { "type": "string", "enum": ["checkout", "signup", "import"] }
      }
    },
    "metadata": {
      "type": "object",
      "additionalProperties": true
    }
  }
}

If you want to test this quickly against real payloads, use the JSON Schema Validator. If your input JSON is messy, run it through JSON Formatter first so errors are easier to locate.

How to read schema validation errors without guessing

The key is to focus on two locations:

  • Instance path: where in the JSON the problem occurred.
  • Schema path: which rule was violated.

Most teams waste time because they only read the error message text. The path tells you what to fix, and which rule you actually wrote.

Debug workflow that stays fast in real projects

  1. Format the payload so you can see the actual structure (JSON Formatter).
  2. Validate against the schema and copy the first error (JSON Schema Validator).
  3. Isolate the failing subtree (copy just that object/array) so you stop scanning the whole payload.
  4. Confirm type assumptions (strings coming from CSV imports are the most common issue).
  5. Re-run validation until the first error disappears; don’t chase the fifth error first.

If your payload is deeply nested and you’re trying to confirm a value exists at a path, it’s often faster to query it than to scroll. Use JSON Query for that, or visually pick fields with JSON Mapper.

Common schema mistakes that create false confidence

  • Forgetting additionalProperties: you miss typos like emali that silently pass through.
  • Using type: "number" when inputs are strings: many sources (CSV, HTML forms) deliver strings. Decide whether you coerce or reject.
  • Overusing anyOf/oneOf: powerful, but can make errors harder to interpret. Start simple.
  • Not modeling nullability: if you allow null, say so explicitly (e.g., type: ["string","null"]).

Keep the contract readable

Schemas tend to rot when they become unreadable. Two practical habits help:

  • Use definitions for repeated objects (addresses, money fields, identifiers).
  • Prefer small, composable schemas over one massive schema that tries to cover every endpoint.

When you need to ship schemas over the wire or store them, minify them (JSON Minifier) and keep the formatted version for humans.

FAQs

Does JSON Schema validate that an ID exists?

No. Schema validates structure and basic constraints. Existence checks are business logic (e.g., database lookups).

Why does validation fail when a number is in quotes?

Because "12.50" is a string, not a number. Decide whether you want to coerce inputs before validation or reject and fix the source.

Should I set additionalProperties to false?

If you want a strict contract, yes—especially for public APIs. For internal payloads, you may allow extra fields in metadata while keeping the top-level strict.

What’s the fastest way to debug a failing schema?

Fix the first error reported, then re-run validation. Many later errors disappear once the structure is correct.

Can I validate arrays of objects?

Yes. Use type: "array" and define the items schema as an object. If each item must be unique, add uniqueItems (with performance caveats for large arrays).

Do I need JSON Schema if I already have TypeScript types?

Types help at compile time. Schema helps at runtime when data crosses a boundary (HTTP, queue, file import). They solve different problems.

How do I quickly check a nested value exists before validating?

Use JSON Query to test a JSONPath expression against the payload, or use JSON Mapper to pick the path visually.

📑 Quick Info

📅
Published
2025-12-26
⏱️
Reading Time
9 min
✍️
Author
RawTools Team