The API deprecation policy decision record: why the deprecation model you chose determines your backward compatibility surface and your client migration coordination overhead
API deprecation policies are not communication tasks that engineering teams schedule after a breaking change is already planned. They are a set of founding decisions about which change types cross the backward compatibility boundary, how much lead time each crossing requires, what migration support the organization is obligated to provide, and how the retirement phase is enforced rather than indefinitely deferred — decisions that have structural consequences invisible in sprint velocity and API uptime metrics until an enterprise client's production system fails silently on an endpoint the engineering team retired without classifying it as a breaking change, or the team discovers it has been maintaining seven versions of an API for three years because no sunset enforcement mechanism converts the documented retirement phase into an actual endpoint shutdown.
A 14-person developer tools company building a static analysis API had been moving fast for two years. The API had been designed for startup clients who could absorb changes without much friction. When a decision needed to be made about endpoint design, the team made it in a Slack thread, implemented it, and shipped it — often changing request and response shapes, renaming endpoints, or removing obsolete methods within the same API version without announcing the changes through any channel other than updated documentation. This worked because their early clients were technical founders who monitored the changelog and adapted quickly. In the third year the company signed an enterprise client: a financial services firm running 3,000 CI/CD jobs per day that consumed the analysis API to gate code quality checks before every merge. The enterprise client had integrated the API carefully, based on the documentation at the time of contract signing. Eight months into the contract, the engineering team removed an endpoint that generated a specific category of code smell report — the endpoint had low usage in the startup client base and the team had replaced its functionality with a redesigned endpoint three months earlier. The old endpoint returned 404. The enterprise client's CI/CD pipeline began failing in the pre-merge quality gate for every repository in their engineering organization simultaneously. Three thousand jobs failed within four hours. The failure surfaced at 2 AM on a Tuesday and required four engineering-days to diagnose, communicate, and remediate — two to identify the 404 as a platform change rather than a client configuration issue, one to draft and distribute the migration path, and one to support the client's engineers migrating their 47 pipeline configurations to the replacement endpoint. No deprecation notice had been issued because the company had no deprecation policy. The endpoint had been in the documentation as active; the team removed it because it was a reasonable engineering decision; the client had no mechanism to anticipate the change or receive notice of it because neither existed.
The cost of the incident was not primarily the four engineering-days — it was the client trust failure that produced a contract review and a six-month period of uncertainty about whether the enterprise relationship would continue. The engineering team's response was to commit to a deprecation policy, which they drafted in the week following the incident. The policy read: "We will give 30 days notice before removing an endpoint or changing required fields." The 30-day policy was an improvement over no policy. It produced a different failure two quarters later. A junior engineer changed the response format of a frequently-called endpoint — not removing a field, but changing a date field from ISO 8601 format to Unix timestamp — on the grounds that the change was a format improvement, not a field removal, and the policy specified notice requirements only for endpoint removal and required field changes. The same enterprise client parsed the date field to populate a downstream audit log. The format change was not caught in the client's test suite because the suite was checking for field presence, not field format. The production failure was silent: the downstream audit log began receiving malformed date records and the corruption ran for three weeks before a quarterly audit caught it. The deprecation policy existed. It covered endpoint removal and required field changes. It did not cover field type changes, response format changes, error code changes, or semantic changes to field values — the four categories where the classification gap between "additive change" and "breaking change" is most commonly contested by the engineers who make the change. Connect this to the production incident severity framework decision record: a severity framework designed around service availability signals will not classify the date format change as a P1 or P0 because the service is fully available, requests are returning 200, and no error rate has increased; the failure mode is data correctness, a criterion class absent from availability-first severity frameworks; the API deprecation policy and the incident severity framework are interdependent because the deprecation policy specifies which changes require notice, and the severity framework must include a data correctness criterion class to surface the failures that occur when a change the deprecation policy classified as non-breaking produces a behavioral difference a client was depending on; if the severity framework has no data correctness criterion class, data corruption caused by an unclassified breaking change will not trigger the P1 response the customer impact warrants.
A 32-person API-first company building a payments integration platform had a deprecation policy drafted by the CTO in the company's second year and updated twice since. The policy specified a 3-month minimum notice period before any breaking change, defined a breaking change as "any change that removes or renames a field, removes an endpoint, or changes required request parameters," required a migration guide for every breaking change, and specified a Deprecation response header in API responses for deprecated endpoints. The policy was well-written, consistently referenced in engineering planning sessions, and served as the basis for client contract language specifying the company's compatibility obligations. The engineering team believed it was operating a stable, well-governed API. In the fourth year, the platform team shipped a change to the payment intent creation endpoint: they added a new required field, `idempotency_scope`, that clients must include in the request body to specify the deduplication scope for payment retry logic. The field had been optional in a two-month beta with zero beta testers choosing to include it. The platform team classified the field addition as non-breaking under the policy's definition — it was a new field, not a removed or renamed field — and shipped it without triggering the 3-month notice period. Eight enterprise clients began experiencing SDK failures within 36 hours of the production deploy. The clients' SDK integrations, which constructed payment intent requests from validated request objects, were now missing a required field in every request. The SDKs returned validation errors. The clients' payment flows stopped processing. The 3-month notice period had not been triggered because the change was classified as additive. The clients had received no notice because the policy's breaking change definition did not enumerate required field additions as breaking. The classification was technically consistent with the policy's written definition and operationally wrong for every client who had a working integration the day before the deploy.
The remediation required rolling back the required field to optional, a six-week stabilization period while the platform team rearchitected the idempotency mechanism to avoid requiring a new client-supplied field, and a policy revision that extended the breaking change definition to include required field additions, field type changes, error code changes, and semantic changes to enumerated field values. The policy revision identified the classification gap as the root cause — not the individual engineer's classification decision, which was correct given the policy as written, but the policy's definition, which had been drafted before the company had enterprise clients with complex SDK integrations and had not been revised to cover the change types that break SDK-based integrations without removing a field or endpoint. The gap between the engineering team's intuitive definition of breaking change ("something that removes an existing feature") and the client's operational definition ("something that requires my integration to be changed to continue working") is the most common source of unplanned migration coordination overhead in API-first companies because both definitions are consistent with legitimate engineering reasoning and neither is sufficient to govern an API used by clients with complex, production-critical integrations. The only definition that serves the client relationship is the operational one: if a correctly-implemented client must change its code to continue functioning, the change is breaking regardless of whether the API gained or lost surface area. Connect this to the engineering team communication channel decision record: the breaking change classification decision requires cross-functional context that a single-team channel review cannot provide; the channel structure must include a defined routing rule for API changes touching the taxonomy's contested boundary classes, with the SDK team, customer success, and enterprise account managers as required audience for the classification judgment; a platform team that classifies a required field addition as non-breaking without routing it to a review venue where the SDK team can flag that the change will break all SDK integrations making requests without the new field is making a cross-functional judgment with single-team information; the channel structure is the mechanism that converts the breaking change taxonomy from a set of rules applied by individual engineers into a cross-team review process where boundary-class changes receive the scrutiny their client impact warrants.
A 56-person B2B SaaS building a data warehouse integration platform for enterprise analytics teams had an API deprecation policy that was comprehensive, documented, and consistently referenced in engineering planning. The policy specified a 6-month notice period for endpoint removal, a 3-month notice period for breaking field changes, a migration guide requirement for every breaking change, a client health check API that allowed clients to query whether any of their active integrations were using deprecated endpoints, a Deprecation-Date response header on deprecated endpoints, a Sunset response header with the ISO 8601 retirement date, and a client notification workflow that sent email to API key owners when their key was detected making calls to a deprecated endpoint. The policy was the product of three years of iteration following two client-facing breaking change incidents and a consulting engagement that reviewed the policy against industry standards. The policy was well-designed. Its failure mode was not in its specification but in its enforcement: the retirement phase existed in documentation but not in practice. In three years under the policy, 12 endpoints had been deprecated with full compliance to the 6-month notice period. Zero had been retired. In each case, when the sunset date approached, one or more enterprise clients surfaced a blocking objection — a migration in progress, a regulatory audit requiring API call auditability during the transition period, a platform freeze preventing client-side changes — and the sunset date was extended. The pattern repeated. Extensions were granted. Endpoints accumulated in "deprecated but active" status. By the end of year three, the team was maintaining API versions v1 through v7 simultaneously, with 31 endpoints carrying active deprecation notices that had been extended at least once.
The active API surface required testing coverage for every release, monitoring for anomalous usage patterns across all versions, security review coverage for authentication edge cases in each version, and on-call runbook entries for incident response across the full version set. A security vulnerability in the authentication token parsing layer was discovered in a penetration test. Patching it required modifying the authentication logic in all seven active versions because the seven versions shared a common authentication layer that had diverged in implementation across versions due to three years of per-version patches accumulated after the initial architecture. The remediation consumed 11 engineering-days: three to identify the vulnerability's scope across all versions, five to patch and test each version's authentication layer independently, two to coordinate the release sequencing across seven versions, and one to produce the documentation required for the security audit. The same vulnerability in a single-version API surface would have required three engineering-days. The additional eight days were the direct cost of the accumulated backward compatibility surface — seven active versions instead of one, each maintained because no sunset enforcement mechanism had converted the documented retirement dates into actual endpoint shutdowns. The enforcement failure produced no detectable signal in any routine metric before the security incident: the deprecated endpoints were working correctly, client integrations were stable, account relationships were positive, uptime was 99.97%. The version accumulation was invisible until a cross-cutting change required touching all active versions simultaneously and the accumulated count converted a routine security patch into a multi-week remediation. Connect this to the on-call alert threshold calibration decision record: the on-call alert thresholds for deprecated endpoints can make the accumulation cost visible before a security incident forces it; a deprecated endpoint with stable or growing call volume during the deprecation window is an endpoint whose clients have not started migrating and whose retirement date will produce client escalations if enforced; usage-volume alerts on deprecated endpoints convert the "sunset will produce a client escalation" problem from a surprise at the retirement date to a visible signal during the notice period that specific clients need proactive migration support engagement rather than a reactive escalation when the enforcement date arrives; the deprecation policy and the alert threshold calibration must be designed together because monitoring is the mechanism that makes client migration progress visible during the deprecation period, and without that signal the engineering team's only indication that a client has not migrated is the escalation at the retirement date.
Structural properties set by the API deprecation policy decision
Two structural properties are determined by the founding decisions about breaking change taxonomy, required notice periods, migration support requirements, and sunset enforcement mechanisms. Neither is visible in API uptime, error rates, or sprint velocity metrics until a client-facing incident surfaces the classification gap that produced an unplanned breaking change, or a cross-cutting infrastructure change reveals the maintenance overhead accumulated across the version surface while each individual deprecated endpoint remained stable and unremarkable.
Property 1: Backward compatibility surface and the version accumulation pattern. The backward compatibility surface is the total API surface area the organization must maintain simultaneously — not the count of version identifiers in URL paths but the count of distinct behavioral contracts that must be honored in responses, tested in CI pipelines, considered in security reviews, and covered in on-call runbooks. The surface accumulates through two distinct mechanisms. The first is classification failures: changes that cross the backward compatibility boundary ship without triggering the notice period because the breaking change taxonomy did not enumerate them or the engineer applying the taxonomy classified them incorrectly. A classification failure produces a new behavioral contract without a deprecation timeline; the old behavior, which the client was depending on, is absent from the new endpoint and present only in clients' cached assumptions; the next time the client calls the endpoint expecting old behavior, they receive unexpected new behavior; the remediation typically requires either reverting the change or creating a compatibility shim that serves old behavior to clients who have not migrated, which is a retroactive deprecation without a notice period or migration guide. The second mechanism is sunset deferral: changes that correctly trigger the notice period and receive migration guides but whose retirement dates are repeatedly extended produce deprecated-but-active endpoints with no defined retirement; each extension is individually reasonable — a specific client's legitimate constraint is accommodated — and collectively produces a portfolio of endpoints that accumulate past their designed lifecycle because no single extension is large enough to trigger a policy review. The backward compatibility surface accumulation is invisible at the individual endpoint level, visible only at the portfolio level, and has no detection path without a mechanism that measures the portfolio — which is exactly what the 56-person company lacked; its per-extension decisions were all locally reasonable and their aggregate was an 11-engineering-day security remediation. The surface should be the output of a deliberate policy rather than the residue of enforcement failures and classification gaps: an organization that knows its active surface area, knows which portions are in active deprecation with firm retirement dates, and knows which clients are using each portion has a surface that is managed; an organization that discovers the extent of its surface area when a security incident requires patching all active versions simultaneously has a surface that is accumulated. Connect this to the production incident severity framework decision record: the severity framework should include an explicit criterion class for backward compatibility surface incidents — incidents that require patching, updating, or remediating an API change across multiple active versions simultaneously; this class does not fit availability-based severity taxonomies because all versions are available and responding correctly, but it has a distinct response resource profile: more engineers, longer coordination windows, more complex release sequencing, and a customer communication format that differs from availability incidents (the service is working; the patch affects all versions; clients do not need to take action but will experience a maintenance window); without this criterion class in the severity framework, multi-version security incidents are triaged at a severity level that triggers insufficient response resources, and the patch timeline extends past what a security vulnerability warrants.
Property 2: Client migration coordination overhead and the classification gap. The client migration coordination overhead is the engineering, customer success, and account management time required to guide external clients through each API change. It is determined primarily by three factors. The first is whether the organization has defined what counts as a breaking change. A shared, written definition creates the vocabulary that allows clients to triage incoming API changes reliably and determines whether changes that require client action are announced in advance or discovered at production failure time. A client whose vendor makes a required field addition without triggering the notice period discovers the change as a validation error in production rather than as a deprecation notice with a migration guide; the migration coordination overhead is an incident response rather than a planned migration, and the customer success and account management overhead of an incident response is five to ten times the overhead of a planned migration with the same technical complexity. The second factor is the lead time provided. A notice period too short for the client's release cycle produces a client who received notice but could not complete the migration before the retirement date, generating the same sunset deferral dynamic as no notice at all. The notice period must be calibrated against the 90th percentile release cycle in the client base, not the median, because enterprise clients with the longest release cycles are typically the clients with the most complex integrations and the highest account value, and a notice period adequate for the median client but inadequate for the enterprise tail generates the highest-stakes escalations at retirement time. The third factor is the quality of migration support. A migration guide that documents the new endpoint behavior but does not include code samples for common migration patterns, does not address the edge cases specific enterprise integrations depend on, and does not include a compatibility testing procedure for clients to validate their migration before redirecting production traffic produces nearly as much migration coordination overhead as no migration guide, because the client's engineers must reverse-engineer the migration path rather than executing a prepared procedure, and the edge cases the guide did not address surface as support tickets during the migration period. Connect this to the engineering team meeting cadence decision record: the breaking change classification decision is a cross-team judgment that requires the platform team's technical context, the SDK team's client integration context, and the customer success team's account relationship context; a meeting cadence that has no standing cross-team review slot for API changes touching the taxonomy's contested boundary classes routes the classification decision to individual engineers in Slack threads where cross-functional input is absent; the cadence must include a recurring architectural review slot that fires before any change the platform team has flagged as potentially breaking, with required quorum including the SDK team lead, customer success lead, and enterprise account manager for affected clients; a breaking change classification made without cross-functional quorum has a high rate of contested-boundary errors, and contested-boundary errors are the category that produces production incidents at client sites without triggering the notice period the policy was designed to prevent.
The API deprecation policy ADR: five sections
Section 1: Breaking change taxonomy and version boundary definitions. The breaking change taxonomy is the foundational section of the deprecation policy because every other section — notice periods, migration guides, sunset timelines — is undefined in scope without it: the notice period applies to breaking changes, but nothing in the policy specifies which changes are breaking. The taxonomy must be derived from the client's perspective rather than the engineering team's: a breaking change is any modification to the API's behavior that can cause a correctly-implemented client, using the API as documented at the time of the modification, to receive an error, produce incorrect output, or require a code change to continue functioning. This definition produces seven enumerable change classes that are unambiguously breaking: (1) endpoint removal — any endpoint that exists in the current API surface and is removed or returns a non-2xx status for previously valid requests; (2) endpoint path or method change — an endpoint previously accessible at a specific path and method that changes either the path or the method; (3) required request field removal or promotion — any field removed from the required set, absent from new request validation, renamed, or added to the required set from optional or from non-existence; (4) response field removal or rename — any field in the response that clients may be parsing, removed or renamed in the new response format; (5) response field type change — any field whose type changes (string to number, number to string, string to enum, nullable to non-nullable, non-nullable to nullable, ISO 8601 date to Unix timestamp); (6) semantic change to enumerated field values — any field whose values change meaning without changing structure (status field changing from 'active' to 'enabled', ID field changing from integer to UUID); (7) error code or error format change — any change to the HTTP status codes returned, the error response body structure, or the error message format that clients may be parsing for programmatic error handling. The taxonomy must also enumerate non-breaking change classes: adding a new optional request field with defined default behavior for clients that omit it; adding a new response field that clients are not required to parse; adding a new endpoint; relaxing a request field constraint; extending an enum with new values that clients are not required to handle exhaustively. The version boundary definition specifies when a URL version bump is required versus when a within-version change with a notice period is sufficient: a URL version is required when old and new behaviors must be simultaneously available for different client segments for a period longer than the standard migration window for the change class, typically when client segments are on different contractual commitments or when the migration complexity means not all clients can complete it within the standard field-change notice period; within-version changes with notice periods are sufficient for changes that all clients can migrate to within the standard notice period without requiring old and new behaviors simultaneously in production. Connect this to the engineering team communication channel decision record: the taxonomy is only as useful as the review mechanism that applies it; a taxonomy applied by individual engineers without cross-functional review will be misapplied on the contested boundary classes — required field additions, semantic value changes, and type changes — because those are precisely the classes where the engineering team's intuition most reliably diverges from the client's operational reality; the channel structure must route any change touching these boundary classes to a review venue with the SDK team and customer success as required audience, converting the classification from a single-team technical judgment into a cross-functional review that catches the contested-boundary errors before they reach production.
Section 2: Required notice periods and deprecation lead times by change class. A single notice period for all change classes produces a period calibrated to the easiest migration (typically too short for complex ones) or the hardest migration (typically too long for simple ones). The policy must specify minimum notice periods by change class, calibrated against the 90th percentile enterprise client's release cycle and migration complexity for each class. Endpoint removal: 6 months minimum; the migration requires identifying all usages of the endpoint across the client's integration, rerouting traffic to the replacement, validating behavioral equivalence for the edge cases the client depends on, and deploying through the client's release process; at a 90th-percentile quarterly release cadence, 6 months provides two release windows, the minimum for a discover-plan-implement-test-deploy cycle with a test window before the first production deployment. Required field additions: 4 months minimum; the migration requires adding the field to all request constructions, updating validation logic, and deploying; simpler than endpoint removal but may be distributed across multiple codebases and multiple teams at enterprise scale. Response field removals, renames, and type changes: 3 months minimum; the migration requires updating all parsing logic for the affected fields; complex downstream systems may require schema migrations to update stored field representations. Semantic field value changes: 3 months minimum; clients that switch on field values must update their switching logic; the migration may require both code changes and data migrations if the client is storing field values. The notice period clock starts at announcement, not at the start of engineering implementation. The policy must specify the required announcement format and distribution channels to make the clock start unambiguous and defensible in contract disputes: required channels include the Deprecation and Sunset response headers (so clients who monitor response headers discover the change automatically), direct email to all API key owners making active calls to the affected endpoint (ensuring the notice reaches clients who do not monitor the API changelog), and the public API changelog (providing the permanent audit record of the deprecation timeline). Notice period extensions are not new notices: when a retirement date is extended, the extension is communicated as an extension with a specific new date and a reason, not as a new deprecation with a new notice period, because re-issuing a deprecation notice for the same endpoint implies the original deprecation was retracted and trains clients to expect retraction rather than retirement on future deprecation notices. Connect this to the on-call alert threshold calibration decision record: the notice period clock starts at announcement but the engineering team's first signal that a specific enterprise client has not started migrating comes from monitoring, not from client communication; usage-volume alerts on deprecated endpoints should fire when the deprecated endpoint's call volume is not declining at the rate consistent with completing all active client migrations before the retirement date; these alerts provide the customer success team with a leading indicator for which clients need proactive migration support engagement rather than a reactive escalation when the retirement date arrives; calibrating the alert threshold against the expected migration decline curve — not a flat threshold — is the mechanism that makes the deprecation period's client migration progress visible during the period when engagement is still possible rather than at the enforcement date when it is too late.
Section 3: Migration support requirements per change class. The migration guide is the minimum migration support requirement for every breaking change. The minimum specification: (1) old behavior and new behavior expressed as request-response examples for the three most common call patterns the affected endpoint serves; (2) the migration path as numbered steps with code examples in the primary SDK languages the organization maintains, specifying the complete sequence from current integration state to post-migration state; (3) edge cases — specific behaviors of the old endpoint that are not equivalent in the new endpoint, with the specification of how the new endpoint handles those cases or why the new endpoint does not preserve them; (4) a compatibility testing procedure — the specific steps a client can execute to validate that their migration produces equivalent results for their integration before redirecting production traffic, including which test assertions map to which behavioral equivalences; (5) an escalation path — the support channel, response SLA, and contact format for clients who encounter migration blockers not addressed in the guide. Beyond the minimum, the migration support model should specify three supplementary options calibrated to migration complexity. Compatibility shim: for endpoint removal and required field additions, a temporary server-side shim that accepts old-format requests and translates them to new-format requests internally, allowing clients to continue sending old-format requests for a defined shim period without code changes while the new endpoint is in production; the shim period is distinct from the deprecation notice period and does not extend it — it is an additional migration tool that allows clients with complex integrations to redirect production traffic to the new endpoint before completing their code migration, reducing the risk of the final cutover; the shim itself has a sunset date and must be deprecated following the same policy. Migration day support: for endpoint removal and required field additions affecting enterprise clients, a defined format for requesting a migration engineering session where the organization's engineers pair with the client's engineers to execute the migration, specifically for enterprise clients whose integrations are complex enough that the migration guide leaves open edge cases specific to their implementation; converting the most complex migrations from isolated client work into a collaborative session eliminates the edge case blockers without requiring a support ticket queue. SDK migration release: for changes handled in the organization's maintained SDK libraries, a migration release that implements the new behavior and includes backward-compatible shim logic so clients can update the SDK version and receive the new behavior without modifying their integration code; the SDK migration release reduces the client migration to an SDK version bump for clients using the maintained SDKs, leaving only clients with custom integrations requiring the full migration procedure. Connect this to the engineering team meeting cadence decision record: migration support requirements announced in the deprecation notice are operational commitments that must appear in sprint backlogs and be tracked against completion; the meeting cadence must include a recurring deprecation review slot that fires quarterly to verify that each active deprecation's migration support deliverables are on schedule, that customer success has identified which clients need proactive outreach, and that the engineering team has completed or committed to the compatibility shims, migration engineering days, and SDK releases announced in the deprecation notice; a deprecation policy that produces migration support commitments but a meeting cadence with no review mechanism for those commitments produces migration guides that are incomplete at the retirement date and the same sunset deferral dynamic that produces the seven-active-versions backward compatibility surface — because the deferral happens when the retirement date arrives with incomplete migration support, not only when enterprise clients object on their own initiative.
Section 4: Sunset enforcement mechanism and client exceptions process. The sunset enforcement mechanism is the policy element most commonly absent from well-written deprecation policies because it is the element that requires the organization to say no to specific enterprise clients at a specific moment, and the social and commercial friction of that moment is higher than any engineering friction in the policy's other sections. Without an enforcement mechanism, the deprecation policy's retirement phase is a documented intention with no execution path, and the first retirement date the organization fails to enforce trains every client to treat all future retirement dates as suggestions. The enforcement mechanism must specify three elements: the technical action on the retirement date (options: return 410 Gone with a migration link in the response body; return 301 Moved Permanently to the replacement endpoint for a grace period before transitioning to 410; begin returning a mandatory warning header in 2xx responses in the 30 days before the retirement date so clients who monitor response headers receive a final prompt before the 410 fires); the notification timeline in the final 30 days (a 30-day warning, a 14-day warning, and a 7-day warning sent to all API key owners who are still making active calls to the endpoint, specifying that the endpoint will return 410 on the retirement date); and the response format for extension requests. The client exceptions process is the policy element that prevents the enforcement mechanism from converting legitimate enterprise migration constraints into relationship-damaging hard cutoffs. The exceptions process must specify: who has authority to grant an extension (the account management lead, not the engineering team — the engineering team's default is to extend because the extension eliminates an immediate escalation while deferring the maintenance cost to a future sprint; the account management lead is better positioned to evaluate whether the client's migration constraint is real and to negotiate a firm replacement date as a contract commitment); the conditions under which an extension will be granted (a documented migration in progress with a committed completion date; a regulatory or contractual constraint preventing client-side changes in the requested window; or a technical blocker in the migration guide that the organization's engineering team must resolve before the migration can complete); the maximum extension duration (90 days for a first extension; a second extension requires VP-level approval and a binding contract commitment with a specified completion date and a defined consequence for non-completion); and the documentation requirement (every extension documented with the client name, the original retirement date, the new retirement date, the reason for the extension, the conditions the client has committed to, and the account management owner responsible for tracking the commitment to completion). The first real enforcement — the first endpoint that is actually retired on its documented retirement date without exception — is the most important event in the policy's credibility lifecycle; the organization should select a low-stakes endpoint for its first real retirement, communicate the enforcement with unusual clarity in the run-up, and execute without exception; the precedent is cited in all subsequent deprecation notices as evidence that the dates are real and converts future notice periods from advisory communications into operational triggers for client migration planning. Connect this to the production incident severity framework decision record: the severity framework must specify how incidents triggered by the organization's own deprecation actions are classified; a client receiving 410 from a retired endpoint is experiencing an incident whose remediation is a client migration, not a service restoration — the severity framework must route these events to migration support rather than engineering incident response, specify the customer communication format that distinguishes a planned retirement from a service degradation, and define the response SLA for migration support escalations that arrive after the retirement date; without this specification in the severity framework, planned retirement events are triaged as availability incidents, the engineering team's incident response resources are consumed diagnosing a 410 that is correct by design, and the customer communication characterizes a policy enforcement as a service failure.
Section 5: Deprecation retrospective and API lifecycle review cadence. The deprecation policy must have a revision mechanism that fires before the classification gap, the sunset deferral pattern, or the migration support quality failure becomes large enough to produce a client incident or a backward compatibility surface problem requiring a multi-week remediation. The revision mechanism includes three components. Semi-annual breaking change audit: every six months, the engineering team reviews every API change shipped in the prior six months and classifies each change retroactively against the breaking change taxonomy; the purpose is not to identify changes that should have triggered the notice period and did not — the client impact has typically already occurred — but to identify patterns in the classification errors that indicate whether the problem is a training gap (engineers consistently misclassifying the same change type), a taxonomy gap (a change type the enumerated list does not cover clearly), or a process gap (a category of changes being routed to review without the cross-functional audience that catches boundary-class errors). The audit output is a structured list of classification corrections with a root cause annotation for each, and a set of proposed taxonomy revisions for any change types where the policy's enumeration was ambiguous. Quarterly active deprecation review: every quarter, the account management lead, customer success lead, and platform team lead review all active deprecations against three criteria — is each deprecation's retirement date still achievable given the current client migration status? which clients have not started migrating and need proactive migration support engagement before the retirement date? which deprecations have exceeded the maximum extension duration and require VP-level escalation to enforce or to negotiate a binding commitment with a firm end date? The quarterly review converts the sunset enforcement mechanism from a date-based trigger that fires regardless of migration readiness into a managed process where the enforcement date approaches with visible migration status and proactive engagement has already happened for the clients who are at risk of not completing on time. Post-cycle deprecation retrospective: after each major deprecation cycle — a URL version retirement, simultaneous retirement of three or more endpoints, or any deprecation that required a sunset extension — the engineering team conducts a structured retrospective against four questions: what was the client migration coordination overhead for this cycle and how does it compare to the policy's baseline estimate? Were there classification errors — changes that should have triggered the notice period and did not, or changes that triggered the notice period unnecessarily? Was the migration guide sufficient — did clients encounter edge cases not addressed by the guide, and how long did it take to resolve each undocumented case? Was the sunset enforcement mechanism executed — if not, what change to the exceptions process would have converted the extension into a managed commitment with a firm endpoint rather than an indefinite deferral? The retrospective output is a prioritized list of policy revisions, migration guide improvements, and taxonomy additions, each with the root cause analysis from the cycle that motivated it. The history of policy revisions is itself a decision record: the breaking change taxonomy that missed required field additions, the migration guide format that left semantic value changes undocumented, the exceptions process that lacked a maximum extension duration — and that history is most useful to engineering leaders onboarding into the API platform who need to understand not just what the current policy says but why each element is specified as it is; API design sessions in ChatGPT, Claude, or Perplexity that produced the current breaking change taxonomy, the migration guide templates, or the exceptions process criteria should be run through the open-source extractor before the semi-annual audit to recover the explicit reasoning about which change types were enumerated because of specific prior classification failures and which edge cases were added to the migration guide template because a specific client's integration surfaced them; the extractor makes the design session's reasoning available to the audit reviewer evaluating whether a proposed taxonomy revision closes a genuine gap or reopens a tradeoff the prior design explicitly decided against, enabling the revision to be made with the context of prior failures rather than repeating the analysis that produced the current taxonomy from scratch.
FAQ
What counts as a breaking change in a REST API?
A breaking change is any change to an API's behavior that can cause a correctly-implemented client, written against the current API documentation and calling the API with a valid request, to receive an error, produce incorrect output, or require a code change to continue functioning. Changes that are unambiguously breaking: removing an endpoint or method; removing a required or optional request field; changing a field's type (string to integer, integer to enum, nullable to non-nullable); changing a field's allowed values (narrowing an enum, tightening a regex constraint); changing a field's semantics (a 'status' field that previously returned 'active' or 'inactive' now returning 'enabled' or 'disabled' — syntactically unchanged, semantically breaking for clients switching on the string value); changing an error code or error format; changing authentication requirements. Changes that are unambiguously non-breaking: adding a new optional request field with a sane default; adding a new response field that clients are not required to process; adding a new endpoint; relaxing a request constraint. The classification gap most commonly occurs in the middle: adding a new required request field (breaking — existing valid requests now fail validation), changing a date field from ISO 8601 to Unix timestamp (breaking — clients that parse the date for downstream storage now receive an unparseable format), and changing a response field from nullable to non-nullable (breaking — clients that check for null now receive unexpected non-null values). The practical test: if a client that was working correctly yesterday could fail, produce wrong output, or require a code change because of this change, it is a breaking change regardless of whether the API gained or lost surface area.
How long should the deprecation notice period be for a public API?
The appropriate deprecation notice period depends on the change class and the client base characteristics. For enterprise clients with quarterly release cycles, six months is a reasonable minimum for endpoint removal — this provides two release windows, the minimum for a discover-plan-implement-test-deploy cycle with a test window before the first production deployment. For required field additions and response field type changes, three to four months is typically sufficient for the same enterprise client base. The failure mode in setting notice periods is applying a single period to all change classes: a 3-month notice for endpoint removal is inadequate for enterprise clients with quarterly release cycles; a 6-month notice for optional field additions trains clients that deprecation notices have exaggerated lead times. The notice period must be calibrated against the 90th percentile release cycle in the client base, not the median, because enterprise clients with the longest release cycles are typically the clients with the most complex integrations and the highest account value — a notice period adequate for the median client but inadequate for the enterprise tail generates the highest-stakes escalations at retirement time. The notice period for extensions is not a new notice period but an explicit extension communication specifying the new date and the reason, preserving the policy's credibility that retirement dates are firm commitments.
How do you actually sunset a deprecated API endpoint when enterprise clients won't migrate?
Enterprise clients who have not migrated by the sunset date are almost always in one of three states: they did not believe the deadline was real (the organization has deferred previous sunset dates and clients have learned that 'deprecated' means 'available indefinitely'); they did not have the engineering capacity to prioritize the migration before the deadline; or they have a technical blocker the migration guide did not address. The first state is a policy credibility problem solved only by executing a real sunset — selecting a lower-stakes endpoint, communicating with unusual clarity that it will be enforced, and enforcing it without exception to establish that all future retirement dates are real. The second state requires migration support: extending the deadline without providing support defers the problem to the next deadline with the same client in the same state; the practical options are migration engineering days (the organization's engineers pair with the client's engineers to execute the migration), compatibility shims (server-side translation of old-format requests to new behavior for a defined period), or a binding contract commitment with a specified completion date. The third state — a technical blocker in the migration guide — requires fixing the guide before extending the deadline, because the same client will be in the same state at the next extension date; the most common technical blocker is that the new endpoint's behavior is not equivalent to the old endpoint for an edge case the client depends on, and the deprecation announcement did not specify how that edge case would be handled in the replacement. The exceptions process should specify the maximum extension duration, the conditions for an extension, and the binding commitment required so that each extension is a managed event with a firm endpoint rather than an indefinite deferral.
How should API versioning strategy and deprecation policy be designed together?
API versioning and deprecation policies are interdependent: the versioning scheme determines what counts as a version boundary, and the deprecation policy specifies the lifecycle of each version. The most common misalignment is an organization that implements URL versioning (/v1/, /v2/) without a version-level deprecation timeline, so all URL versions accumulate as simultaneously active because no policy specifies when a URL version is retired. The design principle is that the deprecation policy should define the breaking change taxonomy first, and the versioning scheme should be derived from it: a new URL version is required when and only when old and new behaviors must be simultaneously available for different client segments for a period longer than the standard migration window for the change class — typically when client segments are on different contractual commitments or when the migration complexity prevents all clients from completing within the standard field-change notice period; field-level breaking changes that all clients can migrate to within the standard notice period do not require a URL version bump. A versioning scheme with a version-level deprecation timeline — a URL version deprecated at the release of the next version and retired 12 months later — produces a backward compatibility surface that is the current version plus at most one prior version in its deprecation window. A versioning scheme without a version-level deprecation timeline produces a surface that is the sum of all URL versions ever released, maintained indefinitely, because no policy converts the version's deprecated status into a retirement date.
Further reading
- Production incident severity framework decision record — the severity framework must include a data correctness criterion class to surface API deprecation failures invisible to availability-based monitoring: a breaking change the deprecation policy did not classify as breaking produces no error rate spike, no latency increase, and no availability degradation — it produces incorrect behavior that clients with downstream processing of the affected field discover at data audit time; a severity framework without a data correctness class assigns these incidents the wrong severity, triggers insufficient response resources, and produces customer communication that characterizes the failure as a service degradation rather than a data quality incident requiring a migration guide and a root cause explanation; the deprecation policy and the severity framework must also align on the criterion class for backward compatibility surface incidents — multi-version patches that do not affect availability but require coordinated remediation across all active API versions — so that a security vulnerability in a multi-version API surface triggers the right response resource allocation rather than a single-version patch timeline applied to a multi-version remediation scope.
- Engineering team communication channel decision record — the breaking change classification decision requires cross-functional context that a single-team channel review cannot provide; the channel structure must include a defined routing rule for API changes touching the taxonomy's contested boundary classes (required field additions, type changes, semantic value changes), with the SDK team, customer success, and enterprise account managers as required audience for the classification judgment; a platform team that applies the breaking change taxonomy without routing contested-boundary changes to a cross-functional review venue will produce the 32-person company's failure — a required field addition classified as non-breaking by engineers who are technically correct under the policy's written definition but operationally wrong for eight enterprise clients whose SDKs break without any notice period having been triggered; the channel structure is the mechanism that converts the taxonomy from a set of rules applied by individual engineers into a cross-team review process that catches the classification errors whose client impact is highest.
- On-call alert threshold calibration decision record — deprecated endpoints need usage-volume alert thresholds calibrated against the expected migration decline curve during the notice period; a deprecated endpoint with stable or increasing call volume is an endpoint whose clients have not started migrating, and the alert should fire during the notice period while proactive migration support is still possible rather than at the retirement date when it is not; the alert threshold for deprecated endpoint usage is a leading indicator that converts the sunset enforcement mechanism from a date-based trigger that surprises the customer success team into a managed process where migration engagement happens before the enforcement date; without this monitoring, the deprecation policy's enforcement depends on client self-reporting of migration blockers, which produces the last-minute escalation pattern that generates sunset deferrals.
- Engineering team meeting cadence decision record — migration support commitments in the deprecation announcement are operational deliverables that must appear in sprint plans and be tracked against completion; the meeting cadence must include a recurring deprecation review slot that fires quarterly to verify that each active deprecation's migration support deliverables — compatibility shims, migration engineering days, SDK releases — are on schedule, that customer success has identified which clients need proactive outreach, and that the engineering team has completed or scheduled the migration support work the announcement committed to; a deprecation policy that produces migration support commitments but a meeting cadence with no review slot for those commitments produces migration guides incomplete at the retirement date and the same sunset deferral dynamic that produces the seven-active-versions backward compatibility surface — because the deferral happens when the retirement date arrives with migration support gaps the client cannot bridge on their own, not only when enterprise clients object proactively.
- Open-source extractor — API deprecation policy design sessions in ChatGPT or Claude contain more explicit tradeoff analysis than most deprecation policy documents: the session where the engineering leader decided which change types to enumerate in the breaking change taxonomy, why the notice period for required field additions is four months rather than three, and how to design the exceptions process without converting it into an unlimited deferral mechanism contains the reasoning about which prior classification failures motivated each policy element; running those design session exports through the extractor before the semi-annual breaking change audit retrieves the explicit reasoning from the design conversation — including the specific client incidents that motivated each taxonomy addition — so the audit reviewer can evaluate whether a proposed taxonomy revision closes a genuine gap or reopens a tradeoff the prior design explicitly decided against; the distinction between a gap and a deliberate exclusion is most reliably available in the design conversation rather than in the reviewer's recall of a policy discussion that may have happened two or three years earlier, and that distinction determines whether the revision should add a new change class to the taxonomy or whether the proposed addition was already considered and excluded for a documented reason.