In this section: Changelog
Changelog
Dated changes to the MCP server and the Chat API that a client could notice, newest first.
An entry marked Breaking changes a field, header or result shape a client may already rely on, so that client's code has to change. Stability lists what Miles promises never to change.
Additions that do not change an existing field (a new optional parameter, a new tool) are not listed individually; the tool reference is generated from the live server and is always current.
2026-09-21
get_wallet_cardrefuses acard_namethat matches two holdings one member holds witherror: "ambiguous_holding"and aholdingslist. That is the code and the keyanalyze_keep_cancelalready answers the same situation with, so one refusal is now handled one way. It used to answermultiple_matcheswithmatches. Both old names ride along until 2026-12-31:matchesstays as a copy ofholdings, andprevious_errorcarriesmultiple_matches. A client that branches onerrorshould readambiguous_holdingand takeholdings[].wallet_idbefore then.multiple_matchesis unchanged onupdate_card,remove_card, the gift card tools and the watchlist, where the rows are not holdings and the retry takes a different argument.A coded refusal now carries
docs, an absolute link to that code's anchor on the new Error codes reference. On a tool result it sits besideerror,messageandfix; over MCP it sits inside theerrorobject understructuredContent.result. Nothing was removed or renamed, the advertised output schema is unchanged, and a refusal whoseerroris a sentence rather than a code carries nodocs. The Chat API's OpenAI-shaped envelope is untouched.
2026-09-19
set_free_night_statusandset_certificate_statustake three new optional fields:note(what a certificate is for or where it is booked, up to 500 characters),earned_onandexpires_on(the member's own dates, read off the issuer).statusis no longer required as long as one of the three is given. Anotecomes back wrapped as untrusted content onget_free_nightsandget_certificates, since the person or an agent may have written it. Anexpiry_basisofmember_suppliedmarks a date the member entered directly, same asfrom_earned_on.
2026-09-17
get_eligibilityanswers the American Express card limit correctly.issuer_status["American Express"].eligibleis true only while both caps have room; it used to be true while either one did, so an account six credit cards over its five card limit read as eligible. Read the newcredit_card_eligibleandcharge_card_eligiblefor the cap a specific card falls under. When acardis named,card_eligibilitynow returnseligible: falsewith the cap sentence inreasonand aportfolio_blockerslist, where it returned "No restrictions found".
2026-09-11
Every card's
image_urlnow carries a?v=query string that changes when the art is redrawn. The path before it is unchanged and still serves the image on its own; a client that trims the query gets the same file with a shorter cache life. Ask Cloudflare for a smaller copy with/cdn-cgi/image/width=W,quality=85,format=auto,onerror=redirectin front of the path, where W is one of 128, 200, 256, 400, 600, 800 or 1200; other option strings are refused.set_credit_usageno longer refuses a free account withsupporter_required. For a free account,get_credit_usage,set_credit_usageandclear_credit_usageleave outtotalsand each row'shistory; a Member's results are unchanged.- MCP#
An agent's
set_credit_usageno longer replaces a credit period the person recorded themselves: that entry comes backskippedwithreason: "member_recorded"and theexistinganswer. Sendoverwrite: trueonly when the person asks to replace it. analyze_keep_cancelvalues a member's credits from the usage they recorded once enough periods are on record, so a verdict can change with no field removed.credit_value_basissays which basis an answer used (recorded,typicalormixed), andbasis: "typical"asks for the previous estimate.analyze_keep_cancelrefuses acard_namethat matches two or more cards in the member's wallet witherror: "ambiguous_holding"and aholdingslist, where it used to analyze the first match. Call it again with oneholdings[].wallet_idaswallet_id;card_nameis optional whenwallet_idis given.
2026-09-10
- MCP#
set_free_night_statusdeclaresstatusas required in its input schema. A call without it was already refused inside the tool; it is now refused by input validation, before the tool runs.
2026-09-09
get_eligibilitycounts American Express credit cards and charge cards against separate caps.issuer_status["American Express"].credit_card_countcounts credit cards only (it counted every open Amex card), the newcharge_card_countcounts charge cards, andnotesreports both counts against their own caps.
2026-09-08
The monthly counter became a monthly budget.
x-miles-quota-limit-monthandx-miles-quota-remaining-monthare replaced byx-miles-budget-percent-usedandx-miles-budget-reset-date, no alias -- see Stability. A spent budget still refuses asinsufficient_quota, withRetry-Afternow the seconds until the reset date rather than a short window.- Chat API#
The daily spend ceiling is one count per account, shared by web chat and the Chat API; each server process used to keep its own. It resets at midnight Pacific instead of rolling over 24 hours.
2026-09-07
- Chat API#
/v1/chat/completionsenforces a daily spend ceiling per account. Past it, a turn is refused429rate_limit_exceededwithRetry-After: 3600. The per-minute window refuses with the same code, so branch onRetry-After; see Rate limits. - Chat API#
GET /v1/modelshas its own rate limit and can refuse429rate_limit_exceededwithRetry-After. - MCP#
When the connection refuses a batch
add_cardpartway (paused, read-only, or over a daily ceiling), the answer is oneisErrorresult carrying the entries that landed,errorandstopped_at_index. Every remaining entry used to come backrejectedas a malformed result. - MCP#
A card date that is not
YYYY-MM-DDis refused with a typederror: "invalid_<field>":date_opened,anniversary_dateandsignup_bonus_received_on, plusreview_by,fee_posts_onandnew_anniversary_dateonupdate_card.update_cardwithproduct_change: trueused to drop a malformed date silently; it is refused now. - OAuth#
A
refresh_tokengrant that sendsscopegets a token pair holding only those scopes, and the narrowing is permanent for that grant.scopeused to be ignored on refresh.
2026-09-06
The
wallet_cardthatadd_cardandupdate_cardecho back carries the member's own values asuser_sign_up_bonusanduser_notes, the spellingget_wallet_cardsalready used;sign_up_bonusandnoteson a card you read are the catalog's. The write parameters keep their names. No alias; Stability records it as an exception to its promise.A card write with
expected_updated_atagainst a card that has no storedupdated_atis refusederror: "unguardable_card", where it used to returnstale_precondition, which a re-read could never clear. Stability records it as an exception to its promise.- MCP#
get_card_inforefuses awallet_idthat is not shaped like one (cc_12) and says to passcard_nameinstead. It used to fall through to a fuzzy catalog match. - MCP#
update_cardis annotateddestructiveHint: true, since it can now clear a field. A client that confirms destructive calls with the person will now confirm this one. - MCP#
get_needs_attentionitems can carry a newkind,status_entitlement: an elite-status entitlement about to expire, with no card attached. It never makeshas_itemstrue on its own. A new scope,
miles:write:reconcile, granted by its own consent toggle, coversset_credit_usage,set_free_night_statusandset_certificate_statusand no other write.miles:writestill covers all three. A token'sscopecan now readmiles:read miles:write:reconcile.
2026-09-04
2026-08-27
- Chat API#
Every response carries
x-ratelimit-limit-requests,x-ratelimit-remaining-requestsandx-ratelimit-reset-requests; a metered account also getsx-miles-quota-limit-monthandx-miles-quota-remaining-month. Nothing new is enforced. - OAuth#
Access tokens, refresh tokens and authorization codes carry the prefixes
miles_at_,miles_rt_andmiles_ac_. Personal keys hadmiles_sk_already.
2026-08-26
- Skills#
/skills/ask-miles.mdpublished; listed on ClawHub the same day.
2026-08-20
Refusals arrive as
isErrorresults withstructuredContent.result.error.code, not as ordinary JSON text. Stability records it as an exception to its promise.
2026-08-18
- MCP#
Gift-card writes (
add_gift_card,update_gift_card,remove_gift_card) exposed; a card number is never echoed back in a result.
2026-08-13
- MCP#
Daily ceilings: 50
knowledge_searchcalls, 500 calls, 100 writes, 1,000 changed rows per user, reset at midnight Pacific.
2026-08-10
- MCP#
Server moved to the MCP specification's 2026-07-28 revision. Both protocol eras are served from the one
/mcpendpoint.