Versioning by media type, and why the URL usually wins

The purist position is that a version belongs in the Accept header because a URL identifies a resource rather than a representation, and the practical position disagrees.

# media type versioning
Accept: application/vnd.shop.v2+json

# URL versioning
GET /api/v2/orders/91204

# what the URL gives you that the header does not:
#   visible in a log, a proxy rule, a crash report, a browser
#   cacheable by anything that keys on the URL
#   testable with curl, without a flag

Both work and the URL wins on operability, which is the axis that matters during an incident. The header approach also interacts badly with caches that do not vary on Accept, which is a class of bug that appears months later at a CDN. The genuinely correct answer is to need versions rarely enough that the mechanism does not matter, which is what an additive-change discipline buys.