API workflows
How to compare two JSON API responses
A reliable API comparison should show the exact data path, classify each change, and separate structural compatibility issues from ordinary value changes.
Document summary
Normalize both responses, decide how arrays should be compared, classify differences by path, and review structural changes before changing values such as identifiers or timestamps.
Key takeaways
- Removed properties and changed data types are more likely to break clients than ordinary value updates.
- Array order may be meaningful, irrelevant, or based on an identifier. Choose the comparison rule deliberately.
- Use representative samples and a schema when optional fields or multiple response shapes exist.
Prepare both responses before comparison
Validate both JSON documents before comparing them. A syntax error can hide the true structure and produce misleading differences.
Formatting is useful for manual reading, but a structural diff should compare parsed values rather than line positions.
- 1
Remove transport wrappers that are not part of the payload.
- 2
Decide whether to ignore volatile fields such as request IDs or timestamps.
- 3
Confirm that both samples represent the same endpoint and scenario.
- 4
Keep the original responses for later verification.
Classify changes by their effect
Grouping every difference into one list makes important changes easy to miss. Separate added, removed, type changed, and value changed paths.
| Change type | Example | Typical risk |
|---|---|---|
| Added | profile.timezone appears | Usually compatible, but strict clients may reject unknown fields. |
| Removed | user.email disappears | Can break clients that require the field. |
| Type changed | id changes from number to string | High risk for validation and generated models. |
| Value changed | status changes from pending to active | Often expected, but important for business logic. |
Use exact paths instead of line numbers
Line numbers change when JSON is formatted. Paths such as user.profile.name or items[2].price identify the real location of a difference and remain useful across formatting styles.
Choose the correct array comparison strategy
Arrays are the most common source of noisy diffs. A reordered list can look completely different even when it contains the same records.
- Compare by position when order is part of the contract.
- Compare by a stable identifier when order can change.
- Compare as a set only when duplicates and order are not meaningful.
- Review nested arrays separately when records contain their own collections.
Example of a breaking response change
The version on the right removes a field, changes the identifier type, and adds a new region. A structural diff should identify each path separately.
{
"id": 42,
"email": "ada@example.com",
"active": true
}{
"id": "42",
"active": true,
"region": "us"
}Reduce noise from volatile values
Request IDs, timestamps, signatures, and generated links may change on every request. Mark or ignore those paths so they do not hide meaningful differences.
Use a schema for compatibility checks
A sample diff shows what changed between two examples. A JSON Schema can show whether the new response still satisfies the expected contract across many possible values.
- Validate required fields.
- Check data types and allowed values.
- Review nullability changes.
- Confirm additional property rules.
- Test more than one representative response.
Review changes before release
Treat removed fields, renamed paths, narrower allowed values, and changed types as potential breaking changes. Document them and test the affected clients before deployment.
- 1
Create a clean before and after diff.
- 2
Mark expected and unexpected changes.
- 3
Validate the new response against the contract.
- 4
Update generated types and tests.
- 5
Publish migration notes when clients must change.