# API versioning strategy defined

- **Pattern:** `ab-002165` (`saas-api-design.api-consistency.api-versioning-strategy`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002165
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002165)

## Why it matters

Adding versioning after external consumers exist is extremely expensive: every client integration must be migrated simultaneously or you must maintain two incompatible surfaces indefinitely. Without a versioning strategy, the first breaking change — adding a required field, renaming a resource, changing a status code — breaks all callers with no migration path. ISO-25010:2011 maintainability.modifiability and compatibility.interoperability are both undermined: the API cannot evolve without breaking the contract.

## Severity rationale

Medium because the cost is future maintainability debt rather than immediate breakage, but retrofitting versioning once external consumers exist is disruptively expensive.

## Remediation

Add a `/v1/` prefix to all API routes now, before you have external consumers. In Next.js App Router this is a directory move:

```
app/api/v1/users/route.ts
app/api/v1/billing/route.ts
```

Update all same-repo fetch calls to use the versioned paths. Document the versioning scheme in your README: one paragraph naming the strategy (URL versioning), the current version, and what triggers a version bump (breaking changes). When a v2 becomes necessary, serve v1 from the old directory during a documented deprecation window. The cost of adding this prefix now is one rename operation; the cost of adding it later is a coordinated migration across every consumer.

## Detection

- **ID:** `api-versioning-strategy`
- **Severity:** `medium`
- **What to look for:** Count all API routes and check whether at least 1 versioning mechanism is present. Look for: URL-based versioning (`/api/v1/`, `/api/v2/`), header-based versioning (`Accept-Version`, `API-Version` headers), or explicit version documentation. Also check: if versioning exists, is it applied consistently (all routes versioned or none)? For early-stage projects with a single version, check whether there is at least a documented plan (README, comments, or a `/v1/` prefix already in place even if v2 doesn't exist yet).
- **Pass criteria:** Either (a) a versioning scheme is in place and applied consistently (all routes include a version segment or version header handling exists), or (b) the project is clearly in pre-v1 phase with no external consumers (no public API docs, no external integrations) and routes use a `/v1/` prefix indicating awareness.
- **Fail criteria:** No versioning of any kind and no evidence of planning for it; or versioning exists but inconsistently applied (some routes versioned, others not).
- **Skip (N/A) when:** The project has only internal API routes consumed solely by the same-repo frontend (no external API consumers, no published API docs, no webhooks). Signal: no external API documentation, no evidence of third-party consumers, no webhook endpoints.
- **Detail on fail:** Example: `No URL versioning — routes use /api/resource without version prefix; no version header handling found"). Max 500 chars.
- **Remediation:** Add a version prefix to your API routes now, before you have external consumers. The simplest approach is URL versioning: prefix all routes with `/api/v1/`. In Next.js App Router, this means moving route files into `app/api/v1/` subdirectories. This is a low-friction change now but expensive to retrofit once external consumers exist. Document the versioning scheme in your README. When you release breaking changes, increment to `/api/v2/` and maintain v1 for a deprecation window.

---

## External references

- iso-25010 compatibility.interoperability
- iso-25010 maintainability.modifiability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-002165
