Breaking Changes
title: "Breaking Changes — What Constitutes a Breaking API Change" description: "Breaking API changes include removing fields, changing types, making optional fields required, modifying endpoint behavior, or altering authentication requirements." date: 2026-06-28 lastmod: 2026-06-28 weight: 20 tags: [apis, versioning] }
Breaking changes in APIs include removed fields, changed types, stricter validation, modified behavior, and altered auth requirements that force client modifications.
What You'll Learn
- Types of breaking changes
- Detecting breaking changes
- Mitigating breaking changes
Why It Matters
Understanding what breaks clients helps you avoid accidental breakage and plan major versions properly.
Breaking Change Categories
flowchart TD
subgraph Breaking
RF[Removed Fields]
CT[Changed Types]
OR[Optional to Required]
BE[Behavior Changes]
AE[Auth Changes]
RE[Renamed Endpoints]
end
Code Examples
# Breaking changes to avoid
# 1. Removing a field (BREAKING)
# v1: {"id": 1, "name": "Alice", "email": "a@b.com"}
# v2: {"id": 1, "name": "Alice"} # email removed - BREAKING
# 2. Changing a field type (BREAKING)
# v1: {"id": "123"} # string
# v2: {"id": 123} # number - BREAKING (clients expect string)
# 3. Making optional field required (BREAKING)
# v1: POST /users { "name": "Alice" } # email optional
# v2: POST /users { "name": "Alice", "email": "a@b.com" } # email required - BREAKING
# 4. Changing endpoint behavior (BREAKING)
# v1: GET /users returns all users
# v2: GET /users returns only active users - BREAKING
# 5. Changing auth requirements (BREAKING)
# v1: GET /public/data (no auth needed)
# v2: GET /public/data (auth required) - BREAKING
# Breaking change detector
def detect_breaking_changes(old_spec, new_spec):
breaking = []
# Check removed endpoints
old_endpoints = {e['path'] for e in old_spec['endpoints']}
new_endpoints = {e['path'] for e in new_spec['endpoints']}
removed = old_endpoints - new_endpoints
if removed:
breaking.append(f"Removed endpoints: {removed}")
# Check removed response fields
for ep in new_spec['endpoints']:
old_resp = old_spec['responses'].get(ep)
new_resp = new_spec['responses'].get(ep)
if old_resp and new_resp:
removed_fields = set(old_resp.keys()) - set(new_resp.keys())
if removed_fields:
breaking.append(f"{ep}: removed fields {removed_fields}")
return breaking
Common Mistakes
1. Assuming Clients Don't Use a Field
If it's in the response, someone depends on it. Deprecate first.
2. Silent Behavior Changes
Changing sorting, filtering, or pagination defaults breaks expectations.
3. Error Response Changes
Changing error codes, messages, or structure breaks error handling.
4. Rate Limit Changes
Drastically lowering rate limits breaks clients at scale.
5. Data Format Changes
Changing date formats, encoding, or pagination structure.
Practice Questions
- Is removing an optional field breaking?
- Is adding a required field to a POST request breaking?
- Is changing the error response format breaking?
- How do you mitigate breaking changes?
- What is the deprecation window?
Answers:
- Yes. Any removed field is breaking.
- Yes. Existing requests without the field will fail.
- Yes. Clients parse error responses programmatically.
- Deprecate first, document migration, support both versions.
- Minimum 6-12 months between deprecation announcement and removal.
Challenge: Audit your API for breaking changes. Create a migration guide for the next major version.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro