How to Handle API Breaking Changes Without Breaking Clients
How to Handle API Breaking Changes Without Breaking Clients
Your API will change. New features, bug fixes, security patches, and architecture evolution require API modifications. The challenge: making changes without breaking the applications that depend on your current API. Here's how companies like Stripe, GitHub, and Twilio evolve their APIs without causing outages.
What Is a Breaking Change?
A breaking change is any modification that causes existing, working client code to fail.
Breaking (requires client changes)
| Change | Why It Breaks |
|---|---|
| Remove a field from response | Clients parsing that field get errors |
| Rename a field | Same as removing |
| Change a field's type | "price": "49.99" → "price": 4999 |
| Remove an endpoint | Clients calling it get 404 |
| Add a required parameter | Existing requests without it fail |
| Change authentication method | Existing credentials stop working |
| Change error response format | Client error handling breaks |
| Change status code meaning | 200 → 201 for creation |
Non-Breaking (safe to deploy)
| Change | Why It's Safe |
|---|---|
| Add a new optional field to response | Clients ignore unknown fields |
| Add a new endpoint | Existing clients don't call it |
| Add an optional parameter | Existing requests work without it |
| Add a new enum value | Clients handle unknown values gracefully |
| Improve error messages | Machine-readable codes stay the same |
| Add a new HTTP method to existing endpoint | Existing calls still work |
Strategies for Safe Evolution
1. Additive-Only Changes
The safest strategy: only add, never remove or modify. New fields, new endpoints, new optional parameters. Existing clients continue working unchanged.
Rule: If your OpenAPI spec diff only shows additions, it's safe.
2. Deprecation Before Removal
Never remove a field or endpoint without warning. Follow this timeline:
- Announce deprecation — add
Deprecatedheader, update docs, notify via email/changelog - Migration period — 6-12 months minimum (Stripe uses 12 months)
- Usage monitoring — track which clients still use deprecated features
- Direct outreach — contact active users of deprecated features
- Remove — only after usage drops to near-zero
3. Sunset Header (RFC 8594)
Sunset: Sat, 08 Mar 2027 00:00:00 GMT
Deprecation: Sat, 08 Mar 2026 00:00:00 GMT
Link: <https://api.example.com/docs/migration>; rel="sunset"
Include in responses for deprecated endpoints. Automated tools can detect and alert on these headers.
4. Response Field Deprecation
Mark fields as deprecated in your response without removing them:
{
"name": "John",
"email": "john@example.com",
"username": "john_doe",
"_deprecated_fields": ["username"]
}
Or use your OpenAPI spec to mark fields as deprecated, which shows in generated documentation and SDKs.
5. Stripe's Approach: API Version Pinning
Stripe pins each account to the API version it first used. New accounts get the latest version. Existing accounts stay on their version until they explicitly upgrade.
Stripe-Version: 2024-12-18
How it works:
- Each API version has a fixed response format
- Breaking changes create a new version
- Account is pinned to a version
- Dashboard shows available upgrades with changelogs
- Client can override version per-request for testing
This is the gold standard but requires maintaining compatibility layers for every version.
6. Feature Flags
Instead of versioning the entire API, toggle individual features:
X-Feature: new-pricing-model
Clients opt in to new behavior on a per-feature basis. Less overhead than full API versioning.
Communication Patterns
Changelog
Maintain a dated changelog of all API changes:
## 2026-03-08
### Added
- `order.metadata` field in order responses
- `GET /api/v1/orders/search` endpoint
### Deprecated
- `order.notes` field (use `order.metadata` instead, removal: 2027-03-08)
### Fixed
- `order.total` now correctly includes tax for EU orders
Migration Guides
For every breaking change, provide a migration guide:
- What changed and why
- Before/after code examples
- Step-by-step migration instructions
- Timeline (when old behavior stops working)
- Support contact for questions
SDK Updates
Release SDK updates that handle the migration. Ideally, updating the SDK version is all clients need to do.
Monitoring Deprecation Usage
Track which clients use deprecated features:
SELECT api_key, endpoint, count(*)
FROM api_logs
WHERE endpoint IN (deprecated_endpoints)
AND timestamp > NOW() - INTERVAL '30 days'
GROUP BY api_key, endpoint
ORDER BY count DESC;
Proactively reach out to clients still using deprecated features before removal.
Managing API evolution? Explore API versioning tools and best practices on APIScout — comparisons, guides, and developer resources.