Change the API without breaking the clients you forgot about
APIs tend to keep their old clients forever. A mobile app someone installed 18 months ago is still calling your endpoints today. A partner integration nobody remembers is a cron job in their cloud, hitting /predict every hour.
ML makes this worse. Retraining changes outputs. Feature additions change inputs. If you don't plan for versioning, your first meaningful model update will break production for every client you didn't know existed.
Put the version in the path: /v1/predict, /v2/predict. Blunt, visible, hard to misuse.
GET /v1/predict
POST /v1/predict
# Later, once v2 is ready, v1 keeps working:
POST /v2/predict
Keep the URL stable; clients send a version header.
GET /predict Accept: application/vnd.myapi.v1+json # Or a custom header: X-API-Version: 2
Not a transport strategy — a rule for when to bump a version number. MAJOR.MINOR.PATCH, usually reported in /metadata and response bodies.
Breaking change. Remove a field, change a type, change an error shape, rename an endpoint. Bump v1 → v2.
Backward-compatible additions. New optional request field, new optional response field, new endpoint. Same URL version, bump 1.2.0 → 1.3.0.
Bug fixes, docs, performance. No observable contract change. 1.2.0 → 1.2.1.
/v1/. Simplest possible choice.Accept:.api_version in /metadata and response bodies?prediction → label in the response a breaking change? Yes. Every client parsing the response is broken. This is the change that gets shipped on a Friday, paged on Monday. Version it.
In your api/main.py and api/api_spec.md:
/v1/FastAPI(title=..., version="1.0.0")api_version and model_version from /metadataapi_spec.md: what counts as breaking, how you'll communicate it, and how long you'll keep old versions running