Minting a new operating point does not imply a new URL version. A repricing does
not change a selection. A retune does not reprice anyone. Only a breaking change
to the wire contract mints
/v2.
URL versions are major-only
The only version identifiers that ever appear in a path are/v1, /v2, /v3.
A minor or patch number never appears in a URL.
- A breaking change is a major bump and gets a new URL version.
- Patches and minor additions stay at the current URL version. A new
optional response field, a new optional request field with a safe default, a
new operating-point label, a bug fix — all ship at the existing
/vN.
What counts as breaking
The test is the client’s, not ours: a change is breaking if a correct client written against the current contract stops working.Nothing is served unversioned
The version segment is an explicit route. A path outside a known version prefix matches nothing and is rejected before any of our code runs. There is no unversioned route and no implicit “latest”. Clients pin a URL version explicitly, exactly as they pin an operating point.Two rules that keep your client working
These are the client’s side of the bargain. A client that ignores them will break on a change this contract considers non-breaking — and that will be the client’s bug, not a broken promise.1
Ignore response fields you do not recognise
New optional fields ship within
/v1. Strict schema validation that rejects
unknown fields will fail on the next additive change. The first one already
designed is the usage block.2
Do not exhaustively match the gate outcome or its reason
The gate outcome is an open, extensible enum. Today it takes two values —
a select outcome (
gate.engaged: true) and a stand down outcome
(gate.engaged: false) — with the trigger carried in reason
(engage:needle, standdown:high_drift, …).A third outcome, escalate, is planned: it signals that a caller declared a
hard downstream capacity cap and neither a sufficient within-cap selection nor
full pass-through was available. It will arrive additively — a new reason
prefix and/or a new optional field — so a client that tolerates unrecognised
prefixes will not break.A version keeps serving until it is formally deprecated
Standing up/v2 is never, by itself, grounds for switching off /v1.
Formal deprecation requires all of:
- A published deprecation notice naming the version, its replacement, and a sunset date.
- A migration path — what a caller must change, in writing.
- A notice period that has actually elapsed before removal, long enough that a pinned client is not broken by surprise.
This commitment is load-bearing beyond ordinary API courtesy: published work
cites an endpoint and an operating point, and those citations have to stay
re-runnable. Retiring a URL version can invalidate a reproducibility promise
attached to a published result, so it is not a decision that gets made on
convenience.
Changes you should expect at /v1
Additively, within this URL version:
- The
usageblock on the response — the metering receipt. Additive and optional, which is why it does not mint/v2. mode: "shadow"as a third value forbudget.mode.- An escalate gate outcome, as described above.
- New operating-point labels, whenever the engine is retuned or a new engine revision is published.