Maintaining Documentation for Multiple API Versions
API7.ai
July 21, 2026
Key Takeaways
- Treat every supported API version as a distinct contract. Give each version its own reference, examples, changelog, and lifecycle state instead of quietly rewriting one set of pages.
- Make the active version unmistakable. A persistent version selector, canonical URLs, visible status labels, and version-specific search prevent developers from copying instructions for the wrong contract.
- Publish documentation with the API. Versioned OpenAPI files, examples, and migration notes should pass review and automated checks in the same change that modifies production behavior.
- Document transitions, not only snapshots. Developers need a breaking-change inventory, before-and-after examples, dates, and a tested migration path.
- Use runtime signals as a second channel. The standardized
DeprecationandSunsetresponse headers can alert consumers whose teams never revisit the portal.
APIs rarely stay on version one. Authentication improves, resource models evolve, fields become obsolete, and business rules change. The hard part is not creating another /v2 reference. It is keeping several truthful sets of documentation available while making sure every reader knows which one applies.
This guide focuses on the documentation system around API versions. For the design trade-offs behind URL, header, and query-parameter versioning, first read API Versioning: Managing Changes Over Time.
Why Multi-Version Documentation Becomes Difficult
A single-version documentation site has a simple relationship: one page describes one production behavior. Multiple versions turn that relationship into a matrix. A provider might support v1 and v2 in production, preview v3, maintain two SDK generations, and offer regional deployments that do not upgrade simultaneously.
That complexity creates predictable failure modes:
- Search results lead users to an old reference without showing that it is old.
- A shared quick start silently changes to v2 while v1 users still depend on it.
- Code tabs call a different base URL or use a different schema than the page describes.
- A deprecated operation remains searchable but its replacement is not linked.
- A bug fix is applied only to the newest documentation, even though it affects every version.
- Documentation is published before the matching deployment reaches all environments.
The solution is to model documentation as versioned product data, not as a collection of loosely related pages.
flowchart LR
C["API contract change"] --> S["Versioned OpenAPI source"]
S --> V["Lint and compatibility checks"]
V --> D["Versioned reference and guides"]
V --> T["Contract and example tests"]
D --> P["Developer portal"]
T --> P
P --> O["Observed production version"]
O --> F["Freshness audit"]
F --> S
classDef source fill:#e8f3ff,stroke:#1677ff,color:#102a43;
classDef gate fill:#fff7e6,stroke:#d48806,color:#5c3b00;
classDef publish fill:#f6ffed,stroke:#389e0d,color:#173b0b;
class S,C source;
class V,T,F gate;
class D,P,O publish;
Design a Version-Aware Information Architecture
Give Each Version a Stable URL
Version selectors are useful, but a selector backed only by client-side state produces ambiguous links. A developer should be able to bookmark, share, and search a URL that always resolves to the same contract, such as:
/docs/v1/users/create /docs/v2/users/create /docs/v3-preview/users/create
Do not reuse /docs/users/create for whichever version is newest unless it is clearly a landing page. If it redirects, state the policy and avoid redirecting a link that previously represented another contract. Stable URLs also make analytics and support tickets easier to interpret.
Use canonical metadata deliberately. A v1 page and a v2 page are not duplicates when they describe different behavior, so each should normally be self-canonical. If a retired page contains no unique migration value and permanently redirects, then the replacement can become canonical.
Keep Version Context Visible
Do not rely on the URL alone. Display the version in the header, navigation, endpoint title, and copied code. A good status banner combines a label with a next action:
v1 — Deprecated. Supported until March 31, 2027. Migrate to v2 using the upgrade guide.
Use distinct labels for preview, current, supported, deprecated, and retired. “Old” is not a lifecycle policy. Preview documentation should also state whether breaking changes can occur and whether production use is supported.
When a reader changes versions, preserve the current conceptual page if an equivalent exists. If it does not, take the reader to a version landing page with an explanation rather than showing an unrelated endpoint.
Separate Shared Concepts from Versioned Contracts
Not every page must be copied. Concepts such as account setup or general security guidance may apply across versions, while endpoints, schemas, error catalogs, SDK instructions, and limits often differ.
Classify content explicitly:
| Content | Typical Strategy | Reason |
|---|---|---|
| Endpoint reference | Versioned | It is part of the contract |
| Request and response examples | Versioned and tested | Fields and behavior change |
| SDK setup | Versioned by SDK/API compatibility | Package generations can diverge |
| Authentication concept | Shared when behavior is identical | Avoid needless duplication |
| Changelog | Chronological and filterable | Shows transitions across versions |
| Migration guide | Connects exactly two versions | Gives users an actionable path |
| Deprecation policy | Shared | Establishes provider-wide expectations |
Shared pages should declare which versions they cover. “Applies to v1 and later” is more useful than no scope statement.
Make the Contract the Source of Truth
Maintain one OpenAPI document per independently supported contract. A directory can be simple:
contracts/ v1/openapi.yaml v2/openapi.yaml v3-preview/openapi.yaml docs/ shared/ migrations/v1-to-v2.md migrations/v2-to-v3.md examples/ v1/ v2/
Pin tools to a contract file and a release identifier. A build that reads a mutable latest.yaml can accidentally republish older pages with newer schemas. Record the API version, source commit, and build time in generated output so an auditor can trace what was published.
Run three types of checks in continuous integration:
- Structural validation checks that every OpenAPI document is valid and every internal link resolves.
- Compatibility analysis compares the proposed contract with the released version and flags removed operations, narrowed schemas, new required properties, or changed security requirements.
- Behavioral verification sends documented requests to a version-specific test environment and validates the responses against the same contract.
Generated reference material does not replace narrative content. It prevents endpoint drift, while humans still own quick starts, concepts, migration decisions, and troubleshooting.
Write Migration Guides That Developers Can Execute
A changelog records what happened. A migration guide explains what a consumer must do. Keep those purposes separate.
Start each guide with scope and urgency:
- Who must migrate?
- What is the target version?
- When does support end?
- Can old and new versions run in parallel?
- Where can a team get help?
Then inventory each breaking change in a repeatable format: old behavior, new behavior, consumer impact, required change, and verification. Include before-and-after requests rather than relying on abstract prose.
# v1: version in the path GET /v1/orders/ord_123 HTTP/1.1 Host: api.example.com Authorization: Bearer ${ACCESS_TOKEN} # v2: version selected explicitly by header GET /orders/ord_123 HTTP/1.1 Host: api.example.com Authorization: Bearer ${ACCESS_TOKEN} X-API-Version: 2026-07-01
If a response shape changes, show a field mapping table. Call out fields that moved, changed type, became required, or no longer exist. Provide a test checklist and rollback conditions. For long migrations, include a way to compare traffic or responses between versions before switching all consumers.
sequenceDiagram
participant P as API Provider
participant D as Documentation Portal
participant C as API Consumer
participant G as API Gateway
P->>D: Publish v2 docs and v1-to-v2 guide
P->>C: Announce support and sunset dates
C->>G: Continue calling v1
G-->>C: v1 response plus deprecation signals
C->>D: Follow migration and test checklist
C->>G: Send canary traffic to v2
G-->>C: Validate v2 behavior
C->>G: Move production traffic to v2
P->>D: Retire v1 reference but keep migration page
Communicate Deprecation in Documentation and Responses
A banner in a portal reaches only people who open the portal. Machine-readable response metadata reaches active integrations. Use both.
RFC 9745 standardizes the Deprecation response header and the deprecation link relation. RFC 8594 defines Sunset, which communicates when a resource is expected to stop responding. A response might include:
HTTP/1.1 200 OK Deprecation: @1798675199 Sunset: Wed, 31 Mar 2027 23:59:59 GMT Link: <https://developer.example.com/migrations/v1-to-v2>; rel="deprecation"; type="text/html" Content-Type: application/json
Deprecation and sunset are different. Deprecation says that consumers should stop starting new work on a version. Sunset says when the provider expects it to become unavailable. The sunset date must not precede the deprecation date.
At the gateway layer, these headers can be added consistently for an entire route group, even when several upstream teams own the APIs. Platforms such as API7 Enterprise can also keep version routing, traffic observation, and policy enforcement centralized. The portal remains the detailed source; the gateway provides an operational reminder and evidence about which consumers still use the older version.
Do not expose consumer secrets or internal implementation details in deprecation telemetry. Associate usage with approved client identifiers, aggregate where possible, and define retention rules.
Operate a Documentation Release Workflow
For each API release, require a documentation change set that contains:
- the immutable contract file and version identifier;
- rendered reference updates;
- tested requests and responses;
- a breaking-change report;
- a changelog entry;
- a migration guide when consumers must act;
- updated lifecycle dates and support contacts;
- search, redirect, and navigation changes.
Preview the whole site, not only changed pages. Version selectors, cross-version links, global search, and copy buttons often fail at integration boundaries. Run a link checker against every supported version and scan code blocks for stale hosts, version prefixes, and SDK package names.
After publication, verify the deployed documentation against production metadata. A lightweight audit can compare the versions listed by the portal, contract registry, gateway routes, and support policy. Any disagreement should create an owner-visible alert.
Retirement does not mean deletion on the sunset date. Remove obsolete pages from primary navigation and search, but preserve a small tombstone page at established URLs. It should identify the retired version, link to the successor and migration guide, and explain the resulting runtime behavior, such as 410 Gone. Historical documentation may need longer restricted retention for regulated or long-lived integrations.
Multi-Version Documentation Checklist
Before calling a version ready, confirm that:
- every page and example identifies its version;
- the version has a stable, shareable URL;
- the contract, docs, SDK, and test environment agree;
- search results expose lifecycle status;
- the version selector has a meaningful destination for every page;
- all breaking changes have migration instructions;
- deprecation and sunset dates appear consistently across channels;
- documented requests execute without hidden setup;
- old links have intentional redirects or tombstone pages;
- an owner and review date exist for every supported version.
Conclusion
Successful multi-version documentation gives developers two kinds of certainty: what their current integration can rely on, and what they must do next. Stable URLs, explicit lifecycle labels, versioned contracts, executable migration guides, and automated verification turn that certainty into a maintainable system.
Next, learn how to use the contract behind that system in Using OpenAPI for API Documentation. You can also review API Lifecycle Management for the wider process from design through retirement.