API Versioning 2026
API versioning lets you evolve your interfaces without breaking existing clients and integrations.
Overview
API versioning is the deliberate management of changes to an interface over time. It applies equally to REST APIs, GraphQL schemas, and gRPC services. The goal is to introduce new features and fixes while keeping existing clients working. REST APIs typically version through the path or headers, GraphQL relies on schema evolution and deprecation, and gRPC uses Protocol Buffers with semantic versioning. Regardless of approach, changes must be categorized, communicated, and documented. A clear versioning strategy is central to API lifecycle management and long-term platform stability.
Key Concepts
Backward-compatible and breaking changes
A backward-compatible change adds new functionality without disrupting existing clients. Common examples include optional new fields, additional endpoints, or new query filters. A breaking change alters existing behavior—removing fields, changing required parameters, or renaming endpoints. Breaking changes demand a new version or at least a careful migration path.
REST API versioning
URI versioning and header versioning are the most common approaches for REST. URI versioning uses paths like /v1/products and works well with caching. Header versioning passes the version through a header such as api-version: 1 or Accept: application/vnd.shop.v2+json. Content negotiation is flexible but requires more effort.
GraphQL schema evolution
GraphQL doesn’t use traditional path-based versioning. Instead, the schema evolves incrementally. New fields and types can be added without breaking existing queries. Deprecated fields are marked with the @deprecated directive. Clients decide when to adopt new fields at their own pace.
gRPC and Protocol Buffers versioning
gRPC uses Protocol Buffers for message definitions. New fields can be added as long as they use carefully assigned field numbers. Old clients ignore unknown fields, and new clients handle default values. Semantic versioning helps communicate major, minor, and patch releases.
Semantic versioning
Semantic versioning follows the format Major.Minor.Patch. Major indicates breaking changes, minor indicates new backward-compatible features, and patch indicates bug fixes. For external APIs, often only the major version is communicated publicly to keep complexity manageable for users.
Deprecation and migration
When a version or field should no longer be used, mark it as deprecated. For GraphQL, use @deprecated; for REST, use headers like Deprecation or Sunset. Document the migration path, notify users early, and set a clear end-of-life date.
Documentation across versions
Maintain documentation for each version, including a changelog and migration guide. Users need to understand what changed and what actions are required to upgrade.
Caching and versioning
Versioning in the path is easiest to cache because each version has its own URL. With header versioning or GraphQL, caches must be configured to account for relevant differences. Otherwise, you risk serving incorrect cached responses.
Monitoring and usage analytics
Track which versions are in use. This tells you when old versions can safely be retired. Rate limiting and logging per version help identify load patterns and issues.
API governance
Larger organizations use API governance to standardize how versions are managed. Standards for versioning, deprecation, communication, and documentation ensure consistency across teams and APIs.
Practical Example
A company operates both a REST API and a GraphQL API. It needs to introduce a breaking change to customer address data.
REST API v1:
GET /v1/customers/42
{
"id": 42,
"name": "Acme Corp",
"address": "123 Main Street, 10115 Berlin"
}
REST API v2:
GET /v2/customers/42
{
"id": 42,
"name": "Acme Corp",
"address": {
"street": "123 Main Street",
"zip": "10115",
"city": "Berlin",
"country": "DE"
}
}
GraphQL schema evolution:
type Customer {
id: ID!
name: String!
address: String @deprecated(reason: "Use addressObject instead")
addressObject: Address
}
type Address {
street: String!
zip: String!
city: String!
country: String!
}
With GraphQL, the client can gradually migrate from address to addressObject without changing the API version in the path. With REST, the client must upgrade from v1 to v2.
FAQ: API Versioning
1. What is API versioning?
2. How are REST APIs most commonly versioned?
/v1/customers, while header versioning passes the version through an HTTP header.3. How does versioning work in GraphQL?
@deprecated. Clients control when they switch to new fields.4. How do you version gRPC APIs?
5. What is semantic versioning?
6. What is schema evolution?
7. What does deprecation mean?
8. What’s the difference between backward-compatible and breaking changes?
9. What is content negotiation?
Accept: application/vnd.shop.v2+json. It’s flexible but more complex than URI versioning.10. How do you communicate the end of an API version?
11. What is the Sunset header?
12. Should you always support many API versions simultaneously?
13. How does versioning affect caching?
14. What is API governance in the context of versioning?
15. Which versioning model is best?
Continue Your API Learning Path
The next article in the API learning path covers Idempotency in API Design: Webhooks and Practical Examples — why idempotent operations are essential for building reliable APIs.
References
- https://www.rfc-editor.org/rfc/rfc9110
- https://graphql.org/learn/best-practices/
- https://protobuf.dev/programming-guides/proto3/
Recommended Reading for API Development
If you want to explore API versioning, API design, and software architecture further, we recommend the following books:
API Development
Books about API design, REST, GraphQL, OpenAPI and API architecture
Designing Data-Intensive Applications von Martin Kleppmann
Bei Amazon ansehenAffiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.
API Design Patterns von JJ Geewax
Bei Amazon ansehenAffiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.




