Changelog
What changed for callers of the API, the MCP tools, the CLI and the contract, release by release.
Fortrip's agent API is pre-release. Until general availability, breaking changes may happen. A breaking change ships only in a new major version of the contract, @fortrip/agent-contract, and is announced in the changelog with migration notes. After general availability, v1 will change only additively: new fields, endpoints, enum values and error codes.
The contract, @fortrip/agent-contract, and the CLI, fortrip, share one version number. Each entry lists breaking changes first, then what is new, then how to migrate. The values in an entry are the ones that release had.
4.3.0
Not released yet.
New
- The contract exports more of the values these docs state, so a client can read them instead of copying them:
HTTP_ROUTESandACCOUNT_ROUTES: each endpoint's method and path.routePath()builds a request path from an input.RATE_LIMITS: the requests a token may make per scope and window.ENABLED_REGIONS, from the new entry point@fortrip/agent-contract/regions: the regions a search can be scoped to.PAY_WAYSandPAY_INPUT_WAYS: the ways an order is paid, and the way each field of thepay_orderinput pays by.LIMITSgainstokenPaymentMaxUsd,payMinMinutesLeft(the time that must be left to pay for a token or wallet payment to be offered),payCutoffMinutes(the time left below whichpay_orderrefuses),tokensPerOrder,wechatCodeMinutesandordersPerStay(the orders one stay can have).SUPPLIER_OUTCOME_STATUS: the HTTP status ofsupplier_unavailablefor eachdetails.outcome.SEARCH_RULES,ORDER_HTTP,ME_SCOPES,MCP_SERVER_URL,SKILL_INSTALL_COMMAND,REPOSITORY_URLandDOCS_ORIGIN.
- The API, the MCP tools and the CLI's commands are unchanged.
4.2.0
Released 2026-11-04.
New
- Pay an order with Alipay or WeChat Pay.
pay_order(POST /v1/orders/{orderId}/pay) takesmethod: "alipay_wechat_pay"with the order'stotal. The answer is the order, with a WeChat Pay code and an Alipay link inpayment.wallets. The user pays once, by either. Both charge at once. order.payment.walletsis always sent:{ open, current, wechatPay, alipay }, ornullwhen the order can't be paid this way and no wallet payment is open.wechatPay.qrDataandwechatPay.qrImageUrlarenullwhen there is no live code. A WeChat Pay code lasts 120 minutes.- The text of
book_hotel,get_orderandlist_ordersresults has a consent paragraph for an order that offers the wallets. The contract exports it asWALLET_NEXT_STEPandwalletNextStep. - CLI:
fortrip orders pay <orderId> --wallet --total <total>prints both links, and draws the WeChat Pay code in a wide enough terminal.
Changed
limitPerHotelonget_hotel_offers(POST /v1/hotels/offers) defaults to 10 offers per hotel, up from 5. The maximum is still 20.- An order's
payment.urlis a Fortrip page, for paying and, after payment, for the order's status.
Migration
- Nothing is required. To keep getting 5 offers per hotel, send
limitPerHotel: 5.
4.1.0
Released 2026-11-04.
The schemas keep their shape. Most changes are to the text that agents and users read.
Changed
- Paying by token: use a token only with a tool that can request one from the user's Link wallet; otherwise give
payment.urland never ask for a token. Pay one way only. The charge is in USD. payment_total_changedasks the agent to confirm the order's total, then retry with it and the same token.- Field descriptions are corrected or added:
payment.credentialLimits: the token must allow at leastmaxAmountand stay valid until at leastexpiresAt.payment.handlerslists every reason it can be empty.payment.urldepends onrequiresSignIn.checkOutstates the range: 1 to 15 nights,stay_unsupported(max_nights) beyond 15,invalid_requestpast 30. Validation is the same as in 4.0.0.
- An order awaiting payment says it doesn't need cancelling: it expires unpaid.
- API error messages no longer name MCP tools.
renderToolResultandrenderErrortake an optional surface,"mcp"by default. With"cli", the text names CLI commands and flags instead of tools. The CLI's output uses it.
Migration
- Nothing is required. A 4.0 or 4.1 CLI works with either server.
4.0.0
Released 2026-11-04.
A major release. It removes what was kept for older clients, and makes required what the server always sends.
Breaking changes
payment.handlers[].networkIdis removed.schema,available_instrumentsandconfig { environment, business_profile }are required.payment.handlersis always sent:[]when a token can't pay the order, withpayment.credentialLimitsnull.order.cancelis always sent.- A hotel's
photosand a search hit'sphotoare always sent,nullwhen there are none. - Each error code's
detailsis required where the code defines it.search_too_broad'sdetails.centeris required and may benull.strictErrorEnvelope()is removed. - No token payment over $500, Link's cap per spend request. Such an order has empty
payment.handlers, andpay_orderanswerspayment_method_unavailablebefore anything is charged. Exactly $500 can still be paid by token. - The API takes only an OAuth bearer token as the caller's identity. OAuth authorization-server metadata is served on
mcp.fortrip.aionly. - CLI:
- With
--json, a 429 without Fortrip's error envelope is reported asservice_unavailable, retryable, instead ofrate_limited. The exit code is still 4. - With
--json, a localinvalid_requestalways carriesdetails.issues, empty for an error in the command line itself. - The 1.x and 2.x command names get no rename hints.
- With
New
- The hosted API and MCP server take the 3.5.0 additions: UCP's handler fields, and the token in
payment.instruments.
Migration
- Request the token with
config.business_profilein place ofnetworkId. - Treat an empty
payment.handlersas "no token payment", instead of checking whether the field is present. - Replace
strictErrorEnvelope()withstrictOutput(errorEnvelope). - Update the CLI to 4.0.0. A 3.x CLI can't read the orders this server sends.
3.5.0
Released 2026-11-04.
New
payment.handlers[]gains UCP's handler fields, in UCP's snake case:schema,available_instrumentsandconfig { environment, business_profile }.pay_orderalso takes the token in UCP's Complete Checkout form,payment.instruments. The selected instrument must be astripe_paymentscard with astripe_payment_tokencredential. A card number anywhere in the instruments is refused.sharedPaymentTokenOf(input)returns the token from either form.- Agents are told to request the token with
config.business_profile.
Deprecated
networkId, equal toconfig.business_profile. It is removed in 4.0.0.
The hosted API and MCP server moved from 3.4.0 straight to 4.0.0, so they serve these additions from 4.0.0.
3.4.0
Released 2026-11-03.
New
- Pay an order with a Stripe shared payment token from the user's Link wallet:
pay_order,POST /v1/orders/{orderId}/pay, withsharedPaymentTokenand the order'stotal. The answer is the order,confirming, with its paymentauthorized: the amount is held, and charged once the hotel confirms.- A token pays one order only. Calling again with the same token answers what the first call answered and never charges twice.
- Once
pay_ordersucceeds,payment.urlstops working. A payment that fails leaves the link open.
payment.handlersandpayment.credentialLimits(maxAmountin cents,currency,expiresAt) appear on an order a token can pay: awaiting payment by link, in USD, with at least 15 minutes left to pay. A handler is{ id, type, version, spec, networkId }, and agents request the token with the handler'snetworkId.- New error codes:
payment_total_changed,order_not_payable,payment_in_progress,payment_credential_invalid,payment_declined,payment_action_requiredandpayment_method_unavailable. New rate-limit scope:orders_pay. PAY_NEXT_STEP, the rule for paying by token. It is inpay_order's description, and in the text of results that hold an order a token can pay. It never goes innextStep.- CLI:
fortrip orders pay <orderId> --token <token> --total <total>.
3.3.1
Released 2026-11-03.
Changed
- A stay can be ordered again once its order is confirmed, cancelled or refused by the hotel. A party with none of an open order's guests gets an order of its own.
order_existsnow answers only:- an open order that shares a guest with the request, names compared in any letter case;
- an earlier order that failed at the hotel with its outcome unknown;
- a stay that has had 20 orders.
- Another order of a stay needs a new offer, since an offer is ordered once (
offer_already_ordered). When the new order replaces an unpaid one, the user pays only the new link; the earlier one expires unpaid. - The contract's wording changes to match. No schema change.
3.3.0
Released 2026-10-27.
New
- Cancel an order under its terms:
cancel_order,POST /v1/orders/{orderId}/cancel, withmaximumPenalty. The answer is the order:cancelling, thencancelled. If the hotel refuses, the order isconfirmedagain withcancel.reasonrefused. order.cancel:{ available, reason, penalty, refund }.penaltyandrefundare in the charge currency.reasonis one ofCANCEL_REASONS.- New error codes:
cancellation_changed, when the penalty is now abovemaximumPenalty, andorder_not_cancellable, withdetails.reason. New rate-limit scope:orders_cancel. CANCEL_NEXT_STEP, the consent rule for cancelling. It is incancel_order's description, and ends the text ofget_orderandlist_ordersresults that hold a cancellable order. It never goes innextStep.- CLI:
fortrip orders cancel <orderId> --max-penalty <amount>. Without--max-penaltyit cancels nothing: it prints the order's penalty and exits with code 2.
3.2.0
Released 2026-10-27.
Changed
get_hotel_offersreturns a spread of choices instead of the cheapest few. Up tolimitPerHoteloffers are picked in this order: the cheapest, the cheapest that can be cancelled free, the cheapest with breakfast, the cheapest of each other room, then the rest by price. They are listed cheapest first.- Offers a caller couldn't tell apart collapse into one.
omitted.dominatedcounts them too. - No schema change.
3.1.0
Released 2026-10-26.
New
- Hotel photos, on Fortrip's own URLs. A search hit's
photois the hotel's cover. A hotel'sphotoslists up to 8, cover first, and isnullwhen there are none. - The MCP results of
search_hotels,get_hotelandget_hotel_offersend with a hint on how to present hotels, exported asPRESENTATION_HINT. - The text of a search shows each hotel's cover URL, and the text of a hotel its first 4 photo URLs.
3.0.0
Released 2026-10-25.
The first release of Fortrip API v1. This changelog starts here.
- The HTTP API on
https://api.fortrip.ai: search hotels, read a hotel, get live offers, order an offer, and read and list orders. - The MCP server on
https://mcp.fortrip.ai, with the toolsget_planning_guide,search_hotels,get_hotel,get_hotel_offers,book_hotel,get_orderandlist_orders. - The CLI,
fortrip: hotel and order commands, sign-in, the guide, andfortrip mcp, a local bridge to the MCP server. Text output by default,--jsonfor one line of JSON, and exit codes 0 to 4. - The contract,
@fortrip/agent-contract: the input and output schemas, error codes, limits, the tool and command specs, and the text renderersrenderToolResult,renderErrorandrenderGuide. - Ids are opaque, with the prefixes
htl_,off_andord_.