Versioning by adding a field and never removing one

Four years of an API with no version number in the path, because the rule was that nothing incompatible ships.

what is allowed:
  adding a field to a response
  adding an optional field to a request
  adding a new endpoint
  widening what a field accepts

what is not, ever, without a new resource:
  removing a field
  changing a type
  narrowing what is accepted
  changing the meaning of a value

when a change is genuinely incompatible: a new endpoint
with a new name, and the old one deprecated with a date.

The discipline is cheaper than versioning and it is not free — the response grows, and there are two fields that mean nearly the same thing because the first was wrong. Versioning would have let us delete one; it would also have meant maintaining two code paths for years. Which trade is right depends on how many consumers there are and whether you can talk to them, and with six named integrators we could.