Versioning
Every endpoint answers on two paths:
POST /api/v1/payments/create versioned, use thisPOST /api/payments/create unversioned, permanently supportedBoth run identical code today.
Use the versioned path. It is the only way to be certain a future change will not reach you. An integration on the unversioned path receives whatever “unversioned” resolves to at the time, which today is v1 and one day may not be.
The unversioned path is a permanent alias, not a deprecation. It will not be removed. Integrations exist that cannot be updated, such as plugins that merchants upgrade on their own schedule or never, and those have to keep working.
Every response tells you which version served it:
X-API-Version: v1GET /api/versions lists what exists and which version your request resolved
to.
What counts as a breaking change
Section titled “What counts as a breaking change”We give notice before breaking changes. That promise only means something if we agree on the word.
Shipped without notice, to the current version:
- a new endpoint
- a new optional request field
- a new response field
- a new enum value clients are expected to tolerate
- a validation rule relaxed to accept more input
- a fix to a response that never matched documented behaviour
- any change with no visible effect on requests or responses
Requires a new version:
- removing or renaming a request or response field
- changing a field’s type or meaning
- changing the status code for an existing outcome
- making an optional field required
- tightening validation so previously accepted input is rejected
- removing an endpoint or changing its path
- changing what happens when a field is omitted
The rule underneath: if an integration that works today would stop working, or behave differently without changing its own code, it is breaking.
