Response schemas
Each object below is what the HTTP API answers, what an MCP tool returns as structuredContent, and what the CLI prints with --json.
The fields come from the zod schemas in the @fortrip/agent-contract npm package.
Reading the tables
- Every field is present unless marked optional;
| nullmeans the field can benull. On catalogue factsnullmeans not known, never no. Elsewhere it has its own meaning:nextCursorisnullon the last page,payment.urlwhen there is no link to pay now, andpayment.credentialLimitswhen a token can't pay the order. []marks the items of a list, and "whenkind" or "whentype" a branch of a union, with that branch's fields below it.- The schemas are open: objects can gain fields, enums can gain values, and unions can gain branches. Don't fail on what you don't know.
- Field rules shared by every response (ids, money, dates, names) are in Conventions.
Search result
POST /v1/hotels/search · search_hotels · fortrip hotels search
destinationobject | nullother branches can be added
destinationwhen kind: "place"destination.placeobjectdestination.place.placeIdstringdestination.place.namestringdestination.place.namesobjectdestination.place.names.enstring | nulldestination.place.names.zhstring | nulldestination.place.kind"country" | "region" | "district" | "settlement" | "neighbourhood" | "island"or any other string: values can be added
destination.place.scope"area" | "radius"or any other string: values can be added
destination.place.cityLikeboolean | nulldestination.place.populationinteger | nulldestination.place.regionobject | nulldestination.place.region.placeIdstringdestination.place.region.namestringdestination.place.region.namesobjectdestination.place.region.names.enstring | nulldestination.place.region.names.zhstring | nulldestination.place.countryCodestringdestination.place.locationobjectdestination.place.location.latnumberdestination.place.location.lngnumberdestination.resolution"only_match" | "dominant" | "by_id" | "by_country_code" | "by_locality"or any other string: values can be added
destination.otherMatchesintegerdestination.scope"area" | "radius" | "locality"or any other string: values can be added
destination.centerobjectdestination.center.locationobjectdestination.center.location.latnumberdestination.center.location.lngnumberdestination.center.placeobject | nulldestination.center.place.placeIdstringdestination.center.place.namestringdestination.center.place.namesobjectdestination.center.place.names.enstring | nulldestination.center.place.names.zhstring | nulldestination.center.basis"seat" | "capital" | "busiest_settlement" | "hub" | "point"or any other string: values can be added
destination.radiusMetersnumber | nulldestination.radiusSource"default" | "requested" | nullor any other string: values can be added
destinationwhen kind: "point"destination.centerobjectdestination.center.locationobjectdestination.center.location.latnumberdestination.center.location.lngnumberdestination.center.placeobject | nulldestination.center.place.placeIdstringdestination.center.place.namestringdestination.center.place.namesobjectdestination.center.place.names.enstring | nulldestination.center.place.names.zhstring | nulldestination.center.basis"seat" | "capital" | "busiest_settlement" | "hub" | "point"or any other string: values can be added
destination.scope"radius"or any other string: values can be added
destination.radiusMetersnumberdestination.radiusSource"default" | "requested"or any other string: values can be added
textobject | nulltext.valuestringtext.match"exact"or any other string: values can be added
stayobject | nullstay.checkInstringstay.checkOutstringstay.roomsobject[]stay.rooms[].adultsintegerstay.rooms[].childrenAgesinteger[]pricingobjectpricing.mode"indicative" | "none"or any other string: values can be added
pricing.scope"page" | "pool" | nullor any other string: values can be added
pricing.status"ok" | "unavailable" | nullor any other string: values can be added
sort"distance" | "relevance" | "stars_desc" | "price_asc" | "price_desc"or any other string: values can be added
coverageobjectcoverage.matchedintegercoverage.pricedinteger | nullcoverage.withPriceinteger | nullcoverage.poolRadiusMetersnumber | nullcoverage.excludedNoPriceinteger | nullcoverage.excludedNoFacilityDatainteger | nullcoverage.withinMaxRadiusinteger | nullcoverage.textAnywhereinteger | nullcoverage.localitiesobject | nullcoverage.localities.itemsobject[]coverage.localities.items[].placeobjectcoverage.localities.items[].place.placeIdstringcoverage.localities.items[].place.namestringcoverage.localities.items[].place.namesobjectcoverage.localities.items[].place.names.enstring | nullcoverage.localities.items[].place.names.zhstring | nullcoverage.localities.items[].countintegercoverage.localities.items[].totalintegercoverage.localities.items[].includesobject[]coverage.localities.items[].includes[].placeobjectcoverage.localities.items[].includes[].place.placeIdstringcoverage.localities.items[].includes[].place.namestringcoverage.localities.items[].includes[].place.namesobjectcoverage.localities.items[].includes[].place.names.enstring | nullcoverage.localities.items[].includes[].place.names.zhstring | nullcoverage.localities.items[].includes[].membersintegercoverage.localities.unassignedintegercoverage.localities.moreintegercoverage.nameAsTextinteger | nulldataobject[]data[].hotelIdstringdata[].namestringdata[].namesobjectdata[].names.enstring | nulldata[].names.zhstring | nulldata[].starsnumber | nulldata[].addressobjectdata[].address.lineobject | nulldata[].address.line.textstringdata[].address.line.locale"en" | "zh"or any other string: values can be added
data[].address.countryCodestring | nulldata[].address.regionobject | nulldata[].address.region.placeIdstringdata[].address.region.namestringdata[].address.region.namesobjectdata[].address.region.names.enstring | nulldata[].address.region.names.zhstring | nulldata[].locationobject | nulldata[].location.latnumberdata[].location.lngnumberdata[].timeZonestring | nulldata[].distanceMetersnumber | nulldata[].priceobject | nulldata[].price.kind"indicative"or any other string: values can be added
data[].price.basis"lowest_unit"or any other string: values can be added
data[].price.fromPerRoomNightobjectdata[].price.fromPerRoomNight.amountstringdata[].price.fromPerRoomNight.currencystringdata[].price.fromPerRoomStayobjectdata[].price.fromPerRoomStay.amountstringdata[].price.fromPerRoomStay.currencystringdata[].price.approxobject | nulldata[].price.approx.fromPerRoomNightobjectdata[].price.approx.fromPerRoomNight.amountstringdata[].price.approx.fromPerRoomNight.currencystringdata[].price.approx.fromPerRoomStayobjectdata[].price.approx.fromPerRoomStay.amountstringdata[].price.approx.fromPerRoomStay.currencystringdata[].price.approx.rateDatestringdata[].photoobject | nullThe cover photo; null when there is none.
data[].photo.urlstringdata[].photo.captionobject | nulldata[].photo.caption.textstringdata[].photo.caption.locale"en" | "zh"or any other string: values can be added
nextCursorstring | nullPass it back as cursor for the next page; null on the last page.
notesobject[]notes[].code"indicative_prices" | "prices_unavailable" | "pool_limited" | "amenities_listed_only" | "place_resolved_dominant" | "area_absorbed" | "broad_area" | "island_radius" | "area_retired" | "more_outside_radius" | "more_elsewhere" | "few_hotels_in_scope" | "party_split_required" | "no_results" | "locality_available"or any other string: values can be added
notes[].messagestringHotel
GET /v1/hotels/{hotelId} · get_hotel · fortrip hotels get
hotelIdstringnamestringnamesobjectnames.enstring | nullnames.zhstring | nullbookablebooleanstarsnumber | nulladdressobjectaddress.lineobject | nulladdress.line.textstringaddress.line.locale"en" | "zh"or any other string: values can be added
address.countryCodestring | nulladdress.regionobject | nulladdress.region.placeIdstringaddress.region.namestringaddress.region.namesobjectaddress.region.names.enstring | nulladdress.region.names.zhstring | nulllocationobject | nulllocation.latnumberlocation.lngnumbertimeZonestring | nulldescriptionobject | nulldescription.textstringdescription.locale"en" | "zh"or any other string: values can be added
photosobject[] | nullUp to 8 hotel photos, the cover first; null when the catalogue lists none.
photos[].urlstringphotos[].captionobject | nullphotos[].caption.textstringphotos[].caption.locale"en" | "zh"or any other string: values can be added
checkInTimesobjectcheckInTimes.fromstring | nullcheckInTimes.untilstring | nullcheckOutTimesobjectcheckOutTimes.fromstring | nullcheckOutTimes.untilstring | nullpoliciesobjectpolicies.listedbooleanpolicies.itemsobject[]policies.items[].topic"check_in" | "important_notices" | "booking" | "booking_tips" | "check_in_out" | "check_in_tips" | "reception" | "deposit" | "meal" | "extra_bed" | "pets" | "surroundings" | "meetings" | "non_smoking" | "other"or any other string: values can be added
policies.items[].textstringpolicies.items[].locale"en" | "zh" | nullor any other string: values can be added
amenitiesobjectamenities.listedbooleanamenities.itemsobject[]amenities.items[].code"parking" | "wifi" | "laundry" | "restaurant" | "room_service" | "bar" | "non_smoking" | "business_center" | "pool" | "airport_shuttle" | "spa" | "gym" | "accessible" | "ev_charging" | "air_conditioning" | "pets_allowed" | "kitchen" | "other"or any other string: values can be added
amenities.items[].nameobjectamenities.items[].name.textstringamenities.items[].name.locale"en" | "zh"or any other string: values can be added
breakfastServedboolean | nulldepositobjectdeposit.requiredboolean | nulldeposit.amountobject | nulldeposit.amount.amountstringdeposit.amount.currencystringcontactobjectcontact.phonestring | nullcontact.websitestring | nullroomsobjectoptionalrooms.listedbooleanrooms.itemsobject[]rooms.items[].nameobjectrooms.items[].name.textstringrooms.items[].name.locale"en" | "zh" | nullor any other string: values can be added
rooms.items[].bedsobject | nullrooms.items[].beds.textstringrooms.items[].beds.locale"en" | "zh" | nullor any other string: values can be added
rooms.items[].areaSqmobject | nullrooms.items[].areaSqm.minnumberrooms.items[].areaSqm.maxnumberrooms.items[].maxOccupancyinteger | nullrooms.items[].window"yes" | "no" | "partial" | nullor any other string: values can be added
Offers result
POST /v1/hotels/offers · get_hotel_offers · fortrip hotels offers
stayobjectstay.checkInstringstay.checkOutstringstay.roomsobject[]stay.rooms[].adultsintegerstay.rooms[].childrenAgesinteger[]hotelsobject[]hotels[].hotelobjecthotels[].hotel.hotelIdstringhotels[].hotel.namestringhotels[].hotel.namesobjecthotels[].hotel.names.enstring | nullhotels[].hotel.names.zhstring | nullhotels[].offersobject[]hotels[].offers[].offerIdstringhotels[].offers[].type"hotel"or any other string: values can be added
hotels[].offers[].expiresAtstringhotels[].offers[].hotelobjecthotels[].offers[].hotel.hotelIdstringhotels[].offers[].hotel.roomobjecthotels[].offers[].hotel.room.nameobject | nullhotels[].offers[].hotel.room.name.textstringhotels[].offers[].hotel.room.name.locale"en" | "zh" | nullor any other string: values can be added
hotels[].offers[].hotel.room.bedsobject | nullhotels[].offers[].hotel.room.beds.textstringhotels[].offers[].hotel.room.beds.locale"en" | "zh" | nullor any other string: values can be added
hotels[].offers[].hotel.room.areaSqmobject | nullhotels[].offers[].hotel.room.areaSqm.minnumberhotels[].offers[].hotel.room.areaSqm.maxnumberhotels[].offers[].hotel.room.maxOccupancyinteger | nullhotels[].offers[].hotel.room.window"yes" | "no" | "partial" | nullor any other string: values can be added
hotels[].offers[].hotel.roomCountintegerhotels[].offers[].hotel.mealsobjecthotels[].offers[].hotel.meals.knownbooleanhotels[].offers[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | nullhotels[].offers[].hotel.meals.unspecifiedMainMealsinteger | nullhotels[].offers[].hotel.meals.allInclusiveboolean | nullhotels[].offers[].hotel.meals.guestsCoveredPerRoominteger | nullhotels[].offers[].hotel.meals.labelobject | nullhotels[].offers[].hotel.meals.label.textstringhotels[].offers[].hotel.meals.label.locale"en" | "zh" | nullor any other string: values can be added
hotels[].offers[].priceobjecthotels[].offers[].price.totalobjecthotels[].offers[].price.total.amountstringhotels[].offers[].price.total.currencystringhotels[].offers[].price.perNightAllRoomsobjecthotels[].offers[].price.perNightAllRooms.amountstringhotels[].offers[].price.perNightAllRooms.currencystringhotels[].offers[].price.approxobject | nullhotels[].offers[].price.approx.totalobjecthotels[].offers[].price.approx.total.amountstringhotels[].offers[].price.approx.total.currencystringhotels[].offers[].price.approx.perNightAllRoomsobjecthotels[].offers[].price.approx.perNightAllRooms.amountstringhotels[].offers[].price.approx.perNightAllRooms.currencystringhotels[].offers[].price.approx.rateDatestringhotels[].offers[].price.payAtPropertyobjecthotels[].offers[].price.payAtProperty.disclosure"complete" | "incomplete"or any other string: values can be added
hotels[].offers[].price.payAtProperty.itemsobject[]hotels[].offers[].price.payAtProperty.items[].labelobject | nullhotels[].offers[].price.payAtProperty.items[].label.textstringhotels[].offers[].price.payAtProperty.items[].label.locale"en" | "zh" | nullor any other string: values can be added
hotels[].offers[].price.payAtProperty.items[].amountobject | nullhotels[].offers[].price.payAtProperty.items[].amount.amountstringhotels[].offers[].price.payAtProperty.items[].amount.currencystringhotels[].offers[].price.payAtProperty.items[].mandatorybooleanhotels[].offers[].price.payAtProperty.items[].basis"per_stay" | "per_night" | "per_person" | "per_person_per_night" | "unknown"or any other string: values can be added
hotels[].offers[].price.payAtProperty.items[].collectedAt"property" | "unknown"or any other string: values can be added
hotels[].offers[].cancellationobjecthotels[].offers[].cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"or any other string: values can be added
hotels[].offers[].cancellation.asOfstringhotels[].offers[].cancellation.freeCancellationEndsAtstring | nullhotels[].offers[].cancellation.penaltiesobject[]hotels[].offers[].cancellation.penalties[].startsAtstring | nullhotels[].offers[].cancellation.penalties[].amountobjecthotels[].offers[].cancellation.penalties[].amount.amountstringhotels[].offers[].cancellation.penalties[].amount.currencystringhotels[].offers[].cancellation.timeZonestring | nullhotels[].offers[].confirmationobjecthotels[].offers[].confirmation.mode"instant" | "on_request" | "unknown"or any other string: values can be added
hotels[].offers[].confirmation.withinMinutesinteger | nullhotels[].omittedobjecthotels[].omitted.byNationalityintegerhotels[].omitted.byFiltersintegerhotels[].omitted.dominatedintegerhotels[].omitted.unreadableintegerhotels[].omitted.byLimitintegerunavailableobject[]unavailable[].hotelIdstringunavailable[].reason"sold_out" | "no_matching_offers" | "nationality_restricted" | "offers_unreadable" | "not_found" | "supplier_unavailable" | "stay_in_past"or any other string: values can be added
unavailable[].omittedobject | nullunavailable[].omitted.byNationalityintegerunavailable[].omitted.byFiltersintegerunavailable[].omitted.dominatedintegerunavailable[].omitted.unreadableintegerunavailable[].omitted.byLimitintegerOrder
POST /v1/orders · GET /v1/orders/{orderId} · book_hotel · get_order · fortrip hotels book · fortrip orders get
Over MCP the object also carries nextStep: what to show the user and ask before giving them payment.url.
orderIdstringreferencestringstatus"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"or any other string: values can be added
createdAtstringupdatedAtstringitemsobject[]other branches can be added
items[]when type: "hotel"items[].hotelobjectitems[].hotel.hotelIdstring | nullitems[].hotel.namestringitems[].hotel.namesobjectitems[].hotel.names.enstring | nullitems[].hotel.names.zhstring | nullitems[].hotel.checkInstringitems[].hotel.checkOutstringitems[].hotel.timeZonestring | nullitems[].hotel.roomsobject[]items[].hotel.rooms[].adultsintegeritems[].hotel.rooms[].childrenAgesinteger[]items[].hotel.roomobjectitems[].hotel.room.nameobject | nullitems[].hotel.room.name.textstringitems[].hotel.room.name.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.room.bedsobject | nullitems[].hotel.room.beds.textstringitems[].hotel.room.beds.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.mealsobjectitems[].hotel.meals.knownbooleanitems[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | nullitems[].hotel.meals.unspecifiedMainMealsinteger | nullitems[].hotel.meals.allInclusiveboolean | nullitems[].hotel.meals.guestsCoveredPerRoominteger | nullitems[].hotel.meals.labelobject | nullitems[].hotel.meals.label.textstringitems[].hotel.meals.label.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.cancellationobjectitems[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"or any other string: values can be added
items[].hotel.cancellation.asOfstringitems[].hotel.cancellation.freeCancellationEndsAtstring | nullitems[].hotel.cancellation.penaltiesobject[]items[].hotel.cancellation.penalties[].startsAtstring | nullitems[].hotel.cancellation.penalties[].amountobjectitems[].hotel.cancellation.penalties[].amount.amountstringitems[].hotel.cancellation.penalties[].amount.currencystringitems[].hotel.cancellation.timeZonestring | nullitems[].hotel.payAtPropertyobjectitems[].hotel.payAtProperty.disclosure"complete" | "incomplete"or any other string: values can be added
items[].hotel.payAtProperty.itemsobject[]items[].hotel.payAtProperty.items[].labelobject | nullitems[].hotel.payAtProperty.items[].label.textstringitems[].hotel.payAtProperty.items[].label.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.payAtProperty.items[].amountobject | nullitems[].hotel.payAtProperty.items[].amount.amountstringitems[].hotel.payAtProperty.items[].amount.currencystringitems[].hotel.payAtProperty.items[].mandatorybooleanitems[].hotel.payAtProperty.items[].basis"per_stay" | "per_night" | "per_person" | "per_person_per_night" | "unknown"or any other string: values can be added
items[].hotel.payAtProperty.items[].collectedAt"property" | "unknown"or any other string: values can be added
items[].hotel.confirmationNumberstring | nullpriceobjectprice.totalobjectprice.total.amountstringprice.total.currencystringpaymentobjectpayment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"or any other string: values can be added
payment.urlstring | nullThe payment page, on fortrip.ai. With requiresSignIn false it continues to Stripe Checkout, and anyone holding it can pay; with requiresSignIn true (an order started on the Fortrip website) it continues to the Fortrip booking page, where only the signed-in owner can pay. null when the order isn't awaiting payment, or, while it is, when the link couldn't be read this time: read the order again.
payment.requiresSignInbooleanpayment.expiresAtstring | nullpayment.chargeCurrencystringpayment.localCurrencyAtCheckoutbooleanpayment.localChargeobject | nullpayment.localCharge.amountstringpayment.localCharge.currencystringpayment.handlersobject[]The ways to pay other than url: a com.stripe.payments handler takes a Stripe shared payment token through pay_order. [] when a token can't pay the order: over $500, not charged in USD, an order started on the Fortrip website, a negotiated price, under 15 minutes left, 5 tokens tried, a token payment is under way, or token payment isn't offered for this order.
payment.handlers[].idstringpayment.handlers[].typestringpayment.handlers[].versionstringpayment.handlers[].specstringpayment.handlers[].schemastringpayment.handlers[].available_instrumentsobject[]payment.handlers[].available_instruments[].typestringpayment.handlers[].available_instruments[].configobjectoptionalpayment.handlers[].configobjectpayment.handlers[].config.environment"livemode" | "testmode"or any other string: values can be added
payment.handlers[].config.business_profilestringpayment.credentialLimitsobject | nullWhat the shared payment token for pay_order must allow. null exactly when handlers is [].
payment.credentialLimits.maxAmountintegerRequest the token for at least this amount, in cents; a token that allows less can't pay.
payment.credentialLimits.currencystringThe token's currency, lowercase as Stripe takes it: usd.
payment.credentialLimits.expiresAtstringRequest the token valid until at least this time; the order can't be paid after it.
payment.walletsobject | nullPaying with Alipay or WeChat Pay: pass method alipay_wechat_pay to pay_order to open it. null when the order can't be paid this way and none is open.
payment.wallets.openbooleanWhether pay_order has opened a wallet payment on this order.
payment.wallets.current"wechat_pay" | "alipay" | nullThe wallet the payment is on now; null until it is open.or any other string: values can be added
payment.wallets.wechatPayobject | nullThe WeChat Pay code and link; null until the payment is open.
payment.wallets.wechatPay.qrDatastring | nullThe WeChat Pay code's content, to draw as a QR code; null when there is no live code (open wechatPay.url for one).
payment.wallets.wechatPay.qrImageUrlstring | nullA 480 px PNG of the same code.
payment.wallets.wechatPay.urlstringA link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.
payment.wallets.alipayobject | nullThe Alipay link; null until the payment is open.
payment.wallets.alipay.urlstringA link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.
cancelobjectWhether the order can be cancelled now, and for what penalty and refund.
cancel.availablebooleanWhether the user can cancel the order now.
cancel.reason"cancellable" | "already_cancelled" | "in_progress" | "not_confirmed" | "stay_started" | "non_refundable" | "refused" | "terms_unknown" | "needs_attention"cancellable when it can be cancelled now; otherwise why not.or any other string: values can be added
cancel.penaltyobject | nullThe penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.
cancel.penalty.amountstringcancel.penalty.currencystringcancel.refundobject | nullWhat a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.
cancel.refund.amountstringcancel.refund.currencystringmanageUrlstringOrder (cancel)
POST /v1/orders/{orderId}/cancel · cancel_order · fortrip orders cancel
orderIdstringreferencestringstatus"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"or any other string: values can be added
createdAtstringupdatedAtstringitemsobject[]other branches can be added
items[]when type: "hotel"items[].hotelobjectitems[].hotel.hotelIdstring | nullitems[].hotel.namestringitems[].hotel.namesobjectitems[].hotel.names.enstring | nullitems[].hotel.names.zhstring | nullitems[].hotel.checkInstringitems[].hotel.checkOutstringitems[].hotel.timeZonestring | nullitems[].hotel.roomsobject[]items[].hotel.rooms[].adultsintegeritems[].hotel.rooms[].childrenAgesinteger[]items[].hotel.roomobjectitems[].hotel.room.nameobject | nullitems[].hotel.room.name.textstringitems[].hotel.room.name.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.room.bedsobject | nullitems[].hotel.room.beds.textstringitems[].hotel.room.beds.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.mealsobjectitems[].hotel.meals.knownbooleanitems[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | nullitems[].hotel.meals.unspecifiedMainMealsinteger | nullitems[].hotel.meals.allInclusiveboolean | nullitems[].hotel.meals.guestsCoveredPerRoominteger | nullitems[].hotel.meals.labelobject | nullitems[].hotel.meals.label.textstringitems[].hotel.meals.label.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.cancellationobjectitems[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"or any other string: values can be added
items[].hotel.cancellation.asOfstringitems[].hotel.cancellation.freeCancellationEndsAtstring | nullitems[].hotel.cancellation.penaltiesobject[]items[].hotel.cancellation.penalties[].startsAtstring | nullitems[].hotel.cancellation.penalties[].amountobjectitems[].hotel.cancellation.penalties[].amount.amountstringitems[].hotel.cancellation.penalties[].amount.currencystringitems[].hotel.cancellation.timeZonestring | nullitems[].hotel.payAtPropertyobjectitems[].hotel.payAtProperty.disclosure"complete" | "incomplete"or any other string: values can be added
items[].hotel.payAtProperty.itemsobject[]items[].hotel.payAtProperty.items[].labelobject | nullitems[].hotel.payAtProperty.items[].label.textstringitems[].hotel.payAtProperty.items[].label.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.payAtProperty.items[].amountobject | nullitems[].hotel.payAtProperty.items[].amount.amountstringitems[].hotel.payAtProperty.items[].amount.currencystringitems[].hotel.payAtProperty.items[].mandatorybooleanitems[].hotel.payAtProperty.items[].basis"per_stay" | "per_night" | "per_person" | "per_person_per_night" | "unknown"or any other string: values can be added
items[].hotel.payAtProperty.items[].collectedAt"property" | "unknown"or any other string: values can be added
items[].hotel.confirmationNumberstring | nullpriceobjectprice.totalobjectprice.total.amountstringprice.total.currencystringpaymentobjectpayment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"or any other string: values can be added
payment.urlstring | nullThe payment page, on fortrip.ai. With requiresSignIn false it continues to Stripe Checkout, and anyone holding it can pay; with requiresSignIn true (an order started on the Fortrip website) it continues to the Fortrip booking page, where only the signed-in owner can pay. null when the order isn't awaiting payment, or, while it is, when the link couldn't be read this time: read the order again.
payment.requiresSignInbooleanpayment.expiresAtstring | nullpayment.chargeCurrencystringpayment.localCurrencyAtCheckoutbooleanpayment.localChargeobject | nullpayment.localCharge.amountstringpayment.localCharge.currencystringpayment.handlersobject[]The ways to pay other than url: a com.stripe.payments handler takes a Stripe shared payment token through pay_order. [] when a token can't pay the order: over $500, not charged in USD, an order started on the Fortrip website, a negotiated price, under 15 minutes left, 5 tokens tried, a token payment is under way, or token payment isn't offered for this order.
payment.handlers[].idstringpayment.handlers[].typestringpayment.handlers[].versionstringpayment.handlers[].specstringpayment.handlers[].schemastringpayment.handlers[].available_instrumentsobject[]payment.handlers[].available_instruments[].typestringpayment.handlers[].available_instruments[].configobjectoptionalpayment.handlers[].configobjectpayment.handlers[].config.environment"livemode" | "testmode"or any other string: values can be added
payment.handlers[].config.business_profilestringpayment.credentialLimitsobject | nullWhat the shared payment token for pay_order must allow. null exactly when handlers is [].
payment.credentialLimits.maxAmountintegerRequest the token for at least this amount, in cents; a token that allows less can't pay.
payment.credentialLimits.currencystringThe token's currency, lowercase as Stripe takes it: usd.
payment.credentialLimits.expiresAtstringRequest the token valid until at least this time; the order can't be paid after it.
payment.walletsobject | nullPaying with Alipay or WeChat Pay: pass method alipay_wechat_pay to pay_order to open it. null when the order can't be paid this way and none is open.
payment.wallets.openbooleanWhether pay_order has opened a wallet payment on this order.
payment.wallets.current"wechat_pay" | "alipay" | nullThe wallet the payment is on now; null until it is open.or any other string: values can be added
payment.wallets.wechatPayobject | nullThe WeChat Pay code and link; null until the payment is open.
payment.wallets.wechatPay.qrDatastring | nullThe WeChat Pay code's content, to draw as a QR code; null when there is no live code (open wechatPay.url for one).
payment.wallets.wechatPay.qrImageUrlstring | nullA 480 px PNG of the same code.
payment.wallets.wechatPay.urlstringA link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.
payment.wallets.alipayobject | nullThe Alipay link; null until the payment is open.
payment.wallets.alipay.urlstringA link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.
cancelobjectWhether the order can be cancelled now, and for what penalty and refund.
cancel.availablebooleanWhether the user can cancel the order now.
cancel.reason"cancellable" | "already_cancelled" | "in_progress" | "not_confirmed" | "stay_started" | "non_refundable" | "refused" | "terms_unknown" | "needs_attention"cancellable when it can be cancelled now; otherwise why not.or any other string: values can be added
cancel.penaltyobject | nullThe penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.
cancel.penalty.amountstringcancel.penalty.currencystringcancel.refundobject | nullWhat a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.
cancel.refund.amountstringcancel.refund.currencystringmanageUrlstringOrder (pay)
POST /v1/orders/{orderId}/pay · pay_order · fortrip orders pay
orderIdstringreferencestringstatus"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"or any other string: values can be added
createdAtstringupdatedAtstringitemsobject[]other branches can be added
items[]when type: "hotel"items[].hotelobjectitems[].hotel.hotelIdstring | nullitems[].hotel.namestringitems[].hotel.namesobjectitems[].hotel.names.enstring | nullitems[].hotel.names.zhstring | nullitems[].hotel.checkInstringitems[].hotel.checkOutstringitems[].hotel.timeZonestring | nullitems[].hotel.roomsobject[]items[].hotel.rooms[].adultsintegeritems[].hotel.rooms[].childrenAgesinteger[]items[].hotel.roomobjectitems[].hotel.room.nameobject | nullitems[].hotel.room.name.textstringitems[].hotel.room.name.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.room.bedsobject | nullitems[].hotel.room.beds.textstringitems[].hotel.room.beds.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.mealsobjectitems[].hotel.meals.knownbooleanitems[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | nullitems[].hotel.meals.unspecifiedMainMealsinteger | nullitems[].hotel.meals.allInclusiveboolean | nullitems[].hotel.meals.guestsCoveredPerRoominteger | nullitems[].hotel.meals.labelobject | nullitems[].hotel.meals.label.textstringitems[].hotel.meals.label.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.cancellationobjectitems[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"or any other string: values can be added
items[].hotel.cancellation.asOfstringitems[].hotel.cancellation.freeCancellationEndsAtstring | nullitems[].hotel.cancellation.penaltiesobject[]items[].hotel.cancellation.penalties[].startsAtstring | nullitems[].hotel.cancellation.penalties[].amountobjectitems[].hotel.cancellation.penalties[].amount.amountstringitems[].hotel.cancellation.penalties[].amount.currencystringitems[].hotel.cancellation.timeZonestring | nullitems[].hotel.payAtPropertyobjectitems[].hotel.payAtProperty.disclosure"complete" | "incomplete"or any other string: values can be added
items[].hotel.payAtProperty.itemsobject[]items[].hotel.payAtProperty.items[].labelobject | nullitems[].hotel.payAtProperty.items[].label.textstringitems[].hotel.payAtProperty.items[].label.locale"en" | "zh" | nullor any other string: values can be added
items[].hotel.payAtProperty.items[].amountobject | nullitems[].hotel.payAtProperty.items[].amount.amountstringitems[].hotel.payAtProperty.items[].amount.currencystringitems[].hotel.payAtProperty.items[].mandatorybooleanitems[].hotel.payAtProperty.items[].basis"per_stay" | "per_night" | "per_person" | "per_person_per_night" | "unknown"or any other string: values can be added
items[].hotel.payAtProperty.items[].collectedAt"property" | "unknown"or any other string: values can be added
items[].hotel.confirmationNumberstring | nullpriceobjectprice.totalobjectprice.total.amountstringprice.total.currencystringpaymentobjectpayment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"or any other string: values can be added
payment.urlstring | nullThe payment page, on fortrip.ai. With requiresSignIn false it continues to Stripe Checkout, and anyone holding it can pay; with requiresSignIn true (an order started on the Fortrip website) it continues to the Fortrip booking page, where only the signed-in owner can pay. null when the order isn't awaiting payment, or, while it is, when the link couldn't be read this time: read the order again.
payment.requiresSignInbooleanpayment.expiresAtstring | nullpayment.chargeCurrencystringpayment.localCurrencyAtCheckoutbooleanpayment.localChargeobject | nullpayment.localCharge.amountstringpayment.localCharge.currencystringpayment.handlersobject[]The ways to pay other than url: a com.stripe.payments handler takes a Stripe shared payment token through pay_order. [] when a token can't pay the order: over $500, not charged in USD, an order started on the Fortrip website, a negotiated price, under 15 minutes left, 5 tokens tried, a token payment is under way, or token payment isn't offered for this order.
payment.handlers[].idstringpayment.handlers[].typestringpayment.handlers[].versionstringpayment.handlers[].specstringpayment.handlers[].schemastringpayment.handlers[].available_instrumentsobject[]payment.handlers[].available_instruments[].typestringpayment.handlers[].available_instruments[].configobjectoptionalpayment.handlers[].configobjectpayment.handlers[].config.environment"livemode" | "testmode"or any other string: values can be added
payment.handlers[].config.business_profilestringpayment.credentialLimitsobject | nullWhat the shared payment token for pay_order must allow. null exactly when handlers is [].
payment.credentialLimits.maxAmountintegerRequest the token for at least this amount, in cents; a token that allows less can't pay.
payment.credentialLimits.currencystringThe token's currency, lowercase as Stripe takes it: usd.
payment.credentialLimits.expiresAtstringRequest the token valid until at least this time; the order can't be paid after it.
payment.walletsobject | nullPaying with Alipay or WeChat Pay: pass method alipay_wechat_pay to pay_order to open it. null when the order can't be paid this way and none is open.
payment.wallets.openbooleanWhether pay_order has opened a wallet payment on this order.
payment.wallets.current"wechat_pay" | "alipay" | nullThe wallet the payment is on now; null until it is open.or any other string: values can be added
payment.wallets.wechatPayobject | nullThe WeChat Pay code and link; null until the payment is open.
payment.wallets.wechatPay.qrDatastring | nullThe WeChat Pay code's content, to draw as a QR code; null when there is no live code (open wechatPay.url for one).
payment.wallets.wechatPay.qrImageUrlstring | nullA 480 px PNG of the same code.
payment.wallets.wechatPay.urlstringA link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.
payment.wallets.alipayobject | nullThe Alipay link; null until the payment is open.
payment.wallets.alipay.urlstringA link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.
cancelobjectWhether the order can be cancelled now, and for what penalty and refund.
cancel.availablebooleanWhether the user can cancel the order now.
cancel.reason"cancellable" | "already_cancelled" | "in_progress" | "not_confirmed" | "stay_started" | "non_refundable" | "refused" | "terms_unknown" | "needs_attention"cancellable when it can be cancelled now; otherwise why not.or any other string: values can be added
cancel.penaltyobject | nullThe penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.
cancel.penalty.amountstringcancel.penalty.currencystringcancel.refundobject | nullWhat a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.
cancel.refund.amountstringcancel.refund.currencystringmanageUrlstringOrder list
GET /v1/orders · list_orders · fortrip orders list
Over MCP the object also carries nextStep: what to show the user and ask before giving them payment.url.
dataobject[]data[].orderIdstringdata[].referencestringdata[].status"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"or any other string: values can be added
data[].createdAtstringdata[].updatedAtstringdata[].itemsobject[]other branches can be added
data[].items[]when type: "hotel"data[].items[].hotelobjectdata[].items[].hotel.hotelIdstring | nulldata[].items[].hotel.namestringdata[].items[].hotel.namesobjectdata[].items[].hotel.names.enstring | nulldata[].items[].hotel.names.zhstring | nulldata[].items[].hotel.checkInstringdata[].items[].hotel.checkOutstringdata[].items[].hotel.timeZonestring | nulldata[].items[].hotel.roomsobject[]data[].items[].hotel.rooms[].adultsintegerdata[].items[].hotel.rooms[].childrenAgesinteger[]data[].items[].hotel.roomobjectdata[].items[].hotel.room.nameobject | nulldata[].items[].hotel.room.name.textstringdata[].items[].hotel.room.name.locale"en" | "zh" | nullor any other string: values can be added
data[].items[].hotel.room.bedsobject | nulldata[].items[].hotel.room.beds.textstringdata[].items[].hotel.room.beds.locale"en" | "zh" | nullor any other string: values can be added
data[].items[].hotel.mealsobjectdata[].items[].hotel.meals.knownbooleandata[].items[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | nulldata[].items[].hotel.meals.unspecifiedMainMealsinteger | nulldata[].items[].hotel.meals.allInclusiveboolean | nulldata[].items[].hotel.meals.guestsCoveredPerRoominteger | nulldata[].items[].hotel.meals.labelobject | nulldata[].items[].hotel.meals.label.textstringdata[].items[].hotel.meals.label.locale"en" | "zh" | nullor any other string: values can be added
data[].items[].hotel.cancellationobjectdata[].items[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"or any other string: values can be added
data[].items[].hotel.cancellation.asOfstringdata[].items[].hotel.cancellation.freeCancellationEndsAtstring | nulldata[].items[].hotel.cancellation.penaltiesobject[]data[].items[].hotel.cancellation.penalties[].startsAtstring | nulldata[].items[].hotel.cancellation.penalties[].amountobjectdata[].items[].hotel.cancellation.penalties[].amount.amountstringdata[].items[].hotel.cancellation.penalties[].amount.currencystringdata[].items[].hotel.cancellation.timeZonestring | nulldata[].items[].hotel.payAtPropertyobjectdata[].items[].hotel.payAtProperty.disclosure"complete" | "incomplete"or any other string: values can be added
data[].items[].hotel.payAtProperty.itemsobject[]data[].items[].hotel.payAtProperty.items[].labelobject | nulldata[].items[].hotel.payAtProperty.items[].label.textstringdata[].items[].hotel.payAtProperty.items[].label.locale"en" | "zh" | nullor any other string: values can be added
data[].items[].hotel.payAtProperty.items[].amountobject | nulldata[].items[].hotel.payAtProperty.items[].amount.amountstringdata[].items[].hotel.payAtProperty.items[].amount.currencystringdata[].items[].hotel.payAtProperty.items[].mandatorybooleandata[].items[].hotel.payAtProperty.items[].basis"per_stay" | "per_night" | "per_person" | "per_person_per_night" | "unknown"or any other string: values can be added
data[].items[].hotel.payAtProperty.items[].collectedAt"property" | "unknown"or any other string: values can be added
data[].items[].hotel.confirmationNumberstring | nulldata[].priceobjectdata[].price.totalobjectdata[].price.total.amountstringdata[].price.total.currencystringdata[].paymentobjectdata[].payment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"or any other string: values can be added
data[].payment.urlstring | nullThe payment page, on fortrip.ai. With requiresSignIn false it continues to Stripe Checkout, and anyone holding it can pay; with requiresSignIn true (an order started on the Fortrip website) it continues to the Fortrip booking page, where only the signed-in owner can pay. null when the order isn't awaiting payment, or, while it is, when the link couldn't be read this time: read the order again.
data[].payment.requiresSignInbooleandata[].payment.expiresAtstring | nulldata[].payment.chargeCurrencystringdata[].payment.localCurrencyAtCheckoutbooleandata[].payment.localChargeobject | nulldata[].payment.localCharge.amountstringdata[].payment.localCharge.currencystringdata[].payment.handlersobject[]The ways to pay other than url: a com.stripe.payments handler takes a Stripe shared payment token through pay_order. [] when a token can't pay the order: over $500, not charged in USD, an order started on the Fortrip website, a negotiated price, under 15 minutes left, 5 tokens tried, a token payment is under way, or token payment isn't offered for this order.
data[].payment.handlers[].idstringdata[].payment.handlers[].typestringdata[].payment.handlers[].versionstringdata[].payment.handlers[].specstringdata[].payment.handlers[].schemastringdata[].payment.handlers[].available_instrumentsobject[]data[].payment.handlers[].available_instruments[].typestringdata[].payment.handlers[].available_instruments[].configobjectoptionaldata[].payment.handlers[].configobjectdata[].payment.handlers[].config.environment"livemode" | "testmode"or any other string: values can be added
data[].payment.handlers[].config.business_profilestringdata[].payment.credentialLimitsobject | nullWhat the shared payment token for pay_order must allow. null exactly when handlers is [].
data[].payment.credentialLimits.maxAmountintegerRequest the token for at least this amount, in cents; a token that allows less can't pay.
data[].payment.credentialLimits.currencystringThe token's currency, lowercase as Stripe takes it: usd.
data[].payment.credentialLimits.expiresAtstringRequest the token valid until at least this time; the order can't be paid after it.
data[].payment.walletsobject | nullPaying with Alipay or WeChat Pay: pass method alipay_wechat_pay to pay_order to open it. null when the order can't be paid this way and none is open.
data[].payment.wallets.openbooleanWhether pay_order has opened a wallet payment on this order.
data[].payment.wallets.current"wechat_pay" | "alipay" | nullThe wallet the payment is on now; null until it is open.or any other string: values can be added
data[].payment.wallets.wechatPayobject | nullThe WeChat Pay code and link; null until the payment is open.
data[].payment.wallets.wechatPay.qrDatastring | nullThe WeChat Pay code's content, to draw as a QR code; null when there is no live code (open wechatPay.url for one).
data[].payment.wallets.wechatPay.qrImageUrlstring | nullA 480 px PNG of the same code.
data[].payment.wallets.wechatPay.urlstringA link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.
data[].payment.wallets.alipayobject | nullThe Alipay link; null until the payment is open.
data[].payment.wallets.alipay.urlstringA link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.
data[].cancelobjectWhether the order can be cancelled now, and for what penalty and refund.
data[].cancel.availablebooleanWhether the user can cancel the order now.
data[].cancel.reason"cancellable" | "already_cancelled" | "in_progress" | "not_confirmed" | "stay_started" | "non_refundable" | "refused" | "terms_unknown" | "needs_attention"cancellable when it can be cancelled now; otherwise why not.or any other string: values can be added
data[].cancel.penaltyobject | nullThe penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.
data[].cancel.penalty.amountstringdata[].cancel.penalty.currencystringdata[].cancel.refundobject | nullWhat a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.
data[].cancel.refund.amountstringdata[].cancel.refund.currencystringdata[].manageUrlstringnextCursorstring | nullPass it back as cursor for the next page; null on the last page.
Account
GET /v1/me · fortrip whoami
userIdstringemailstring | nullnamestring | null