Skip to content

Docsio v2 is out

See changelog
← Docsio Research

API lifecycle · Research synthesis

What an API deprecation notice must prove to customers

A research-backed guide to API retirement notices, changing defaults, migration acceptance cases and evidence that customers can safely leave an old version.

By Docsio Research14 min read

A deprecation date tells an integration owner when to act. A useful migration guide also identifies the affected contract, shows the behavior that changes and supplies a way to verify the replacement. Protocol signals and a successful HTTP response cannot establish that the customer's workflow still produces the right result.

Key findings

  • Deprecation, expected retirement and a deprecated OpenAPI operation communicate different information. The guide must supply the missing scope and migration details.

  • Current GitHub documentation describes a date format that differs from RFC 9745. Verify provider-specific behavior before relying on a generic warning parser.

  • Kubernetes documents an empty-selector behavior change across PodDisruptionBudget API versions. A familiar field can carry a different meaning after migration.

  • A completion record should separate observed traffic, selected configuration and tested application outcomes. Each answers a different question.

How we researched this

We read two RFCs, the pinned OpenAPI 3.1.1 specification, Google's compatibility guidance and GitHub and Kubernetes documentation on November 5, 2026. We compared the scope of each signal and policy, then designed a fictional paginated-report migration to illustrate acceptance evidence. The proposal is editorial synthesis. We did not run a vendor migration, inspect customer integrations or measure retirement outcomes.

What should a customer be able to do after reading the notice?

A useful deprecation notice lets an integration owner make three decisions. They can determine whether the change affects their application, identify the work required, and collect evidence that the replacement behaves correctly. A date and a link to the newest reference page answer only part of that problem.

Consider a fictional reporting API. Its old endpoint returns a complete array of records. The replacement returns a page of records and a continuation cursor. A customer changes the route, sees an HTTP 200 response, and marks the migration complete. The daily report now quietly contains only the first page. A syntactically valid response can conceal an incomplete business result.

Our proposed review starts with the outcome the customer depends on. In this example, the requirement is to retrieve the complete set exactly once, including records after the first page. The guide should make that condition visible before presenting the new request. It should also distinguish a malformed request, an empty result, and a request that retrieved only part of the data.

Customer questionEvidence the documentation should provideWhat the customer can verify
Does this affect my integration?Named operations, versions, environments and relevant configurationThe running application uses at least one affected contract.
What is changing?A before-and-after description of request, response and behaviorEach dependency in the application has a replacement or a stated limitation.
When must work finish?A precise deadline with timezone, the event it represents and any exceptionsThe deployment plan completes before the applicable cutoff.
What does success look like?Expected outputs for realistic cases, including a boundary caseThe integration produces the expected result, not merely a successful request.
What happens if migration fails?Supported recovery actions and the limits of revertingThe operator knows which actions remain available at each stage.

This matrix is an editorial proposal. The remaining sections connect it to current protocol definitions and concrete provider documentation. It is designed to help a team review one retirement notice, rather than to select an API versioning strategy.

What do Deprecation, Sunset and an OpenAPI flag actually say?

RFC 9745, published in March 2025, defines Deprecation as an HTTP response header field carrying a Structured Fields date. It signals when deprecation takes effect, including a date in the past. Deprecating a resource does not itself change its behavior. The RFC also defines the deprecation link relation for associated information. A broader scope than the responding resource needs to be documented. When both dates are supplied, the sunset timestamp must not precede deprecation. RFC 9745, sections 2–5

RFC 8594, published in May 2019, describes Sunset as a signal that a URI is likely to become unresponsive at a specified time. It uses an HTTP date. The field does not specify whether the eventual outcome is an error, a redirect or an unreachable service, and it is separate from cache freshness. A provider therefore still needs to document its actual retirement behavior. RFC 8594, sections 3–5

SignalInformation it carriesInformation the guide still needs
Deprecation response fieldThe resource's deprecation dateThe affected scope, reason, replacement and required work
Sunset response fieldExpected future loss of availabilityWhat the service will return and what clients should do
OpenAPI operation flagA declaration that an operation is deprecatedA schedule, migration procedure and completion criteria

The pinned OpenAPI 3.1.1 specification defines the operation-level deprecated field as a boolean, defaulting to false. It says consumers should refrain from using a deprecated operation. That flag can help a rendered reference identify an operation to avoid, but the field itself carries no cutoff date or migration steps. These statements refer specifically to version 3.1.1 of the specification. OpenAPI Operation Object

Check the notice in each place a customer encounters it: the old reference, the response metadata, the changelog and the migration guide. Ask a reviewer to identify the applicable date without being told which page is authoritative. If they find different dates, resolve the discrepancy before turning it into a customer reminder.

Why should a migration guide distinguish a standard from provider behavior?

A standards-compliant example and a provider's documented interface can differ. On November 5, 2026, GitHub.com's public REST API-version documentation describes its Deprecation value as an HTTP date. RFC 9745 specifies a Structured Fields date instead. That is a documentation-level mismatch. We did not call a retiring GitHub endpoint to establish which representation it actually emits. GitHub closing-down guidance · RFC 9745 syntax

For a client maintainer, this creates a specific verification task. Preserve a sanitized response from the relevant provider and environment, then check the parser against that representation and the provider's support guidance. Record which behavior the client accepts. Treat an unparseable date as a visible diagnostic, so a warning does not silently disappear while the normal request continues.

For a provider authoring new documentation, publish the exact format that the implementation produces and test the example. If you are correcting an older format, explain whether existing clients need a parser change and when that correction takes effect. A screenshot of a dashboard date cannot serve as the entire contract for a machine-readable warning.

Keep observation and expectation in different fields in an internal review record. For example, “documented format,” “captured format,” “capture date,” and “parser result” make a discrepancy easy to discuss. Leave the captured format unverified until someone has obtained an appropriate response. Guessing that the server follows either the RFC or a documentation example creates an avoidable blind spot.

The customer-facing guide should present the supported behavior clearly. The internal review record can preserve the uncertainty and the steps taken to resolve it. That distinction allows a team to investigate a contradiction without publishing an unsupported claim that a live service is broken.

Why there is no single notice period to copy

Provider policies attach to different units and stability levels. Compare the unit before comparing the number of months. A hosted API version, a Kubernetes API group version and a command-line flag can have different promises even when the same company or project maintains them.

Published policyUnit and stated conditionConsequence for the notice writer
GitHub REST APIThe previous API version remains supported for at least 24 months after a new version is released.Name the relevant version and the event that starts the window.
Kubernetes GA APIA GA API version may be deprecated but must not be removed within a Kubernetes major version.Distinguish deprecation from endpoint removal.
Kubernetes beta APIFor a deprecated beta API version, serving ends nine months or three minor releases after deprecation, whichever is longer.Track both elapsed time and release count.
Kubernetes alpha APIRemoval is permitted in any release without prior deprecation notice.Show the stability level prominently.

These are the policies as read on November 5, 2026. GitHub also documents exceptional changes for critical security or reliability issues and some low-usage services. Kubernetes separately defines rules for other interfaces. The rows above concern its API versions. Rule 4a separately sets an introduction-to-deprecation window for beta APIs. The beta row shows the later deprecation-to-removal window. GitHub policy · Kubernetes rule 4a

For your own product, begin with commitments already made to customers and the practical work required to leave the old contract. A long interval can still be hard to use when the replacement is unavailable in the customer's region, has a missing capability, or requires another team to change first. Show those dependencies next to the deadline.

Use a table of dated milestones only when each milestone has a defined effect. “New integrations should use the replacement” and “old requests will be rejected” need different descriptions. If a date is provisional, identify who confirms it and where the customer will see an update. Avoid publishing a single bold date that leaves customers to infer what happens.

The clock also needs an owner. Assign someone to check that the notice, the old guide and operational behavior still agree after a postponed cutoff. A moved deadline is easy to update in one article and easy to leave stale in a code example or automated message.

What can break even when the fields look familiar?

Kubernetes provides a particularly useful historical example. Its migration guide says the policy/v1beta1 PodDisruptionBudget API stopped being served in v1.25 and points to policy/v1. In the new version, an explicitly empty spec.selector selects all pods in the namespace. In the old version it selected none. An unset selector selects none in both versions. That is a behavior change a simple version-string replacement would not explain. Kubernetes PodDisruptionBudget migration

Google's AIP-180 similarly treats visible semantics as part of compatibility. It discusses changes to static defaults and to formats or construction of existing field values, including output fields. The guidance recognizes that user code can reasonably depend on behavior beyond a type declaration. This is design guidance, not a count of how often real migrations fail. AIP-180

Use those examples to ask better review questions about your own contract. Does omitting a field mean the same thing as supplying an empty value? Does a date retain its timezone? Are identifiers still opaque to the application? Does a returned object represent a completed action or an accepted request awaiting completion? Each answer should identify a concrete condition the integration owner can test.

A useful change entry has four parts: the previous behavior, the replacement behavior, the affected application assumption, and an example that distinguishes the two. “Pagination changed” is a heading. “Continue until the response has no next cursor; the first response can contain fewer records than the complete result” gives the customer a condition to implement and verify.

Include a case where the old assumption produces a plausible answer. Developers can catch a conspicuous error during a smoke test. An incomplete list or an overly broad selector may look normal until someone compares the result against an expected set. Put that comparison in the migration guide, beside the happy-path example.

A worked migration check for a paginated API

Return to the fictional reporting API. We will use a tiny fixture with three records, named A, B and C. This is an invented documentation example, not a benchmark or a test of Docsio or another service. The chosen identifiers make completeness and duplication easy to inspect.

The old request to GET /v1/reports returns an array containing A, B and C. The replacement request to GET /v2/reports returns A and B plus a next cursor. A second request with that cursor returns C and no next cursor. We define the fixture so the pages are stable for the duration of the check. Production behavior around changing datasets needs its own documented rule.

Acceptance caseSetup and expected responsePassing application result
Complete reportFirst page contains A and B with a next cursor. Second page contains C with no next cursor.The application combines A, B and C exactly once and stops after the final page.
Empty reportFirst response contains no records and no next cursor.The application reports an empty result and terminates without another request.
Second-page failureFirst page succeeds; the next page returns a failure defined by the API's error contract.The application marks the overall result incomplete and follows the documented recovery rule.

For the first case, require the integration owner to compare identifiers and record count, not only HTTP status. For the empty case, require termination. For the failure case, specify whether restarting or retrying can safely repeat earlier work. The provider must supply its actual retry and consistency contract before this fixture becomes executable guidance for a real product.

Keep requests and responses together in the published guide. If code is supplied, have the example print a small summary containing the expected count and a completion indicator. Readers should be able to tell whether they ran the full example. An output sample with a success sentence but no relationship to the returned data is hard to use as evidence.

A customer with a different dependency may need another case. If the report feeds an ordered reconciliation process, verify order. If records contain amounts, verify units and precision. State which dimensions the provided fixture covers so an owner can identify the missing application-specific checks.

The migration evidence should record the client build, selected API version, environment, fixture revision and outcome. That ties “passed” to an identifiable configuration. Reusing an old result after changing the SDK, a parser or a default parameter would otherwise make the record look more reassuring than it is.

How do you know customers have finished migrating?

A provider can observe requests to a deprecated operation. It usually cannot infer every downstream dependency from those requests. As a thought experiment, a monthly reporting job may be absent from a seven-day observation window and still be waiting to call the old endpoint. An integration used only during recovery can be even quieter. These are possible blind spots, not measured prevalence estimates.

Our proposed completion record separates three kinds of evidence. First, the owner identifies the running clients and their configuration. Second, a representative fixture passes against the replacement. Third, the owner observes the intended operational path using that configuration. Treat a remaining unknown as an explicit item instead of silently converting “no recent requests seen” into “migration complete.”

EvidenceWhat it can establishWhat still needs checking
No old requests in a stated windowThe observed traffic did not use the old contract during that window.Scheduled, infrequent, offline and recovery clients outside the observation period
New version configuredThe selected setting has changed in the inspected deployment.Overrides, alternate deployments and application behavior
Acceptance fixture passesThe tested configuration handles the covered cases.Untested permissions, scale, data shapes and workflows
Owner acknowledges completionA responsible person has reviewed the migration.Whether the evidence and observed configuration support the acknowledgment

Give customers a route for reporting a blocker in terms the engineering team can investigate. Ask for the affected operation, the old and replacement versions, a sanitized example, the expected result and the observed result. Discourage sending credentials or sensitive payloads. An issue that says “the replacement cannot express this filter” is more actionable than one saying “migration is difficult.”

Keep the completion criteria proportionate to the change. A text-only correction to a description needs less evidence than a change to authorization or record selection. The point of the record is to expose the assumption being replaced and the evidence that supports the new one.

Before the cutoff, review unresolved cases with a named decision owner. If a customer has a valid missing-capability report, that is information about the migration plan. Record the decision and update the relevant notice when it changes. A support thread and the public guide should not give contradictory instructions.

What should the finished migration guide contain?

Start the page with a short statement of who is affected and the required action. Follow it with the schedule and the replacement's availability. Then show the behavior changes and acceptance cases. Put uncommon constraints near the step they affect, where a reader can use them while making the change.

Keep the old operation's documentation discoverable with a prominent status notice and a link to the migration guide. A customer diagnosing an existing integration still needs to understand its current behavior. Decide separately what happens to historical reference URLs and to API requests. Redirecting a documentation page does not migrate the application that used the old endpoint.

For the fictional reporting example, the opening could say: “Applications using the v1 report-list operation must move to the paginated v2 operation before the published cutoff. Update the page loop and verify the complete three-record fixture before changing the production client. An HTTP 200 response from the first page does not establish that the full report was retrieved.” The actual date, supported environments and recovery instructions belong immediately beside it.

A final editorial review can be brief and concrete. Ask someone unfamiliar with the change to identify an affected client, follow the proposed steps, explain the expected output and locate the recovery path. If they need to infer a default or ask which version a screenshot shows, improve that part of the guide.

Save the review against the published revision and repeat the relevant checks when the implementation or deadline changes. The useful result is a migration guide that an integration owner can turn into a verified deployment plan, with remaining uncertainty visible to the people making the retirement decision.

Limitations

Published policies and examples do not establish live behavior for every provider endpoint. The documented header-format mismatch is not a captured wire-level observation. The fictional fixtures and completion matrix are proposed checks, not a validated benchmark or a universal notice policy. Appropriate timelines and recovery steps depend on the actual contract and customer obligations.

Sources

  1. RFC 9745: The Deprecation HTTP Response Header FieldIETF, Sanjay Dalal and Erik Wilde · Accessed 2026-11-05
  2. RFC 8594: The Sunset HTTP Header FieldIETF, Erik Wilde · Accessed 2026-11-05
  3. API versionsGitHub · Accessed 2026-11-05
  4. Kubernetes deprecation policyKubernetes · Accessed 2026-11-05
  5. Deprecated API migration guideKubernetes · Accessed 2026-11-05
  6. AIP-180: Backwards compatibilityGoogle API Improvement Proposals · Accessed 2026-11-05
  7. OpenAPI Specification 3.1.1, Operation ObjectOpenAPI Initiative · Accessed 2026-11-05