There is one version, and it is the path
/v1 is the prefix on the control plane’s REST routes, and it is the whole of
the versioning scheme. A few paths sit outside it, and they carry no version in
their path at all:
/healthz, which is the only tenant route left outside/v1;/mcp, the MCP transport, where the tool list is the contract;/vrx/{runToken}/v1/..., the worker surface a run hands out, whosev1comes after the run token;/.well-known/oauth-protected-resourceand its/mcpvariant.
/v1/runs and /v1/runs/{runId} now.
GET /v1/runs/{runId} also answers to the agentRunId that the old
GET /runs/{agentRunId} took, so a permalink has one route rather than two.
The old /tasks and /runs paths are not served at all: there is no alias and
no redirect, they answer 404. That is a break, and it is one this page can
allow only because it happened before the 2026-09-25 baseline the freeze
policy below protects. Nothing moves that way after that date.
Every route in the published spec has a fingerprint, /healthz included, so a
shape change there is just as visible to you.
Four things follow from the path being the scheme, and each one is a fact
about the running server rather than a plan.
- No version header selects a shape. The server reads no request header
that chooses between API versions, and one you invent is ignored. From a
browser you cannot even send one: the preflight allow list for request
headers is exactly
Authorization,Content-Type,x-phonebase-step-upandIdempotency-Key. - No dated version to pin. There is no
2026-01-01style version to request and no account level pin behind it. - No
Deprecation,SunsetorWarningresponse header. Nothing in a response announces that a shape is on its way out. What you do get back is the rate limit budget (RateLimit-Limit,RateLimit-Remaining,RateLimit-Reset,RateLimit-Policy),Retry-After, andWWW-Authenticate. See Rate limits. - No
deprecatedmarker in the spec. Nothing in the published OpenAPI document is flagged as on its way out.
/v2. The practical consequence is the one worth
stating out loud: you cannot ask for an older shape. When a response shape
changes, it changes for every caller at the same moment.
The OpenAPI document carries an
info.version field. It tracks the package
that generates the document and it is not something you can request, so do
not read it as a compatibility signal. The fingerprints below are the signal.Pin the shape you parse
This is the part to act on, and it works today. Every operation in the published spec has a fingerprint: a digest over the part of that operation your code can break on. Parameters, request body, the set of response status codes and each one’s schema, response header names, security, and thex-phonebase extensions all go in. Prose is excluded at
every level, so rewording a description never moves a digest.
The digests are published as a single file next to the spec:
The MCP tool surface has its own rule
The tool surface an agent drives is frozen from the launch on 2026-09-25 and evolves under a published program from then on. New tools, new optional parameters and new error codes are allowed. Renames and removals are not: a tool keeps its name and gains meaning, and there is notap_v2 family. A
change that would break an existing caller goes through the deprecation
program below first.
Two things make that checkable from the outside. The server reports a tool
surface version in the serverInfo a client reads at connect time, so a
client can tell one published surface from another. And a parameter or field
added after the frozen baseline carries an @since marker you can read in the
tool reference.
Read MCP surface for the
full statement of that contract.
After launch, additive only
This is the policy for/v1 and for the MCP tool surface from the launch on
2026-09-25 onward. Before that date shapes under /v1 changed in ways that
required a caller to change with them, without notice. One example is on the
receipt shape: leaseId and fencingToken were removed from it, because a
read only credential could lift a live lease off the newest receipt and hand
it to one that can act. The surface published on the launch date is the
baseline this policy protects.
Every change after launch falls into one of three tiers, and the tier decides
what has to happen before it ships.
- Additive. A new operation or tool, a new optional parameter, a new response field, a new error code. Allowed at any time with no notice, because a caller that ignores what it does not recognise keeps working. Parse responses that way: ignore fields you do not know.
- Meaning changes, shape does not. A field keeps its name and type and
what it tells you gets stricter. This is declared rather than versioned: the
change is written into the changelog, and on the MCP surface
the tool description carries an
@sincenote. - Breaking. A rename, a removal, a new required parameter, or an optional
field made required. This goes through a deprecation program. The change is
announced in the changelog with the date it takes effect, the
old shape keeps being served for at least one release cycle after the
announcement, and a field on its way out keeps being accepted and returned
during that time rather than refused. On the MCP surface the result carries
a deprecation warning, and the removal ships with a version bump in the
serverInfoa client reads at connect time.
Deprecation header (RFC 9745)
from the day the removal is announced, and a Sunset header
(RFC 8594) carrying the date it stops
being served. Nothing is deprecated today, so no response carries either header
yet, which is what the list at the top of this page says.
The changelog entries for these surfaces are not written from memory. Each
docs publish compares the contract fingerprints and the MCP tool names against
the previous publish and adds a dated entry listing what was added, what
changed shape, what was removed, and what was renamed. A rename is only
reported as one when the change that made it says so; otherwise it shows up as
a removal and an addition, which is what it looks like to your parser.
Two mechanisms back this up on our side. Every /v1 operation, and /healthz
outside it, has a registered set of known readers, and a change that moves an operation’s
fingerprint fails our build until each reader has been re-confirmed against the
new digest. And the fingerprints are published, so you can pin them and see
a shape move in your own pipeline whether or not the notice reached you. That
is why that section comes before this one.
Where to go next
Changelog
What changed, and the rule that decides whether an entry may appear there.
API reference
The two HTTP surfaces and the boundary between them.
Rate limits
The budget headers, and what to do when one runs out.
MCP surface
The tool surface, and the contract that keeps it stable.