dkduckkit.dev

API Breaking Change Checker

Paste two JSON Schemas and instantly see which changes are breaking, which are safe, and why. No signup, no CLI.

Based on Semantic Versioning 2.0 and JSON Schema. Structural comparison only; $ref is not resolved.

Last updated: March 2026

TL;DR

Structural diff for two JSON Schema objects: removals, required/optional shifts, enum edits, format and validation bounds, nullable, oneOf/anyOf counts, and additionalProperties — with request vs response context so request body diffs are not misclassified.

Formula: Recursive property walk + keyword compares; breaking if consumers lose data, face stricter validation, or (in request context) must send new required fields.

When to use this

  • Reviewing API pull requests when only schema fragments are pasted from OpenAPI.
  • Sanity-checking whether a proposed response or request body change needs a major SemVer bump.
Schema context
Removed response fields break existing clients
Old schema (current version)
removed added modified
1 {
2 "type": "object",
3 "properties": {
4 "id": {
5 "type": "string",
6 "description": "User ID"
7 },
8- "name": {
9 "type": "string",
10 "description": "Display name"
11 },
12~ "email": {
13 "type": "string",
14 "description": "Email address"
15 },
16~ "role": {
17 "type": "string",
18 "enum": [
19 "admin",
20 "user",
21 "guest"
22 ]
23 }
24 },
25 "required": [
26 "id",
27 "name"
28 ]
29 }
New schema (proposed changes)
removed added modified
1 {
2 "type": "object",
3 "properties": {
4 "id": {
5 "type": "string",
6 "description": "User ID"
7 },
8+ "fullName": {
9 "type": "string",
10 "description": "Full display name"
11 },
12~ "email": {
13 "type": "string",
14 "description": "Email address"
15 },
16~ "role": {
17 "type": "string",
18 "enum": [
19 "admin",
20 "user"
21 ]
22 },
23+ "createdAt": {
24 "type": "string",
25 "format": "date-time"
26 }
27 },
28 "required": [
29 "id",
30 "fullName",
31 "email"
32 ]
33 }
Major bump required5 changes detected

3Breaking changes

name

Field 'name' removed — clients that read or depend on this field will break

Major version bump required. Deprecate with Sunset header before removing.

!
email

Field 'email' is now required — existing requests that omit this field will receive validation errors

Major version bump required. This is a common mistake — adding required fields always breaks existing clients.

role

Enum value 'guest' removed from 'role' — clients that send or expect this value will break

Major version bump required.

2Non-breaking changes

+
fullName

Field 'fullName' added — existing clients that ignore unknown fields are unaffected

Minor version bump. Verify clients use lenient JSON parsing (most do).

+
createdAt

Field 'createdAt' added — existing clients that ignore unknown fields are unaffected

Minor version bump. Verify clients use lenient JSON parsing (most do).

What is a breaking change?

From a consumer's perspective, a breaking change

Breaking change (API)
Modification causing existing clients to fail or require updates.
Read more →
is anything that makes an existing integration fail: missing fields they read, validation that rejects payloads they used to send, or types they can no longer parse. This tool labels common JSON Schema edits so you can align with SemVer
Semantic Versioning (SemVer)
MAJOR.MINOR.PATCH scheme communicating compatibility changes.
Read more →
before you ship.

The optional-to-required trap

Marking a field as required when it was optional is one of the most frequent accidental majors: old clients stop sending it, and the server returns 400. Treat that as breaking in both request and response-oriented reviews unless you have a coordinated rollout.

Enum value removal

Removing an enum literal breaks any client that still emits or branches on that value. Adding literals is usually safe for wire format, but exhaustive switch statements in typed code may need updates — the tool calls that out in recommendations.

Request vs response context

The same structural diff can mean different compatibility: dropping a key from a response often breaks readers, while dropping it from a request body usually means the server simply ignores an extra field old clients still send. Conversely, new required request fields are breaking because legacy clients do not send them. Toggle the context control above to match the schema you pasted.

Once you know whether a change is breaking, use our API Versioning Decision Helper to choose the right SemVer bump and communicate it in changelogs.

See also: Breaking change (API)

Breaking change (API)
Modification causing existing clients to fail or require updates.
Read more →
in the glossary.

Frequently asked questions

What counts as a breaking change in a REST API?
A breaking change is any modification that causes existing clients to fail without code updates. Common breaking changes: removing a response field (clients reading it get undefined), changing a field's type (string → number breaks parsers), adding a required request field (existing requests without it fail validation), removing an enum value (clients may send it), changing error codes (clients pattern-matching on them break).
Is adding a new field to a response breaking?
Usually no — most JSON parsers silently ignore unknown fields. However, strictly-typed clients generated from schemas (OpenAPI, gRPC) may throw on unknown fields if they use strict deserialization mode. For public APIs, assume adding optional response fields is safe, but document it as a minor version bump and advise consumers to test with strict parsing disabled.
Does the breaking change classification differ for request vs response schemas?
Yes. For response schemas: removing a field is breaking (clients read it), adding a field is safe. For request schemas: removing a field is safe (server stops reading it, old clients still send it without errors), but adding a required field is breaking (old clients don't send it, server rejects them). This asymmetry is the most common source of incorrect breaking change assessments.
How does the oneOf/anyOf change affect API consumers?
In response schemas, adding a new variant to oneOf is breaking — clients using exhaustive pattern matching (switch/case on a discriminator) will fail on the unknown variant. Removing a variant is always breaking. In request schemas, adding a variant is safe (server becomes more permissive), but removing one is breaking (clients may send the removed variant).
What is the safest way to evolve an API without breaking clients?
Follow additive-only changes: add optional fields, add new endpoints, relax validation. Never remove fields without a deprecation period. Use the Sunset header to signal retirement timelines. Version your API (v1, v2) when breaking changes are unavoidable. Run consumer-driven contract tests (Pact) to verify no consumer depends on the fields you're removing.

Related tools