A few months ago, our platform team hit a wall. The backend kept emitting payloads the frontend said it could not parse, the data lake rejected daily extracts for "schema drift," and the on-call rotation spent more time arguing whose job validation was than fixing anything. None of this was because engineers didn't know what valid JSON looked like. The problem was that twelve people touched a payload between producer and consumer, and each of them had a different mental model for what "looks right" meant.
That is the gap this article addresses. Not "what is JSON" — you already know — but the operational question: when a JSON payload moves across team boundaries, what concrete checks does each person on the path need to perform, in what order, and how do you keep the bar high without turning it into a bottleneck? I have shipped this checklist across three product teams now, refined it twice, and the source of friction has dropped meaningfully.
Why a Personal Definition of "Looks Right" Is Not Enough
JSON's grammar is small. The ECMA-404 JSON specification defines six structural forms, two number representations, and three literal keywords. Any engineer can memorize that in an afternoon. The trouble starts when payloads become the contract between services, and the contract has dozens of constraints that JSON does not natively express — required fields, enum values, date formats, numeric ranges, locale, currency, time zones.
When that contract lives only in someone's head, every reviewer applies their own subset. The backend reviewer checks field presence; the QA reviewer checks value plausibility; the frontend reviewer checks rendering safety. Each step passes in isolation, but the merged review has gaps. The fix is not more discipline, more discipline. The fix is to write the contract down and structure the review so each role has a narrow, explicit job.
I treat the payload as an artifact that travels through five stations, and at each station a different person asks a different question. The station list is intentionally short. Long checklists do not get read. Short, role-specific ones do.
The Five Stations of a JSON Payload
Station 1: Producer Authoring
Whoever writes the code that constructs the payload owns the first review. The question they ask is not "does this parse" but "does this match the schema we agreed on?" That requires the schema to exist as a versioned file in a shared repo, not buried in a Slack thread from three sprints ago.
The authoring check should cover five things, in order:
- The payload builds without runtime errors (no
undefinedconverted to a string, no missing keys producing partial objects). - Required fields are populated for every code path, including partial-success branches and retry handlers.
- Enum values come from a closed set, not a free-text type.
- Date/time values are emitted in exactly one canonical format — RFC 3339 with an explicit offset is the safest default, and the RFC 3339 specification is the authoritative reference.
- Numbers that should be integers stay integers; never let a JavaScript float leak into an integer field.
I have seen item 5 cause real outages. A JavaScript service computed 42 / 1, stored it, and emitted 42. A separate service computed 42 / 3, then logged the same field. Both payloads "looked fine." The downstream accountant could not reconcile either.
Station 2: Contract Validation at the Producer Boundary
Before a payload leaves the producer's service, it should be validated against the schema that the consumers agreed to. This is the moment to fail fast — either reject the payload with a structured error and a correlation ID, or quarantine it for human review. What you must not do is let a malformed payload join a queue and hope the consumer finds it later.
Two practical rules for this station:
- Run validation in the same process as emission, so the producer sees the failure in their own dashboard. Distributed failures where only the consumer logs the error are debugging hell.
- Capture a redacted sample of the failed payload alongside the validation error. Redact first, capture second. You want enough bytes to reproduce the bug without leaking PII into a log bucket that does not have the right access controls.
Station 3: Consumer-Side Structure Check
The consumer checks the opposite question from the producer: "given a payload that passed producer validation, is it shaped the way I expect?" This is where defensive parsing earns its keep — but defensive parsing is not the same as paranoid parsing. You want to handle three cases explicitly:
- Missing optional fields: substitute a documented default, do not throw.
- Unexpected extra fields: ignore them, do not log them at info level (they're noise, and they're a privacy risk).
- Type-shape mismatches the producer's validation missed: surface a clear, actionable error that names the field, the expected type, and the actual type, and route the payload to a quarantine queue.
Notice that station 3 deliberately does not include business-logic validation. That belongs elsewhere. If a reviewer finds themselves asking "is this order's total correct," they have drifted out of structure and into semantics, and the review will never finish.
Station 4: Cross-Team Schema Diff on Every Change
This is the station teams skip, and the one that costs the most. When a payload schema changes — a field is renamed, a value's meaning shifts, a new enum member is added — every consumer team needs to know before the change ships, not after. A green CI on the producer's repo tells you nothing about whether the consumer's parser still works.
A workable cadence is to require an explicit diff review for any schema file under source control, with at least one reviewer from each downstream consumer team. The diff should be small enough to read in five minutes; if it is not, the schema is probably doing too much and needs splitting. You can pair this station with a generated changelog so consumers can audit their exposure at any time, not just at the moment of the change.
Station 5: Periodic Sampling Audit
Once a quarter, pull a random sample of production payloads from each boundary and run them through the full contract check — the same check the producer ran in station 2, but on real traffic. Drift happens. Producers add fields "just for now." Consumers filter around edge cases and forget the producer never fixed them. A quarterly audit catches these before they become "the system has always behaved this way" lore.
Sample size matters less than sample honesty. I aim for 30 to 50 payloads per boundary, drawn from across the time and customer distribution. Spot-checking what you happen to remember only confirms your own biases.
Picking Tools That Fit the Checklist, Not the Other Way Around
The checklist above is intentionally tool-agnostic. You will need a schema language (JSON Schema is the standard, but Avro or Protobuf work too), a validator that runs in the producer process, and a workspace where reviewers can paste a payload and see the structured result against the schema in seconds. The workspace matters more than people expect — the difference between a reviewer running a validation step and skipping it is usually how long the step takes.
The Lizely team's JSON Validator is a sensible fit for stations 3 and 5: paste a payload, paste the schema, get a line-numbered, plain-English report of what mismatches and why. I have used it to debug cross-team schema drift specifically because the error messages name the path, not just the byte offset, which is what most parser errors do.
For the deeper reference on the broader question of structural validity — what counts as a real JSON document, how strict a parser should be, and where common tooling draws the line — the JSON reference on MDN is the document I send to new reviewers. It is concise, accurate, and stable.
Frequently asked questions
How do we get a team to adopt this when they already "know JSON"?
Start with the pain. Find the most recent cross-team payload bug, walk through it station by station, and show which station would have caught it. Teams resist abstract checklists; they will not resist a checklist that explains last week's outage.
Where should the canonical schema live?
In the same monorepo as the consumer, not the producer, if you have to pick one. Consumers feel schema breakage first; if they own the file, they notice a stale copy instantly. Treat it as an interface definition language, and apply the same review discipline as a public API.
What if the producer and consumer disagree on what a field means?
That is not a checklist failure; that is an ownership ambiguity. Resolve it by writing a one-paragraph field definition next to each entry in the schema, reviewed and signed off by both teams. Untyped schemas let this argument smolder for years.
Can we automate this checklist entirely?
Partial automation is realistic and worth pursuing. Stations 1, 2, and most of 3 can run in CI or in-process. Station 4 — the cross-team diff review — is the one that genuinely needs a human, because the failure mode is "two teams mean different things by the same word." Station 5 is sample-based by design and benefits from a human picking the samples deliberately. Treat automation as a force multiplier, not a replacement for the human stations.
This article was drafted with AI assistance and reviewed for technical accuracy before publishing.
Top comments (0)