SaaS product engineering

API deprecation: make customer migration verifiable

Define how customers will complete their work after the old endpoint closes. Then make the migration decision depend on evidence for each consumer.

Planning example
Fictional export migration from page numbers to opaque cursors
Artifacts
Five-cohort ownership matrix, acceptance worksheet and checked example dates
Evidence boundary
Proposed migration plan; no actual consumers or endpoint rollout tested
Client tokens move from a navy connector lane to a teal lane while amber and unassigned tokens await a decision.
Conceptual illustration of verified migration progress with unresolved ownership kept visible.

Start with the customer's job after the old endpoint closes

An API retirement plan should explain how each affected consumer will complete its existing work after the old interface becomes unavailable. A release date and a replacement endpoint are inputs to that plan. Neither demonstrates that a customer's integration has migrated.

Consider a fictional reporting API moving from page-number pagination to opaque cursors. The customer wants a complete scheduled export, with recoverable progress after an interrupted run. Replacing page=4 with a cursor parameter is only one part of that job. The integration must also understand whether a cursor expires, how ordering behaves and what to do when the source data changes during an export.

This article provides a proposed planning package, not a completed migration or a customer case study. The consumer cohorts are illustrative. Use the consumer matrix and acceptance worksheet to assign real evidence before choosing the final retirement decision.

Define the replacement in observable behavior

For the fictional export, define the result before declaring the new API ready. Does an export represent a stable snapshot or a changing view? Are repeated records possible after a retry? Can the consumer resume with the same cursor, and what response tells it to restart? The provider and consumer need the same answers.

A useful acceptance example fixes a small dataset and an explicit ordering rule, interrupts the export after one page, then resumes it through the supported mechanism. Compare the complete exported identity set with the intended dataset. Add a separate case for an expired cursor. These are proposed checks; this planning package does not implement either endpoint or claim a no-duplicates guarantee.

Document differences that require customer work, including authentication scope, error handling and SDK support where they change. Keep unaffected behavior out of the migration checklist unless a regression check needs it. A long list of general API advice makes the actual breaking change harder to identify.

The customer needs a complete resumable export. The proposed replacement contract must define data view, ordering, cursor lifetime and restart behavior before acceptance can establish readiness.
Figure 1. Proposed export-migration acceptance boundary. Neither endpoint is implemented in this planning package. View full-size figure.

Assign an owner to every missing replacement capability. If a customer depends on a supported behavior that the new version lacks, classify it as a migration dependency. Renaming it an exception does not make the replacement sufficient.

Separate readiness from an empty traffic chart

A consumer inventory should join request evidence to a responsible integration owner. Avoid assuming one API credential equals one customer or one deployed client: credentials can be shared, rotated or used by multiple scheduled processes. Record the attribution rule and its known gaps.

Illustrative consumer cohorts and the next evidence needed before migration can be confirmed
Illustrative cohortCurrent evidenceRequired next proof
Daily exporterNamed owner; new endpoint exercisedComplete interrupted-export acceptance and confirm deployment
Monthly finance jobOwner known; no requests this weekObserve the relevant scheduled cycle or run an agreed equivalent
Shared integration credentialRequests exist; several possible ownersSeparate consumers and assign accountable owners
Dormant clientNo recent requests; owner has not confirmed retirementConfirm intended future use and the treatment of reactivation
Unknown callerOld-version traffic cannot yet be attributedResolve ownership or record an explicit unresolved-risk decision

None of these fictional rows is marked migrated. The matrix is a device for exposing missing evidence, not a scorecard designed to turn green. Choose observation windows according to the consumer's actual use cycle and explain what happens when that cycle is longer than the proposed transition period.

Track two populations separately: known consumers and unattributed old-version traffic. A percentage calculated only from identified integrations can look complete while excluding the unresolved callers. Record the denominator alongside every progress number. A vanished request stream may indicate a failed job, an attribution change or dormancy, rather than successful adoption.

Make the notice actionable at the point of use

Publish a migration guide that names the affected resources, behavior changes, replacement path and the evidence customers should produce. Include the transition dates with their time zone, an owner for questions and a clear exception process. The guide should let an integration maintainer estimate the work without reverse-engineering a changelog.

The Deprecation header defined by RFC 9745 signals a resource's lifecycle status. Its presence does not change the resource's behavior. The accompanying deprecation link relation can point to migration information. Document any intended scope beyond the responding resource so that consumers do not have to guess which API surfaces the notice covers.

An illustrative schedule can announce deprecation at 00:00 UTC on October 1, 2026 and expected retirement at 00:00 UTC on January 1, 2027. These dates belong only to this example. They are not a Dreamtsoft API announcement or a recommended universal notice period.

Illustrative procedure
Deprecation: @1790812800
Sunset: Fri, 01 Jan 2027 00:00:00 GMT

The two headers deliberately use different date formats. Deprecation uses a Structured Field Date; RFC 8594's Sunset field uses HTTP-date and indicates expected unavailability. RFC 9745 requires the sunset timestamp not to precede deprecation. The supplied date check verifies this example's conversion and ordering only.

A header can make a notice discoverable to software, but it does not prove the customer's maintainer saw it. Treat observed delivery, owner acknowledgement and completed migration as separate records. The communication owner should decide which additional established customer channels are necessary for the affected population.

Gate retirement on evidence and owned exceptions

Use a migration state that names the next missing proof. For example, identified can move to replacement verified after the behavioral checks pass, then to consumer deployed when the responsible owner confirms the intended runtime uses the new path. Add old dependency cleared only after the agreed observation and acceptance conditions are satisfied.

Proposed states progress from identified to replacement verified, consumer deployed and old dependency cleared. Unattributed callers and owned exceptions remain visible beside the decision.
Figure 2. Proposed evidence states. All five illustrative cohorts remain pending; no customer migration has been measured. View full-size figure.

These are proposed states, not a required industry standard. The value is that a decision maker can ask what evidence changed between them. A support acknowledgement should not silently stand in for deployment proof, and deployment of one worker should not stand in for all consumers behind a shared credential.

An exception needs an owner, affected scope, reason, next action and review condition. Record whether it delays global retirement, receives a separately supported transition path or results in an explicitly accepted loss of service for that use. Do not leave a silent permanent compatibility branch without an accountable decision.

Before closure, rehearse the intended post-retirement behavior in an appropriate test environment. Record what a remaining old client receives and what operators can observe. Sunset metadata alone does not specify the eventual response. If postponement or temporary re-enablement is possible, document who can authorize it and which data or behavior changes could make it unsafe.

Give the decision owner a short, inspectable packet

The final packet should contain the behavioral acceptance evidence, attributed consumer inventory, unresolved caller evidence and owned exceptions. Add the current notice, the planned closure behavior and the observations that would change the decision. This is enough to distinguish readiness from confidence based on a declining traffic chart.

For the fictional cursor migration, the key evidence is that real consumers can complete and resume their export under the documented contract, and that remaining old dependencies are either cleared or explicitly owned. Sending the announcement is a communication milestone. Retirement is a product decision made from the resulting evidence.

Sources

Documentation checked .

  1. RFC 9745: Deprecation HTTP header
  2. RFC 8594: Sunset HTTP header