In this section: Stability

Stability

What Miles promises not to change on the MCP server and the Chat API, how a breaking change ships when one must, and the exceptions on record.

The rule

Agents on the other side of an MCP connection cannot be redeployed by Miles. So:

  • A shipped tool's declared parameters are never renamed or removed. A test in Miles' build fails on any field or tool disappearing.
  • A breaking change ships as a new tool name plus a deprecation window on the old one, never an in-place edit of an existing field.
  • A pure addition, a new optional parameter or a new tool, can appear at any time without notice.
  • The resource URI miles://guidance/working-with-miles and the points_question prompt's question argument are never renamed either.

The Chat API

/v1/chat/completions follows the OpenAI request and response shapes. Two things are outside that contract and may change with a changelog entry rather than a deprecation window: the x-miles-budget-* headers, and the miles object on non-streaming responses.

Exceptions on record

On 2026-08-20 the refusal channel changed shape. Every declared parameter schema was untouched, but a refusal (a spent ceiling, a missing scope, a Membership gate) stopped arriving as the tool's ordinary JSON text and started arriving as an isError result with a structured code. A caller that detected a refusal by parsing the tool's text got a plain sentence and a parse error instead. It shipped without a deprecation window because the connected population at the time was two users, and it is recorded here rather than hidden so the promise above stays honest.

On 2026-09-06 the wallet_card that add_card and update_card echo back renamed two keys in place, with no alias: the member's own sign_up_bonus became user_sign_up_bonus, and notes became user_notes. The write parameters kept their names. A caller that read either key off the echo found it missing. The same day, a guarded write against a card with no stored updated_at started answering unguardable_card where it had answered stale_precondition. Neither had a deprecation window, because the only account connected at the time was the founder's own. Both were recorded here late, on 2026-09-11, when an audit found them; the changelog entry has the details.

On 2026-09-21 get_wallet_card renamed the code it refuses an ambiguous card_name with, from multiple_matches to ambiguous_holding, and its row list from matches to holdings. No parameter changed. It was renamed rather than left alone because analyze_keep_cancel already refused the identical situation under the second name, and a client had to learn both to handle one thing. This one does carry a transition: the old list key stays as a copy of the new one, and previous_error carries the old code, both until 2026-12-31. The changelog entry has the details.

Credentials

Every credential Miles mints carries a prefix: miles_sk_ for a personal key, miles_at_ and miles_rt_ for OAuth access and refresh tokens, miles_ac_ for an authorization code. The prefixes are stable and safe to match on.