Fortrip

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; | null means the field can be null. On catalogue facts null means not known, never no. Elsewhere it has its own meaning: nextCursor is null on the last page, payment.url when there is no link to pay now, and payment.credentialLimits when a token can't pay the order.
  • [] marks the items of a list, and "when kind" or "when type" 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 | null

other branches can be added

destinationwhen kind: "place"
destination.placeobject
destination.place.placeIdstring
destination.place.namestring
destination.place.namesobject
destination.place.names.enstring | null
destination.place.names.zhstring | null
destination.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 | null
destination.place.populationinteger | null
destination.place.regionobject | null
destination.place.region.placeIdstring
destination.place.region.namestring
destination.place.region.namesobject
destination.place.region.names.enstring | null
destination.place.region.names.zhstring | null
destination.place.countryCodestring
destination.place.locationobject
destination.place.location.latnumber
destination.place.location.lngnumber
destination.resolution"only_match" | "dominant" | "by_id" | "by_country_code" | "by_locality"

or any other string: values can be added

destination.otherMatchesinteger
destination.scope"area" | "radius" | "locality"

or any other string: values can be added

destination.centerobject
destination.center.locationobject
destination.center.location.latnumber
destination.center.location.lngnumber
destination.center.placeobject | null
destination.center.place.placeIdstring
destination.center.place.namestring
destination.center.place.namesobject
destination.center.place.names.enstring | null
destination.center.place.names.zhstring | null
destination.center.basis"seat" | "capital" | "busiest_settlement" | "hub" | "point"

or any other string: values can be added

destination.radiusMetersnumber | null
destination.radiusSource"default" | "requested" | null

or any other string: values can be added

destinationwhen kind: "point"
destination.centerobject
destination.center.locationobject
destination.center.location.latnumber
destination.center.location.lngnumber
destination.center.placeobject | null
destination.center.place.placeIdstring
destination.center.place.namestring
destination.center.place.namesobject
destination.center.place.names.enstring | null
destination.center.place.names.zhstring | null
destination.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.radiusMetersnumber
destination.radiusSource"default" | "requested"

or any other string: values can be added

textobject | null
text.valuestring
text.match"exact"

or any other string: values can be added

stayobject | null
stay.checkInstring
stay.checkOutstring
stay.roomsobject[]
stay.rooms[].adultsinteger
stay.rooms[].childrenAgesinteger[]
pricingobject
pricing.mode"indicative" | "none"

or any other string: values can be added

pricing.scope"page" | "pool" | null

or any other string: values can be added

pricing.status"ok" | "unavailable" | null

or any other string: values can be added

sort"distance" | "relevance" | "stars_desc" | "price_asc" | "price_desc"

or any other string: values can be added

coverageobject
coverage.matchedinteger
coverage.pricedinteger | null
coverage.withPriceinteger | null
coverage.poolRadiusMetersnumber | null
coverage.excludedNoPriceinteger | null
coverage.excludedNoFacilityDatainteger | null
coverage.withinMaxRadiusinteger | null
coverage.textAnywhereinteger | null
coverage.localitiesobject | null
coverage.localities.itemsobject[]
coverage.localities.items[].placeobject
coverage.localities.items[].place.placeIdstring
coverage.localities.items[].place.namestring
coverage.localities.items[].place.namesobject
coverage.localities.items[].place.names.enstring | null
coverage.localities.items[].place.names.zhstring | null
coverage.localities.items[].countinteger
coverage.localities.items[].totalinteger
coverage.localities.items[].includesobject[]
coverage.localities.items[].includes[].placeobject
coverage.localities.items[].includes[].place.placeIdstring
coverage.localities.items[].includes[].place.namestring
coverage.localities.items[].includes[].place.namesobject
coverage.localities.items[].includes[].place.names.enstring | null
coverage.localities.items[].includes[].place.names.zhstring | null
coverage.localities.items[].includes[].membersinteger
coverage.localities.unassignedinteger
coverage.localities.moreinteger
coverage.nameAsTextinteger | null
dataobject[]
data[].hotelIdstring
data[].namestring
data[].namesobject
data[].names.enstring | null
data[].names.zhstring | null
data[].starsnumber | null
data[].addressobject
data[].address.lineobject | null
data[].address.line.textstring
data[].address.line.locale"en" | "zh"

or any other string: values can be added

data[].address.countryCodestring | null
data[].address.regionobject | null
data[].address.region.placeIdstring
data[].address.region.namestring
data[].address.region.namesobject
data[].address.region.names.enstring | null
data[].address.region.names.zhstring | null
data[].locationobject | null
data[].location.latnumber
data[].location.lngnumber
data[].timeZonestring | null
data[].distanceMetersnumber | null
data[].priceobject | null
data[].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.fromPerRoomNightobject
data[].price.fromPerRoomNight.amountstring
data[].price.fromPerRoomNight.currencystring
data[].price.fromPerRoomStayobject
data[].price.fromPerRoomStay.amountstring
data[].price.fromPerRoomStay.currencystring
data[].price.approxobject | null
data[].price.approx.fromPerRoomNightobject
data[].price.approx.fromPerRoomNight.amountstring
data[].price.approx.fromPerRoomNight.currencystring
data[].price.approx.fromPerRoomStayobject
data[].price.approx.fromPerRoomStay.amountstring
data[].price.approx.fromPerRoomStay.currencystring
data[].price.approx.rateDatestring
data[].photoobject | null

The cover photo; null when there is none.

data[].photo.urlstring
data[].photo.captionobject | null
data[].photo.caption.textstring
data[].photo.caption.locale"en" | "zh"

or any other string: values can be added

nextCursorstring | null

Pass 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[].messagestring

Hotel

GET /v1/hotels/{hotelId} · get_hotel · fortrip hotels get

hotelIdstring
namestring
namesobject
names.enstring | null
names.zhstring | null
bookableboolean
starsnumber | null
addressobject
address.lineobject | null
address.line.textstring
address.line.locale"en" | "zh"

or any other string: values can be added

address.countryCodestring | null
address.regionobject | null
address.region.placeIdstring
address.region.namestring
address.region.namesobject
address.region.names.enstring | null
address.region.names.zhstring | null
locationobject | null
location.latnumber
location.lngnumber
timeZonestring | null
descriptionobject | null
description.textstring
description.locale"en" | "zh"

or any other string: values can be added

photosobject[] | null

Up to 8 hotel photos, the cover first; null when the catalogue lists none.

photos[].urlstring
photos[].captionobject | null
photos[].caption.textstring
photos[].caption.locale"en" | "zh"

or any other string: values can be added

checkInTimesobject
checkInTimes.fromstring | null
checkInTimes.untilstring | null
checkOutTimesobject
checkOutTimes.fromstring | null
checkOutTimes.untilstring | null
policiesobject
policies.listedboolean
policies.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[].textstring
policies.items[].locale"en" | "zh" | null

or any other string: values can be added

amenitiesobject
amenities.listedboolean
amenities.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[].nameobject
amenities.items[].name.textstring
amenities.items[].name.locale"en" | "zh"

or any other string: values can be added

breakfastServedboolean | null
depositobject
deposit.requiredboolean | null
deposit.amountobject | null
deposit.amount.amountstring
deposit.amount.currencystring
contactobject
contact.phonestring | null
contact.websitestring | null
roomsobjectoptional
rooms.listedboolean
rooms.itemsobject[]
rooms.items[].nameobject
rooms.items[].name.textstring
rooms.items[].name.locale"en" | "zh" | null

or any other string: values can be added

rooms.items[].bedsobject | null
rooms.items[].beds.textstring
rooms.items[].beds.locale"en" | "zh" | null

or any other string: values can be added

rooms.items[].areaSqmobject | null
rooms.items[].areaSqm.minnumber
rooms.items[].areaSqm.maxnumber
rooms.items[].maxOccupancyinteger | null
rooms.items[].window"yes" | "no" | "partial" | null

or any other string: values can be added

Offers result

POST /v1/hotels/offers · get_hotel_offers · fortrip hotels offers

stayobject
stay.checkInstring
stay.checkOutstring
stay.roomsobject[]
stay.rooms[].adultsinteger
stay.rooms[].childrenAgesinteger[]
hotelsobject[]
hotels[].hotelobject
hotels[].hotel.hotelIdstring
hotels[].hotel.namestring
hotels[].hotel.namesobject
hotels[].hotel.names.enstring | null
hotels[].hotel.names.zhstring | null
hotels[].offersobject[]
hotels[].offers[].offerIdstring
hotels[].offers[].type"hotel"

or any other string: values can be added

hotels[].offers[].expiresAtstring
hotels[].offers[].hotelobject
hotels[].offers[].hotel.hotelIdstring
hotels[].offers[].hotel.roomobject
hotels[].offers[].hotel.room.nameobject | null
hotels[].offers[].hotel.room.name.textstring
hotels[].offers[].hotel.room.name.locale"en" | "zh" | null

or any other string: values can be added

hotels[].offers[].hotel.room.bedsobject | null
hotels[].offers[].hotel.room.beds.textstring
hotels[].offers[].hotel.room.beds.locale"en" | "zh" | null

or any other string: values can be added

hotels[].offers[].hotel.room.areaSqmobject | null
hotels[].offers[].hotel.room.areaSqm.minnumber
hotels[].offers[].hotel.room.areaSqm.maxnumber
hotels[].offers[].hotel.room.maxOccupancyinteger | null
hotels[].offers[].hotel.room.window"yes" | "no" | "partial" | null

or any other string: values can be added

hotels[].offers[].hotel.roomCountinteger
hotels[].offers[].hotel.mealsobject
hotels[].offers[].hotel.meals.knownboolean
hotels[].offers[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | null
hotels[].offers[].hotel.meals.unspecifiedMainMealsinteger | null
hotels[].offers[].hotel.meals.allInclusiveboolean | null
hotels[].offers[].hotel.meals.guestsCoveredPerRoominteger | null
hotels[].offers[].hotel.meals.labelobject | null
hotels[].offers[].hotel.meals.label.textstring
hotels[].offers[].hotel.meals.label.locale"en" | "zh" | null

or any other string: values can be added

hotels[].offers[].priceobject
hotels[].offers[].price.totalobject
hotels[].offers[].price.total.amountstring
hotels[].offers[].price.total.currencystring
hotels[].offers[].price.perNightAllRoomsobject
hotels[].offers[].price.perNightAllRooms.amountstring
hotels[].offers[].price.perNightAllRooms.currencystring
hotels[].offers[].price.approxobject | null
hotels[].offers[].price.approx.totalobject
hotels[].offers[].price.approx.total.amountstring
hotels[].offers[].price.approx.total.currencystring
hotels[].offers[].price.approx.perNightAllRoomsobject
hotels[].offers[].price.approx.perNightAllRooms.amountstring
hotels[].offers[].price.approx.perNightAllRooms.currencystring
hotels[].offers[].price.approx.rateDatestring
hotels[].offers[].price.payAtPropertyobject
hotels[].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 | null
hotels[].offers[].price.payAtProperty.items[].label.textstring
hotels[].offers[].price.payAtProperty.items[].label.locale"en" | "zh" | null

or any other string: values can be added

hotels[].offers[].price.payAtProperty.items[].amountobject | null
hotels[].offers[].price.payAtProperty.items[].amount.amountstring
hotels[].offers[].price.payAtProperty.items[].amount.currencystring
hotels[].offers[].price.payAtProperty.items[].mandatoryboolean
hotels[].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[].cancellationobject
hotels[].offers[].cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"

or any other string: values can be added

hotels[].offers[].cancellation.asOfstring
hotels[].offers[].cancellation.freeCancellationEndsAtstring | null
hotels[].offers[].cancellation.penaltiesobject[]
hotels[].offers[].cancellation.penalties[].startsAtstring | null
hotels[].offers[].cancellation.penalties[].amountobject
hotels[].offers[].cancellation.penalties[].amount.amountstring
hotels[].offers[].cancellation.penalties[].amount.currencystring
hotels[].offers[].cancellation.timeZonestring | null
hotels[].offers[].confirmationobject
hotels[].offers[].confirmation.mode"instant" | "on_request" | "unknown"

or any other string: values can be added

hotels[].offers[].confirmation.withinMinutesinteger | null
hotels[].omittedobject
hotels[].omitted.byNationalityinteger
hotels[].omitted.byFiltersinteger
hotels[].omitted.dominatedinteger
hotels[].omitted.unreadableinteger
hotels[].omitted.byLimitinteger
unavailableobject[]
unavailable[].hotelIdstring
unavailable[].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 | null
unavailable[].omitted.byNationalityinteger
unavailable[].omitted.byFiltersinteger
unavailable[].omitted.dominatedinteger
unavailable[].omitted.unreadableinteger
unavailable[].omitted.byLimitinteger

Order

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.

orderIdstring
referencestring
status"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"

or any other string: values can be added

createdAtstring
updatedAtstring
itemsobject[]

other branches can be added

items[]when type: "hotel"
items[].hotelobject
items[].hotel.hotelIdstring | null
items[].hotel.namestring
items[].hotel.namesobject
items[].hotel.names.enstring | null
items[].hotel.names.zhstring | null
items[].hotel.checkInstring
items[].hotel.checkOutstring
items[].hotel.timeZonestring | null
items[].hotel.roomsobject[]
items[].hotel.rooms[].adultsinteger
items[].hotel.rooms[].childrenAgesinteger[]
items[].hotel.roomobject
items[].hotel.room.nameobject | null
items[].hotel.room.name.textstring
items[].hotel.room.name.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.room.bedsobject | null
items[].hotel.room.beds.textstring
items[].hotel.room.beds.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.mealsobject
items[].hotel.meals.knownboolean
items[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | null
items[].hotel.meals.unspecifiedMainMealsinteger | null
items[].hotel.meals.allInclusiveboolean | null
items[].hotel.meals.guestsCoveredPerRoominteger | null
items[].hotel.meals.labelobject | null
items[].hotel.meals.label.textstring
items[].hotel.meals.label.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.cancellationobject
items[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"

or any other string: values can be added

items[].hotel.cancellation.asOfstring
items[].hotel.cancellation.freeCancellationEndsAtstring | null
items[].hotel.cancellation.penaltiesobject[]
items[].hotel.cancellation.penalties[].startsAtstring | null
items[].hotel.cancellation.penalties[].amountobject
items[].hotel.cancellation.penalties[].amount.amountstring
items[].hotel.cancellation.penalties[].amount.currencystring
items[].hotel.cancellation.timeZonestring | null
items[].hotel.payAtPropertyobject
items[].hotel.payAtProperty.disclosure"complete" | "incomplete"

or any other string: values can be added

items[].hotel.payAtProperty.itemsobject[]
items[].hotel.payAtProperty.items[].labelobject | null
items[].hotel.payAtProperty.items[].label.textstring
items[].hotel.payAtProperty.items[].label.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.payAtProperty.items[].amountobject | null
items[].hotel.payAtProperty.items[].amount.amountstring
items[].hotel.payAtProperty.items[].amount.currencystring
items[].hotel.payAtProperty.items[].mandatoryboolean
items[].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 | null
priceobject
price.totalobject
price.total.amountstring
price.total.currencystring
paymentobject
payment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"

or any other string: values can be added

payment.urlstring | null

The 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.requiresSignInboolean
payment.expiresAtstring | null
payment.chargeCurrencystring
payment.localCurrencyAtCheckoutboolean
payment.localChargeobject | null
payment.localCharge.amountstring
payment.localCharge.currencystring
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.

payment.handlers[].idstring
payment.handlers[].typestring
payment.handlers[].versionstring
payment.handlers[].specstring
payment.handlers[].schemastring
payment.handlers[].available_instrumentsobject[]
payment.handlers[].available_instruments[].typestring
payment.handlers[].available_instruments[].configobjectoptional
payment.handlers[].configobject
payment.handlers[].config.environment"livemode" | "testmode"

or any other string: values can be added

payment.handlers[].config.business_profilestring
payment.credentialLimitsobject | null

What the shared payment token for pay_order must allow. null exactly when handlers is [].

payment.credentialLimits.maxAmountinteger

Request the token for at least this amount, in cents; a token that allows less can't pay.

payment.credentialLimits.currencystring

The token's currency, lowercase as Stripe takes it: usd.

payment.credentialLimits.expiresAtstring

Request the token valid until at least this time; the order can't be paid after it.

payment.walletsobject | null

Paying 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.openboolean

Whether pay_order has opened a wallet payment on this order.

payment.wallets.current"wechat_pay" | "alipay" | null

The wallet the payment is on now; null until it is open.or any other string: values can be added

payment.wallets.wechatPayobject | null

The WeChat Pay code and link; null until the payment is open.

payment.wallets.wechatPay.qrDatastring | null

The 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 | null

A 480 px PNG of the same code.

payment.wallets.wechatPay.urlstring

A link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.

payment.wallets.alipayobject | null

The Alipay link; null until the payment is open.

payment.wallets.alipay.urlstring

A link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.

cancelobject

Whether the order can be cancelled now, and for what penalty and refund.

cancel.availableboolean

Whether 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 | null

The penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.

cancel.penalty.amountstring
cancel.penalty.currencystring
cancel.refundobject | null

What a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.

cancel.refund.amountstring
cancel.refund.currencystring
manageUrlstring

Order (cancel)

POST /v1/orders/{orderId}/cancel · cancel_order · fortrip orders cancel

orderIdstring
referencestring
status"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"

or any other string: values can be added

createdAtstring
updatedAtstring
itemsobject[]

other branches can be added

items[]when type: "hotel"
items[].hotelobject
items[].hotel.hotelIdstring | null
items[].hotel.namestring
items[].hotel.namesobject
items[].hotel.names.enstring | null
items[].hotel.names.zhstring | null
items[].hotel.checkInstring
items[].hotel.checkOutstring
items[].hotel.timeZonestring | null
items[].hotel.roomsobject[]
items[].hotel.rooms[].adultsinteger
items[].hotel.rooms[].childrenAgesinteger[]
items[].hotel.roomobject
items[].hotel.room.nameobject | null
items[].hotel.room.name.textstring
items[].hotel.room.name.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.room.bedsobject | null
items[].hotel.room.beds.textstring
items[].hotel.room.beds.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.mealsobject
items[].hotel.meals.knownboolean
items[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | null
items[].hotel.meals.unspecifiedMainMealsinteger | null
items[].hotel.meals.allInclusiveboolean | null
items[].hotel.meals.guestsCoveredPerRoominteger | null
items[].hotel.meals.labelobject | null
items[].hotel.meals.label.textstring
items[].hotel.meals.label.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.cancellationobject
items[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"

or any other string: values can be added

items[].hotel.cancellation.asOfstring
items[].hotel.cancellation.freeCancellationEndsAtstring | null
items[].hotel.cancellation.penaltiesobject[]
items[].hotel.cancellation.penalties[].startsAtstring | null
items[].hotel.cancellation.penalties[].amountobject
items[].hotel.cancellation.penalties[].amount.amountstring
items[].hotel.cancellation.penalties[].amount.currencystring
items[].hotel.cancellation.timeZonestring | null
items[].hotel.payAtPropertyobject
items[].hotel.payAtProperty.disclosure"complete" | "incomplete"

or any other string: values can be added

items[].hotel.payAtProperty.itemsobject[]
items[].hotel.payAtProperty.items[].labelobject | null
items[].hotel.payAtProperty.items[].label.textstring
items[].hotel.payAtProperty.items[].label.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.payAtProperty.items[].amountobject | null
items[].hotel.payAtProperty.items[].amount.amountstring
items[].hotel.payAtProperty.items[].amount.currencystring
items[].hotel.payAtProperty.items[].mandatoryboolean
items[].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 | null
priceobject
price.totalobject
price.total.amountstring
price.total.currencystring
paymentobject
payment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"

or any other string: values can be added

payment.urlstring | null

The 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.requiresSignInboolean
payment.expiresAtstring | null
payment.chargeCurrencystring
payment.localCurrencyAtCheckoutboolean
payment.localChargeobject | null
payment.localCharge.amountstring
payment.localCharge.currencystring
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.

payment.handlers[].idstring
payment.handlers[].typestring
payment.handlers[].versionstring
payment.handlers[].specstring
payment.handlers[].schemastring
payment.handlers[].available_instrumentsobject[]
payment.handlers[].available_instruments[].typestring
payment.handlers[].available_instruments[].configobjectoptional
payment.handlers[].configobject
payment.handlers[].config.environment"livemode" | "testmode"

or any other string: values can be added

payment.handlers[].config.business_profilestring
payment.credentialLimitsobject | null

What the shared payment token for pay_order must allow. null exactly when handlers is [].

payment.credentialLimits.maxAmountinteger

Request the token for at least this amount, in cents; a token that allows less can't pay.

payment.credentialLimits.currencystring

The token's currency, lowercase as Stripe takes it: usd.

payment.credentialLimits.expiresAtstring

Request the token valid until at least this time; the order can't be paid after it.

payment.walletsobject | null

Paying 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.openboolean

Whether pay_order has opened a wallet payment on this order.

payment.wallets.current"wechat_pay" | "alipay" | null

The wallet the payment is on now; null until it is open.or any other string: values can be added

payment.wallets.wechatPayobject | null

The WeChat Pay code and link; null until the payment is open.

payment.wallets.wechatPay.qrDatastring | null

The 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 | null

A 480 px PNG of the same code.

payment.wallets.wechatPay.urlstring

A link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.

payment.wallets.alipayobject | null

The Alipay link; null until the payment is open.

payment.wallets.alipay.urlstring

A link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.

cancelobject

Whether the order can be cancelled now, and for what penalty and refund.

cancel.availableboolean

Whether 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 | null

The penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.

cancel.penalty.amountstring
cancel.penalty.currencystring
cancel.refundobject | null

What a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.

cancel.refund.amountstring
cancel.refund.currencystring
manageUrlstring

Order (pay)

POST /v1/orders/{orderId}/pay · pay_order · fortrip orders pay

orderIdstring
referencestring
status"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"

or any other string: values can be added

createdAtstring
updatedAtstring
itemsobject[]

other branches can be added

items[]when type: "hotel"
items[].hotelobject
items[].hotel.hotelIdstring | null
items[].hotel.namestring
items[].hotel.namesobject
items[].hotel.names.enstring | null
items[].hotel.names.zhstring | null
items[].hotel.checkInstring
items[].hotel.checkOutstring
items[].hotel.timeZonestring | null
items[].hotel.roomsobject[]
items[].hotel.rooms[].adultsinteger
items[].hotel.rooms[].childrenAgesinteger[]
items[].hotel.roomobject
items[].hotel.room.nameobject | null
items[].hotel.room.name.textstring
items[].hotel.room.name.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.room.bedsobject | null
items[].hotel.room.beds.textstring
items[].hotel.room.beds.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.mealsobject
items[].hotel.meals.knownboolean
items[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | null
items[].hotel.meals.unspecifiedMainMealsinteger | null
items[].hotel.meals.allInclusiveboolean | null
items[].hotel.meals.guestsCoveredPerRoominteger | null
items[].hotel.meals.labelobject | null
items[].hotel.meals.label.textstring
items[].hotel.meals.label.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.cancellationobject
items[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"

or any other string: values can be added

items[].hotel.cancellation.asOfstring
items[].hotel.cancellation.freeCancellationEndsAtstring | null
items[].hotel.cancellation.penaltiesobject[]
items[].hotel.cancellation.penalties[].startsAtstring | null
items[].hotel.cancellation.penalties[].amountobject
items[].hotel.cancellation.penalties[].amount.amountstring
items[].hotel.cancellation.penalties[].amount.currencystring
items[].hotel.cancellation.timeZonestring | null
items[].hotel.payAtPropertyobject
items[].hotel.payAtProperty.disclosure"complete" | "incomplete"

or any other string: values can be added

items[].hotel.payAtProperty.itemsobject[]
items[].hotel.payAtProperty.items[].labelobject | null
items[].hotel.payAtProperty.items[].label.textstring
items[].hotel.payAtProperty.items[].label.locale"en" | "zh" | null

or any other string: values can be added

items[].hotel.payAtProperty.items[].amountobject | null
items[].hotel.payAtProperty.items[].amount.amountstring
items[].hotel.payAtProperty.items[].amount.currencystring
items[].hotel.payAtProperty.items[].mandatoryboolean
items[].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 | null
priceobject
price.totalobject
price.total.amountstring
price.total.currencystring
paymentobject
payment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"

or any other string: values can be added

payment.urlstring | null

The 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.requiresSignInboolean
payment.expiresAtstring | null
payment.chargeCurrencystring
payment.localCurrencyAtCheckoutboolean
payment.localChargeobject | null
payment.localCharge.amountstring
payment.localCharge.currencystring
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.

payment.handlers[].idstring
payment.handlers[].typestring
payment.handlers[].versionstring
payment.handlers[].specstring
payment.handlers[].schemastring
payment.handlers[].available_instrumentsobject[]
payment.handlers[].available_instruments[].typestring
payment.handlers[].available_instruments[].configobjectoptional
payment.handlers[].configobject
payment.handlers[].config.environment"livemode" | "testmode"

or any other string: values can be added

payment.handlers[].config.business_profilestring
payment.credentialLimitsobject | null

What the shared payment token for pay_order must allow. null exactly when handlers is [].

payment.credentialLimits.maxAmountinteger

Request the token for at least this amount, in cents; a token that allows less can't pay.

payment.credentialLimits.currencystring

The token's currency, lowercase as Stripe takes it: usd.

payment.credentialLimits.expiresAtstring

Request the token valid until at least this time; the order can't be paid after it.

payment.walletsobject | null

Paying 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.openboolean

Whether pay_order has opened a wallet payment on this order.

payment.wallets.current"wechat_pay" | "alipay" | null

The wallet the payment is on now; null until it is open.or any other string: values can be added

payment.wallets.wechatPayobject | null

The WeChat Pay code and link; null until the payment is open.

payment.wallets.wechatPay.qrDatastring | null

The 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 | null

A 480 px PNG of the same code.

payment.wallets.wechatPay.urlstring

A link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.

payment.wallets.alipayobject | null

The Alipay link; null until the payment is open.

payment.wallets.alipay.urlstring

A link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.

cancelobject

Whether the order can be cancelled now, and for what penalty and refund.

cancel.availableboolean

Whether 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 | null

The penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.

cancel.penalty.amountstring
cancel.penalty.currencystring
cancel.refundobject | null

What a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.

cancel.refund.amountstring
cancel.refund.currencystring
manageUrlstring

Order 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[].orderIdstring
data[].referencestring
data[].status"awaiting_payment" | "expired" | "confirming" | "confirmed" | "failed" | "cancelling" | "cancelled" | "needs_attention"

or any other string: values can be added

data[].createdAtstring
data[].updatedAtstring
data[].itemsobject[]

other branches can be added

data[].items[]when type: "hotel"
data[].items[].hotelobject
data[].items[].hotel.hotelIdstring | null
data[].items[].hotel.namestring
data[].items[].hotel.namesobject
data[].items[].hotel.names.enstring | null
data[].items[].hotel.names.zhstring | null
data[].items[].hotel.checkInstring
data[].items[].hotel.checkOutstring
data[].items[].hotel.timeZonestring | null
data[].items[].hotel.roomsobject[]
data[].items[].hotel.rooms[].adultsinteger
data[].items[].hotel.rooms[].childrenAgesinteger[]
data[].items[].hotel.roomobject
data[].items[].hotel.room.nameobject | null
data[].items[].hotel.room.name.textstring
data[].items[].hotel.room.name.locale"en" | "zh" | null

or any other string: values can be added

data[].items[].hotel.room.bedsobject | null
data[].items[].hotel.room.beds.textstring
data[].items[].hotel.room.beds.locale"en" | "zh" | null

or any other string: values can be added

data[].items[].hotel.mealsobject
data[].items[].hotel.meals.knownboolean
data[].items[].hotel.meals.included("breakfast" | "lunch" | "dinner")[] | null
data[].items[].hotel.meals.unspecifiedMainMealsinteger | null
data[].items[].hotel.meals.allInclusiveboolean | null
data[].items[].hotel.meals.guestsCoveredPerRoominteger | null
data[].items[].hotel.meals.labelobject | null
data[].items[].hotel.meals.label.textstring
data[].items[].hotel.meals.label.locale"en" | "zh" | null

or any other string: values can be added

data[].items[].hotel.cancellationobject
data[].items[].hotel.cancellation.status"free" | "partial_penalty" | "non_refundable" | "unknown"

or any other string: values can be added

data[].items[].hotel.cancellation.asOfstring
data[].items[].hotel.cancellation.freeCancellationEndsAtstring | null
data[].items[].hotel.cancellation.penaltiesobject[]
data[].items[].hotel.cancellation.penalties[].startsAtstring | null
data[].items[].hotel.cancellation.penalties[].amountobject
data[].items[].hotel.cancellation.penalties[].amount.amountstring
data[].items[].hotel.cancellation.penalties[].amount.currencystring
data[].items[].hotel.cancellation.timeZonestring | null
data[].items[].hotel.payAtPropertyobject
data[].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 | null
data[].items[].hotel.payAtProperty.items[].label.textstring
data[].items[].hotel.payAtProperty.items[].label.locale"en" | "zh" | null

or any other string: values can be added

data[].items[].hotel.payAtProperty.items[].amountobject | null
data[].items[].hotel.payAtProperty.items[].amount.amountstring
data[].items[].hotel.payAtProperty.items[].amount.currencystring
data[].items[].hotel.payAtProperty.items[].mandatoryboolean
data[].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 | null
data[].priceobject
data[].price.totalobject
data[].price.total.amountstring
data[].price.total.currencystring
data[].paymentobject
data[].payment.status"unpaid" | "authorized" | "paid" | "released" | "refund_pending" | "refunded"

or any other string: values can be added

data[].payment.urlstring | null

The 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.requiresSignInboolean
data[].payment.expiresAtstring | null
data[].payment.chargeCurrencystring
data[].payment.localCurrencyAtCheckoutboolean
data[].payment.localChargeobject | null
data[].payment.localCharge.amountstring
data[].payment.localCharge.currencystring
data[].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[].idstring
data[].payment.handlers[].typestring
data[].payment.handlers[].versionstring
data[].payment.handlers[].specstring
data[].payment.handlers[].schemastring
data[].payment.handlers[].available_instrumentsobject[]
data[].payment.handlers[].available_instruments[].typestring
data[].payment.handlers[].available_instruments[].configobjectoptional
data[].payment.handlers[].configobject
data[].payment.handlers[].config.environment"livemode" | "testmode"

or any other string: values can be added

data[].payment.handlers[].config.business_profilestring
data[].payment.credentialLimitsobject | null

What the shared payment token for pay_order must allow. null exactly when handlers is [].

data[].payment.credentialLimits.maxAmountinteger

Request the token for at least this amount, in cents; a token that allows less can't pay.

data[].payment.credentialLimits.currencystring

The token's currency, lowercase as Stripe takes it: usd.

data[].payment.credentialLimits.expiresAtstring

Request the token valid until at least this time; the order can't be paid after it.

data[].payment.walletsobject | null

Paying 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.openboolean

Whether pay_order has opened a wallet payment on this order.

data[].payment.wallets.current"wechat_pay" | "alipay" | null

The wallet the payment is on now; null until it is open.or any other string: values can be added

data[].payment.wallets.wechatPayobject | null

The WeChat Pay code and link; null until the payment is open.

data[].payment.wallets.wechatPay.qrDatastring | null

The 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 | null

A 480 px PNG of the same code.

data[].payment.wallets.wechatPay.urlstring

A link, on fortrip.ai, for the user to pay with WeChat Pay; anyone holding it can pay.

data[].payment.wallets.alipayobject | null

The Alipay link; null until the payment is open.

data[].payment.wallets.alipay.urlstring

A link, on fortrip.ai, for the user to pay with Alipay; anyone holding it can pay.

data[].cancelobject

Whether the order can be cancelled now, and for what penalty and refund.

data[].cancel.availableboolean

Whether 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 | null

The penalty if cancelled now, under the accepted terms, in the charge currency; null when not stated.

data[].cancel.penalty.amountstring
data[].cancel.penalty.currencystring
data[].cancel.refundobject | null

What a cancellation now refunds: what was paid less the penalty, in the charge currency; null when not stated.

data[].cancel.refund.amountstring
data[].cancel.refund.currencystring
data[].manageUrlstring
nextCursorstring | null

Pass it back as cursor for the next page; null on the last page.

Account

GET /v1/me · fortrip whoami

userIdstring
emailstring | null
namestring | null

On this page