I once maintained a JSON Schema by hand for a payment webhook payload. For months it was fine. Then the provider added a field, my schema said additionalProperties: false, and a valid payload started failing validation at 2am. The schema wasn't wrong when I wrote it. It was wrong the moment reality changed and I didn't.
Hand-written schemas drift
That's the core problem with writing JSON Schema by hand: it's a snapshot of what you believed the data looked like on the day you wrote it. Nobody updates the schema when the payload changes, because the schema lives in one repo and the actual payloads live in production.
There's a better starting point than belief: the actual sample payloads you already have.
Sample-first, then tighten
The workflow that's worked for me since: paste a real sample response into JSONSchema, get back a draft 2020-12 schema with required fields marked automatically, plus a plain-English explanation of every validation rule it generated. Then you tighten it — because you know which fields are optional in practice, which strings are actually enums, and which number is really an integer that must be positive.
The explanation part matters more than it sounds. Half the reason schemas rot is that nobody remembers what pattern regex was supposed to match six months later. A schema you can read is a schema you'll maintain.
Where this fits in real work
- Documenting a legacy API that has no schema at all — point it at a real response, work backwards.
- Contract testing — generate the schema from a captured payload, then enforce it in CI so drift fails a build instead of failing a customer.
- Feeding structured output contracts to LLM tooling, where strict schemas are basically a requirement now.
One habit that helped: regenerate from a fresh sample after any provider API change, and diff the two schemas. The diff is the changelog the provider forgot to send you.
What it is not
It won't guess your business rules. Nothing can infer "this integer is a percent between 0 and 100" from one sample where the value happens to be 42 — that's your job, and the tool leaves those decisions visible rather than silently inventing constraints. Samples with missing optional fields will produce schemas that mark things required that aren't; check the required list before you trust it. And it outputs draft 2020-12, so if you're stuck on draft-04 tooling, you'll need to adjust.
Try it on your worst payload
Grab the ugliest, most optional-field-riddled JSON response your system deals with and paste it into JSONSchema. If the generated schema marks something required that shouldn't be, that gap in your sample data just told you something about your test coverage too.
Top comments (0)