Currently Available: Need a skilled Software Developer for your next project?
Categories
APIs

How to Version an API Without Breaking Existing Clients

When you change an API, software that already calls it may keep sending the old requests and expecting the old responses. An API version identifies the contract between a service and its clients. That contract defines which operations are available, what data they accept, and which responses they return. A breaking change alters that contract in a way an existing client cannot handle.

The safest approach is to preserve the current contract for existing clients and introduce a new version only when a breaking change is necessary. Then give clients a clear migration path and keep the old version available long enough for them to move. You also need to decide which changes keep old clients working and when to retire an old version.

Decide which changes need a new version

Create a new version when a change makes a valid request or response under the old contract invalid or unusable. Renaming a response field, changing its data type, removing an operation, or making an optional request parameter required are common examples. An existing client fails if it receives data it cannot use or sends a request the service no longer accepts.

Adding an optional request parameter or response field is generally compatible because existing clients can continue using the fields they already know. However, some clients reject unknown response fields or rely on exact response shapes. Before treating an addition as safe, consider how actual clients parse responses and whether their generated code tolerates fields they have not seen.

Keep changes that preserve the existing contract in the current version. Reserve a new major version for changes that break it. This avoids creating a separate version for every small improvement, which adds maintenance work without giving clients a clear benefit. The discussion of semantic versioning for APIs explains why applying major, minor, and patch numbers to a hosted API can create needless version branches.

Choose a version identifier clients can use

For many HTTP APIs, putting a version in the path, such as /v1/ or /v2/, makes it easy to find in request URLs, logs, and documentation. A client switches versions by changing its base URL. The server must direct requests to the right version and support each path, and the URLs show the API’s version history. API designers disagree about whether versions belong in resource URLs. Versioning strategy guidance covers this trade-off.

A header-based approach keeps the URL stable and tells the server which representation or contract the client expects. For example, a client can use the HTTP Accept header to request a media type, a label for the response format it accepts. This keeps version selection out of the URL, but makes requests less obvious to inspect and can complicate debugging when a tool or intermediary hides or changes headers. Choose this approach when your clients and infrastructure reliably support it.

Whichever method you choose, document it consistently across your API portfolio. Clients should be able to find the version in the same place for each service. Postman’s API versioning guidance also emphasizes establishing a strategy early so API owners and consumers can plan around it.

Run old and new contracts side by side

When you release a breaking change, keep the old contract working while clients adopt the new one. For example, a service can route /v1/customers to the old behavior and /v2/customers to the revised behavior. Both versions can share internal business logic, but each must return the fields and status behavior its own clients expect.

Supporting multiple versions takes engineering time and infrastructure resources. Developers must account for each version when they fix defects, update documentation, or change behavior shared across versions. Avoid keeping separate copies of the whole service when one shared implementation can handle each version’s requests and responses. The trade-offs of URI versioning include its visibility and the risk of duplicated maintenance.

GraphQL, a query language and runtime for APIs, does not remove the compatibility problem. A GraphQL service can change its schema, the set of fields and behaviors it offers, but clients still depend on those fields and behaviors. If the API owner cannot control when clients update, the owner still needs to preserve what older clients expect or manage a breaking change. The limits of GraphQL as a versioning solution describes this issue.

Retire an old version with notice

Deprecation and sunset describe two stages of retiring an API version or feature. Deprecation tells clients that it is being phased out. A sunset date tells them when the service plans to stop providing it. The HTTP Deprecation and Sunset headers can send these notices in responses. The API deprecation guidance explains how to use them along with direct migration notices.

Before setting a sunset date, measure traffic by version and identify the clients that still use the older contract. You can identify clients only from information your API records, such as credentials or other request details. Check that your request records distinguish consumers before relying on them to identify clients. Send those clients a migration guide that names the changed behavior, shows the replacement, and explains the retirement date. Monitor old-version traffic as the deadline approaches, then confirm which clients have moved before shutting down the endpoint.

Do not use one traffic threshold as a cutoff for every API. Even a small share of requests can come from a critical customer or an integration that runs infrequently. Set the support period to fit your clients’ release cycles. Account for the impact of failure, and allow clients enough time to test a migration. Without direct notice and a usable migration path, clients may discover the retirement only when their requests fail.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *