API Contract Change Checklist
The conversation explains how to modify a public JSON API without disrupting existing clients, emphasizing the importance of preserving field names, types, presence, and JSON shape. It provides a step-by-step compatibility checklist, exampl
A read-only, creator-approved conversation screened before publication.
Explain how to change a public JSON API response without breaking existing clients. Give a step-by-step compatibility checklist, an example of a safe additive change, an example of a breaking change, and a concise rollout plan.
HOW TO CHANGE A PUBLIC JSON API WITHOUT BREAKING CLIENTS Core principle: consumers depend on (a) field names, (b) field types, (c) field presence, and (d) the JSON shape (object vs array). A change is safe only if it preserves all four for every existing client. Everything else must be versioned or rolled out in stages. STEP-BY-STEP COMPATIBILITY CHECKLIST 1. Inventory the contract - List every endpoint, field, type, and optionality. Freeze it as the "v1 contract." - Note which fields clients might rely on implicitly (e.g. a missing field they treat as null, a field they re-serialize). 2. Classify the change - Additive: new field, new enum value, new endpoint, wider accepted input. Usually safe. - Modifying: rename, retype, remove, reorder (arrays), change null semantics. Breaking. - Ask: "Does any existing client break if this field disappears, changes type, or changes meaning?" 3. Never remove or rename — deprecate instead - Keep the old field, add the new one alongside it, and document the old one as deprecated. - Only remove after a deprecation window (measure actual traffic, not calendar time). 4. Keep types stable - Don't change a number to a string, null to 0, or an object to an array. Type coercion in clients will silently corrupt data. - If you must change a type, ship a new field with a new name (e.g. price -> price_cents as int) and keep the old one. 5. Preserve field presence semantics - Adding a field is safe; changing whether a field appears at all (conditional vs always) is not. Clients that do `if ("x" in obj)` will behave differently. 6. Guard the JSON shape - Don't change a response from an object to an array, or nest/un-nest fields. Shape changes break every parser. 7. Handle enum/value additions carefully - Adding a new enum value is usually safe (clients should have a default branch). Changing the meaning of an existing value is breaking. 8. Add explicit versioning for anything risky - URL versioning (/v1/, /v2/), Accept header versioning, or a version field in the body. Keep old versions alive. 9. Test against real clients - Run contract tests (OpenAPI/Swagger diff, JSON Schema validation) and replay recorded production traffic against the new response to catch drift. 10. Document and communicate - Changelog, deprecation notices, migration guide, and a clear "supported until" date. EXAMPLE OF A SAFE ADDITIVE CHANGE Old response: { "id": 42, "name": "Widget", "price": 9.99 } New response: { "id": 42, "name": "Widget", "price": 9.99, "price_cents": 999, "in_stock": true } Why it's safe: existing fields keep name, type, and presence. New fields are additional keys; old clients ignore them, new clients use them. No existing parser breaks. EXAMPLE OF A BREAKING CHANGE Old response: { "id": 42, "name": "Widget", "price": 9.99 } Breaking change: { "id": 42, "title": "Widget", "price": "9.99", "currency": "USD" } Why it breaks: "name" was renamed to "title" (clients reading response.name now get undefined), and price changed from a number to a string (arithmetic, JSON.parse, and strict type checks all fail). This must never ship as an in-place change — only as a new version. CONCISE ROLLOUT PLAN 1. Additive first: ship new fields alongside old ones (no removal, no renames). Monitor error rates for 2-4 weeks. 2. Deprecate: mark old fields/versions deprecated in docs and responses (e.g. a "deprecated": true flag or a Warning header). Track actual usage per client. 3. Cutover: once deprecated traffic drops below your threshold (e.g. <1% or a set date), release the new version (v2) with the clean contract. 4. Parallel run: run v1 and v2 simultaneously; route new clients to v2, keep v1 for stragglers. 5. Sunset: announce a hard date, then remove v1. Keep a frozen snapshot or a migration shim if long-tail clients exist. 6. Verify: after each step, compare error rates and response-size/parse metrics against the pre-change baseline. Golden rule: additive changes can ship anytime; anything that renames, removes, retypes, or reshapes belongs in a new version with a deprecation window and a measured cutover.
RELATED SIGNALS
Systematic Editing Pass for Clearer, More Forceful Writing
The conversation provided a systematic editing pass for refining a rough draft into a clearer, more forceful version without altering its me
READ TRANSMISSION →
Sunk Cost Fallacy and Escalation of Commitment: Historical Examples and Decision
The response explains the sunk cost fallacy and escalation of commitment using the Concorde and Motorola Iridium projects as examples, and p
READ TRANSMISSION →
Decision Matrix for Project Management Approaches: A Worked Example
The conversation provides a step-by-step guide to creating a decision matrix for comparing project management approaches, using a worked exa
READ TRANSMISSION →