Changelog

Version 1.20.0

  • Withdrawn Cancellation Requests on VRBO:

    • When a VRBO guest withdraws a request to cancel and the booking stays live, Host Tools now records it: cancellationRequestedDate is cleared, a cancellationRequestWithdrawn entry is added to the reservation's events, and a reservation.changed webhook is sent. A later request on the same booking sets cancellationRequestedDate again and is sent as before.
    • Host Tools sees the withdrawal when it next reads the booking's details on VRBO, so it can come a little after the guest withdraws.
  • Pet Fees Go to VRBO:

    • While content sync is on, a listing's pet fee now goes to VRBO as VRBO's own pet fee, charged per night (unit PER_DAY) or per stay (PER_STAY), as long as the listing allows pets (policy.petPolicy.allowedPets is Allowed or AllowedOnRequest). A pet fee charged per pet, or on a listing that doesn't allow pets, still isn't sent, and skipped says why. When pets stop being allowed, the pet fee sent before is removed from VRBO.
    • A listing that already has a pet fee sends it to VRBO with its next content update.
    • /api/getListingContentOptions now lists VRBO in the pet fee kind's channels.
    • Importing a VRBO listing brings its pet fee in as a pet fee (kind pet, feeType PET_FEE), so direct booking quotes charge it only for guests with pets.
  • Fees a Channel Can't Take Are No Longer Errors:

    • A fee a channel can't take by its rules (a kind it doesn't have, a per-night fee on Airbnb, a percentage fee on VRBO, a pet fee on Booking.com, and so on) no longer makes a "Fees not sent" error in that channel's contentSyncStatus, nor a type: "error" webhook. Nothing went wrong, and the host couldn't fix it without deleting a fee other channels use.
    • The write's skipped still lists these fees, with why, when the request changes which fees can't be sent, and Host Tools' fee editor marks them on each fee.
    • Each fee from /api/getListing/{listingID} and /api/getListings now has notSentTo: the channels the listing is on that won't be sent it, each with why, as the fee editor marks it. It's returned only when there's one, and worked out on each read, so it follows the listing's channels and pet policy. A write ignores it, so fees can still be sent back as they were read.
    • A fee the channel answered for but didn't keep, and a fee Houfy keeps after it was deleted in Host Tools, are still errors.
  • Listing groups only take your own listings, and turnover codes have a minimum length:

    • /api/addListingGroup now answers 400 when listingIDs names a listing that isn't in this account, and lists those ids in data.listingIDs. Nothing is saved.
    • accessCode must be at least 20 characters, or an empty string to turn the turnover link off. A shorter code is a 400. Codes Host Tools generates are 40 characters.

Version 1.19.0

  • OAuth clients must be trusted before a host sees their consent page:

    • POST /oauth/register now accepts only clients whose redirect_uris all point at a trusted AI assistant's own domain (claude.ai, claude.com, chatgpt.com, openai.com, cursor.com) or at the user's machine (localhost, 127.0.0.1, ::1). Any other redirect is a 400 naming the domain. An app that connects to hosts' accounts from its own domain is registered by Host Tools as an official partner: email [email protected].
    • A client_name containing "Host Tools" is refused unless the client only redirects to the local machine.
    • The consent page refuses a client that is neither trusted nor an official partner, including clients registered before this change: the host sees the refusal on the page, and the API answers unauthorized_client.
    • The consent page tells the host where they will be sent after approving, and shows a logo only for official partners.
  • Accept and Decline VRBO Requests to Book:

    • /api/acceptReservation/{reservationID} and /api/declineReservation/{reservationID} now take a VRBO reservation with status "pending", and do what Accept and Decline do in the VRBO owner app. As on Airbnb, Host Tools then refreshes the reservation from VRBO, so the new status and the reservation webhook follow shortly after the call.
    • To decline on VRBO, give a reason from either list. Host Tools sends VRBO the closest of VRBO's own reasons, or "Other" with the reason's words. With a lower-case reason, messageToGuest goes to the guest with the decline; an upper-case reason sends no message. VRBO leaves the requested dates as they are; block them in Host Tools to close them on every channel.
    • A request VRBO says can no longer be answered (it expired, the guest withdrew it, or it was already answered) is a 409 with VRBO's words. A warning VRBO wants confirmed on vrbo.com first, such as a calendar conflict, is a 400.
    • The accept_booking_request and decline_booking_request MCP tools take VRBO requests the same way.
  • Headless Airbnb Auto-Connect on Large Accounts:

    • After the owner approves on Airbnb, /api/owner-import/auto-connect/airbnb now shows them a Host Tools page that counts their listings as they import, then sends them to your redirect when the import finishes. An account with a few hundred listings used to end on a 504 timeout page instead, so the owner never got back to you, even though the import finished.
    • The redirect and its parameters are unchanged. It now arrives once every listing is in, which can be several minutes later on a large account. If the owner closes the page first, the import still finishes but there's no redirect; the listingGroup.changed webhook still reports the listings joining the group.
  • Publish a Listing to Airbnb:

    • New /api/publishListing/{listingID} publishes a listing that isn't on Airbnb yet as a new Airbnb listing, on one of the user's Airbnb accounts: {"channel": "Airbnb", "accountID": "...", "roomType": "entire_home"}. Host Tools creates it with the listing's name, address, base price, content and photos, and lists it with every date closed. Its dates open once the listing's calendar sync is on. The listing's content sync is turned on, which also pushes its content to its other channels when it was off.
    • The publish is queued, so the endpoint answers 202. /api/getListing/{listingID} and /api/getListings return a new publishing field, which holds the publish while it runs, and the listing then shows up in channels.Airbnb.
    • A new error code, listing.publishFailed, carries Airbnb's reason when it refuses the listing (a type: "error" webhook and /api/getErrors). Host Tools deletes what it created on Airbnb first, so the listing can be published again. It needs the listings:read scope, like the other listing errors.
    • The MCP server has a matching publish_listing tool.
  • Publish a Listing to Booking.com as a New Room:

    • /api/publishListing/{listingID} now takes "channel": "Booking", with the accountID of one of the user's Booking.com accounts, which is one property. Host Tools adds the listing to that property as a new room, with its rooms and beds, maximum guests, room amenities, bathrooms, smoking policy, fees and photos. roomType is the room's type, one of apartment, holiday_home, villa, chalet, bungalow, mobile_home and studio; by default it's the one the listing's property type is, else apartment.
    • The listing must be at the property's address: Booking.com adds a room only there, and a listing elsewhere needs a property of its own, which Host Tools can't create yet. A listing whose map location is more than 100 m from the property's, and whose street address isn't the property's, is refused with a 400 saying how far away it is.
    • The property's own address, name, description, photos, check-in and check-out times, pets and children policies and amenities, which every room of it shares, stay as they are on Booking.com.
    • Booking.com checks the room once its content is in. If a check names the room, Host Tools deletes it, and listing.publishFailed carries Booking.com's reason. A check that the room has no photos waits for them, and Booking.com checks the room again once they're on it. The room has no rate, so it can't be booked until the listing's calendar sync is on.
    • publishing can now have a Booking entry, and the listing then shows up in channels.Booking. The publish can take up to half an hour while Booking.com processes the photos.
  • Publish a Listing to VRBO as a New Property:

    • /api/publishListing/{listingID} now takes "channel": "HomeAway", with the accountID of one of the user's VRBO accounts and a required hostType, private or professional, plus the property's short-term rental registrationNumber where its place requires one. Host Tools creates a property on that account at the listing's address, fills it with the listing's name as its headline, its description, property type, rooms and beds, amenities, photos, house rules, check-in and check-out times, fees and base price, answers VRBO's regulatory questions with hostType and registrationNumber, and takes it live with every date blocked. Its dates open once the listing's calendar sync is on.
    • VRBO lists it at once, with no review, and with its own defaults for booking (instant booking, a Lenient cancellation policy, pay-per-booking). It asks the user for payout details later. The house rules' text and a fee per extra guest go with the listing's next content push.
    • The listing needs a name of 10 to 80 characters, a description, a street address, a city, a postal code, a state in the US, Canada or Australia, a country, a map location, a currency, a base price and a maximum number of guests, and at an address with several units, the unit (apartment) VRBO knows it by. The VRBO account needs a phone number, two-step verification and its business details; without them, the publish fails with listing.publishFailed saying which.
    • VRBO can't delete a property, so one VRBO refuses stays on the user's VRBO account, unseen by guests, and publishing the listing again carries on with it.
    • publishing can now have a HomeAway entry, and the listing then shows up in channels.HomeAway. The MCP publish_listing tool takes the same hostType and registrationNumber.
  • Check-in and Checkout Times on Every Listing:

    • Breaking: /api/setListing/{listingID} now refuses a checkInTime outside 8–23 or a checkOutTime outside 10–23 on every listing, not only one on Airbnb. These are the hours Airbnb takes (it refuses a checkout before 10AM), so a listing keeps times every channel accepts if it's later added to Airbnb. Re-sending a listing's current time is still fine, even one outside these hours: only a time that changes is checked.
    • On a listing on Airbnb, a current check-in time before 8AM no longer refuses the request. A current time outside these hours (one imported from VRBO, say) isn't sent to Airbnb, so its other time still goes.
  • Airbnb Change Requests (Alterations):

    • Reservations now have alterationRequest: the open change request on an Airbnb reservation, with the requested dates, guest counts, who sent it (initiatedBy: guest or host) and the price of the stay if it is accepted: hostPayout, guestPrice and itemized rates, the same way as the reservation's own. It's null when there is none, and on other channels.
    • /api/quoteAlteration/{reservationID} prices a change before it is sent: the booking as it is and as proposed, each with hostPayout, guestPrice and rates, Airbnb's own price next to a totalPrice of yours, and the nights the new dates share with another booking. Nothing goes to the guest. Same body as /api/requestAlteration/{reservationID}.
    • A new request fires a reservation.changed webhook, with a new alterationRequested entry in the reservation's events.
    • When the request closes (accepted, declined, withdrawn or voided), alterationRequest goes back to null and another reservation.changed webhook follows, with an alterationRequestClosed entry in events.
    • Answering a request that Airbnb has already closed is a 409 that says so, and the request is removed from the reservation.
    • /api/acceptAlterationRequest/{reservationID} and /api/declineAlterationRequest/{reservationID} answer a guest's request. Once accepted, the reservation's new dates, guests and payout show shortly after.
    • /api/requestAlteration/{reservationID} asks the guest to accept new dates, guest counts or a new total price on a confirmed reservation. Send only what changes. /api/cancelAlterationRequest/{reservationID} withdraws it.
    • In the MCP: quote_alteration, request_alteration and respond_to_alteration_request.
    • Airbnb only for now. VRBO will come later. Booking.com and Houfy don't let a host change a booking through an API.
  • Cancel a VRBO Reservation:

    • /api/cancelReservation/{reservationID} now cancels a VRBO reservation on VRBO, with a refund to the guest, as the VRBO owner app's "Cancel reservation" does. Call /api/getCancellationOptions/{reservationID} first. For a VRBO reservation it returns what VRBO's form offers right now: the reasons (each a value to send and a label to show, with the refundOptions values VRBO allows for it and VRBO's notes for it), the refundOptions (each with the refundTotal VRBO quotes and its breakdown: booking amount, booking commission, guest service fee, lodging taxes), the bookingAmount and currency, the customReasonLength VRBO requires, and VRBO's warnings. The refunds VRBO offers depend on the reason and on how far off the stay is (100%, 50% and 0% close to or during the stay with some reasons; 100% only months out).
    • Then send one reason as reason with a customReason of the required length, and one of that reason's refundOptions as refundPercentType. refundAmount defaults to the chosen option's refundTotal and is required when it has none. message is a note to VRBO with the cancellation, which VRBO may not show the guest.
    • A reason VRBO doesn't offer, a refund it doesn't allow with that reason, or a customReason of the wrong length is a 400 before anything is sent. When VRBO refuses the cancellation, the answer is a 409 with VRBO's text. As on Airbnb, the reservation's status becomes cancelled and a reservation.changed webhook follows.
    • VRBO counts a cancellation sent this way as the host's, whoever asked for it. When a guest has asked to cancel (cancellationRequestedDate is set), VRBO's own advice, returned in warnings, is to have the guest cancel from their VRBO account, which avoids the host penalties; VRBO has no call to approve or decline a request. Cancelling here with the reason GUEST_NEEDS_TO_CANCEL is the fallback.
    • The MCP server's get_cancellation_options and cancel_reservation do the same.

Version 1.18.0

  • Guest Cancellation Requests on VRBO:

    • When a VRBO guest asks to cancel a booking, the reservation now records it: cancellationRequestedDate on the reservation (in /api/getReservation, /api/getReservations and the webhook document) and a cancellationRequested entry in its events. A reservation.changed webhook is sent when Host Tools first sees the request. If Host Tools first sees a request more than 24 hours after the guest made it, the field and event are still recorded but no webhook is sent for it.
    • The reservation stays accepted until the host approves the request on VRBO; then status becomes cancelled and a reservation.cancelled webhook is sent, as before. The date is set once and isn't cleared if the guest withdraws the request or the host declines it.
  • House Rules No Longer Go to Airbnb:

    • Airbnb's API stopped taking a listing's house rules text in its 2026.06.30 version, which Host Tools now uses. notes.houseRules set through /api/setListing/{listingID} still goes to VRBO and Houfy while content sync is on, but no longer to Airbnb, so the house rules on Airbnb stay as the host last set them there.
    • Importing a listing from Airbnb no longer fills in notes.houseRules or policy.childrenAllowed, as Airbnb no longer returns either.
  • Property Type on VRBO:

    • While a listing's content sync is on, its propertyTypeId now goes to VRBO too, as VRBO's type of the same kind, and only when VRBO has another. A type VRBO has no counterpart for isn't sent, so VRBO keeps its own. A listing that was already syncing sends its type with its next push.
    • VRBO no longer offers a guest house or a hostel, so in /api/getListingContentOptions the guest_house and hostel property types no longer list VRBO in their channels. On a listing on VRBO, /api/setListing/{listingID} now refuses them, unless the listing already has one.
  • Property Type, Rooms, Size and Photos on Houfy:

    • While a listing's content sync is on, its propertyTypeId now goes to Houfy too, as Houfy's type of the same kind, and only when Houfy has another. A type Houfy has no counterpart for isn't sent. A listing that was already syncing sends its type with its next push.
    • bedrooms (when at least 1), bathrooms (a .5 too) and space with spaceUnit (in whole units) now go to Houfy too, each only when Houfy has another. A space of 0 clears the size on Houfy. 0 bedrooms isn't sent, as an import from Houfy stores 0 for a listing whose rooms Houfy doesn't list. A listing that was already syncing sends them with its next push.
    • Houfy takes only the types its listing editor offers for the listing's kind (vacation rental, multi-room listing or boat), so it refuses a hotel on a vacation rental, for example. A type Houfy refuses is named in contentSyncStatus.Houfy.lastError, and the listing's other fields still go.
    • Breaking: a listing on Houfy is now checked for its property type too. /api/setListing/{listingID} refuses a propertyTypeId whose channels in /api/getListingContentOptions leave out Houfy (yurt, for example), unless the listing already has it.
    • Photo changes now go to Houfy too while content sync is on. Houfy ends up with exactly the listing's photos, in its order and with their captions, and the first is the cover. A photo Houfy turns away or can't download is named in contentSyncStatus.Houfy.lastError and sent again on the next push.
  • What /api/setListing/{listingID} Doesn't Refuse, Now Documented:

    • No behavior change. The endpoint now says what happens to a change it doesn't refuse with a 400. While the listing's content sync and messagingEnabled are both on, a change a channel won't be sent (house rules VRBO can't hold, a fee a channel doesn't take, a name Booking.com would refuse) is saved and listed in the answer's skipped with the reason.
    • A value a channel refuses only when it's pushed, such as a text longer than a limit the channel doesn't publish, is saved and answered with 200. The refusal shows up after the push: in contentSyncStatus.<channel>.lastError from /api/getListing/{listingID}, as a type: "error" webhook with the code listing.contentSyncFailed, and in /api/getErrors.
    • skipped[].channel can be Houfy, for a fee Houfy doesn't take. The docs listed only Airbnb, VRBO and Booking.
    • House rules too long for VRBO's 3 rules of 150 characters are listed in skipped when the request changes them, as well as in contentSyncStatus.HomeAway.lastError after the push.
    • The fee limits each channel already had are now listed under "Fees": Airbnb, VRBO and Booking.com take one fee of each kind (a second cleaning fee isn't sent), and VRBO takes at most 6 fees besides cleaning and extra guests, and no fee over 20,000. A fee that isn't sent is listed in skipped when the request changes which fees can't be sent.

Version 1.17.0

  • Content Sync to Houfy:

    • While a listing's content sync is on, its content now goes to Houfy too: name (as the listing name and the headline), notes.description, notes.houseRules, checkInTime, checkOutTime, maxGuests, amenities and fees. "Content sync" on /api/setListing/{listingID} lists what each becomes there, and contentSyncStatus has a Houfy entry.
    • Houfy takes any fee by its name, but not a pet fee, a deposit or an extra-guest fee, which it keeps in its own settings. It can't remove a fee through its API, so one deleted in Host Tools stays on Houfy, and the listing's contentSyncStatus.Houfy.lastError names it until it's removed there.
    • In /api/getListingContentOptions, the amenities, property types and fee kinds Houfy has now list Houfy in their channels. A listing on Houfy is checked against them as against the other channels, for its amenities (not its property type or beds, which Houfy isn't sent: its API doesn't change a property type).
    • Importing a listing from Houfy now brings in only the amenities Houfy marks as present (it used to bring in all of them), reads its "Vacation Home" type as vacation_home, and takes the check-out time from Houfy's check-out time rather than the end of its check-in window.
  • Fees on Booking.com:

    • While a listing's content sync is on, its fees now go to its room on Booking.com as the room's charges, each from today until it changes, as Booking.com's charge of the same kind. A room's charge replaces the property's of the same type for that room, so a fee deleted in Host Tools leaves the room with the property's charge, if it has one.
    • cleaning, management (as Booking.com's service charge), resort, linens, bath_linens, electricity, water, heating, air_conditioning, internet, parking and pool go. A pet fee isn't sent, as Booking.com would charge it to every guest, and neither is a deposit, an extra-guest fee or a fee per guest past a number of guests. Each is named in the listing's contentSyncStatus error.
    • In /api/getListingContentOptions, those feeKinds now list Booking in their channels.
  • Fee Kinds in the Listing Content Options:

    • /api/getListingContentOptions now also returns feeKinds: the kinds a fee takes on /api/setListing/{listingID}, with each one's label and the channels (Airbnb, VRBO) that have it. other is a fee no channel has, so its channels are empty.
  • Airbnb's Other Description Sections:

    • A listing's notes has five new fields, one for each of Airbnb's other description sections: space ("The space"), access ("Guest access"), interaction ("Interaction with guests"), otherNotes ("Other details to note") and transit ("Getting around"). Each is {"texts": [{"language": "en", "value": "..."}]}, like shortDescription.
    • Importing a listing from Airbnb now brings them in, and /api/getListing/{listingID} and /api/getListings return them. A section that's empty on Airbnb is left out.
    • /api/setListing/{listingID} takes them in notes. As for every note, notes replaces all of them, so send these with the others to keep them.
    • While a listing's content sync is on, the English text of each goes to Airbnb's section of the same name. VRBO still gets only notes.description as its description.
  • House Rules on VRBO, Now Documented:

    • While a listing's content sync is on, VRBO already gets these as its house rules, and the content sync table in /api/setListing/{listingID} now lists them: maxGuests as the maximum guests; policy.childrenAllowed, policy.smokingAllowed and policy.petPolicy.allowedPets as whether children, smoking and pets are allowed (pets on request go as allowed); and the English notes.houseRules as its custom rules, at most 3 of up to 150 characters each. House rules too long for that aren't sent, and contentSyncStatus.HomeAway.lastError says why.
    • VRBO's other house rules (events, the minimum age, the children's ages) stay as VRBO has them.

Version 1.16.0

  • Calendar Rules:

    • New endpoints to read and manage a listing's calendar rules: /api/getCalendarRules/{listingID}, /api/createCalendarRule/{listingID}, /api/setCalendarRule/{calendarRuleID}, /api/pauseCalendarRule/{calendarRuleID}, /api/moveCalendarRule/{calendarRuleID} and /api/deleteCalendarRule/{calendarRuleID}. Reading needs the pricing:read scope, the others pricing:write.
    • They take every rule type the Host Tools app offers, including "Same Dates Every Year" (event: "yearlyDates") and "Nth Weekday of a Month" (event: "nthWeekday"), and every option: the gradual scales, grossUpByPercentage, availability, blockCheckin, blockCheckout, months, afterReservationLength and beforeReservationLength.
    • Rules apply from the top of the list down, and a later rule overwrites an earlier one on the same day, minimum nights included. Each rule has a position; a new rule goes to the bottom unless you send one, and Move Calendar Rule moves it.
    • Dates are YYYY-MM-DD on the listing's calendar. A specificDates end date is not included, like a check-out day; a yearlyDates end date is.
    • A rule from a calendar rule group (calendarRuleGroupName set) is shared with every listing in the group, so it can't be changed, paused, moved or deleted through the API.
    • /api/setCalendar/{listingID} now says that its prices only apply to listings whose price source is API; calendar rules apply whatever the price source.
  • Calendar Rules in the MCP:

    • The tools are now get_calendar_rules and create_calendar_rule, plus new update_calendar_rule, pause_calendar_rule, move_calendar_rule and delete_calendar_rule, matching the endpoints above. The old names get_pricing_rules and create_pricing_rule still work.
    • Fixed: rules made with create_pricing_rule never applied, because no weekdays were saved with them. A rule now applies on every day unless limitDays names some. An older rule with no weekdays shows an empty limitDays; editing it gives it every day.
    • Fixed: specificDatesStartDate and specificDatesEndDate were saved a day early for listings in the Americas. They're now read as that day on the listing's calendar, the same as in the app, and returned as YYYY-MM-DD.
    • Fixed: the blocked scale did nothing. A rule created with it is now saved as an availability rule with blocked: true, which blocks the dates. An older blocked rule turns into one when it's edited.
    • get_calendar_rules returns VRBO as VRBO (not HomeAway), weekdays and months as lists, and calendarRuleGroupName in place of priceRuleGroupName.
    • set_prices now says that its prices only apply to listings whose price source is API.
  • Rooms No Longer Have privateBathroom:

    • No channel has a private bathroom per bedroom (Airbnb and VRBO treat a bathroom as a room of its own, and Booking.com has no such setting), and Host Tools never sent it anywhere. It's gone from the listing editor.
    • /api/getListing/{listingID} and /api/getListings no longer return privateBathroom on each room in bedroomConfiguration.bedrooms.
    • /api/setListing/{listingID} no longer requires it on each room. A request that still sends it isn't refused: the value is ignored.
  • Airbnb Rooms Matched by Their Beds:

    • While a listing's content sync is on, each room in bedroomConfiguration now goes to the Airbnb room that already has the same beds, and the others pair in order, as on VRBO. They were matched by position alone, so removing or reordering a room moved beds between Airbnb's rooms, away from the photos and details Airbnb keeps on each.
    • Fixed: when Airbnb had a room without beds before one with beds, such as a living room without a sofa bed before one with, no rooms were sent, nor the fees and photos after them, and contentSyncStatus.Airbnb.lastError asked the host to add beds on Airbnb. That room is now left alone, and a room added in Host Tools fills it instead of going beside it.
  • Rooms, and Photos in Rooms:

    • /api/getListing/{listingID} now returns an id on each bedroom in bedroomConfiguration.bedrooms, and a new rooms list for the listing's other rooms (a living room without beds, bathrooms, kitchen, patio and so on; a living room with beds stays in bedroomConfiguration), each with an id, a typeId and a label. Each photo in photos has a roomID when it's in a bedroom or room.
    • /api/getListingContentOptions has a new roomTypes list: the kinds of room rooms takes, with the channels each goes to.
    • /api/setListing/{listingID} now takes rooms, and an id on each bedroom so a bedroom keeps its photos when the list changes. A bedroom or room sent without an id matches the one at its place in the list; an id the listing doesn't have is refused. When rooms has any bathrooms, bathrooms is set from them (a half bathroom counts as 0.5).
    • /api/setListingPhoto/{listingID}/{photoID} and /api/uploadListingPhoto/{listingID} take a roomID to put the photo in a bedroom or room. null takes it out of its room. A room that's removed takes its photos out with it.
    • While a listing's content sync is on, its rooms and which room each photo is in now go to Airbnb, and which room each photo is in goes to VRBO too, for its bedrooms and bathrooms. A photo the host put in a room on a channel stays there unless Host Tools put it there.
    • Importing a listing from Airbnb now brings in its rooms and photo rooms, a living room without beds among them. When Airbnb's rooms have fewer bathrooms than the listing's bathrooms, the import adds the missing ones to rooms, so the count they set stays the listing's.
    • In the MCP, update_listing takes rooms and bedroom ids, manage_listing_photos takes a roomId on upload and update, and get_listing_content_options lists roomTypes.

Version 1.15.0

  • Holiday Homes and Studios Imported from Booking.com:

    • Importing a listing from Booking.com now brings a holiday home in as propertyTypeId: "vacation_home" (House) and a studio as "studio". Both were left out.
    • In /api/getListingContentOptions, vacation_home and studio now include Booking in their channels. Booking.com still isn't sent a property type, so /api/setListing/{listingID} doesn't check it there.
  • Content Held on a Disabled Listing Goes Once It's Enabled:

    • Fixed: nothing is pushed while a listing is disabled, and enabling it (messagingEnabled: true on /api/setListing/{listingID}) didn't send the content changes saved meanwhile. They waited for a later change to the content. Now they go when the listing is enabled, all of them if content sync was turned on while it was disabled (the push that turning it on sends).
    • Each contentSyncStatus entry has a new waitingFor: listingEnabled while the listing is disabled with content sync on, so a lastPushedAt of null there means the push is waiting, and null otherwise.
  • 14 More Amenities Go to Airbnb:

    • These amenities now go to Airbnb while a listing's content sync is on, and importing a listing from Airbnb now brings them: fire_pit, beach_access, kitchenette, stereo (Airbnb's sound system), safe, billiards (Airbnb's pool table), table_tennis (Airbnb's ping pong table), sauna, miniature_golf and game_room, plus four new ones: outdoor_shower, bidet, mosquito_net and home_theater.
    • In /api/getListingContentOptions they include Airbnb in their channels, so /api/setListing/{listingID} now accepts them on a listing that's only on Airbnb.
    • On a listing whose content sync is already on, each one goes to Airbnb once it changes in Host Tools. Until then, Airbnb keeps what it has, so an amenity the host has on Airbnb that an earlier import didn't bring in isn't removed. Turning content sync on sends them all, like every other amenity.
  • House on Listings on Airbnb and VRBO:

    • /api/setListing/{listingID} now accepts propertyTypeId: "vacation_home" on a listing on both Airbnb and VRBO. Since 1.13.0 it refused it there unless the listing already had it.
    • In /api/getListingContentOptions, vacation_home is now labelled "House", as both channels call it, and its channels include VRBO. Its id doesn't change.
    • /api/getListing/{listingID} and /api/getListings return propertyType: "House" for it, where they returned "Vacation home". A listing whose propertyType is the "house" an import stored now has propertyTypeId: "vacation_home", where it had none.
    • Importing a listing from VRBO now brings a house as its property type. It was left out.
  • Linked Rooms, Price Source and Discounts in the Docs:

    • /api/getListing/{listingID} and /api/getListings now document linkedRoomID, priceSource, priceSourceListingID, weeklyDiscount, monthlyDiscount, nonRefundableDiscount, minPrice and bookingWindow. They were already returned; only the docs were missing.
    • linkedRoomID on /api/setListing/{listingID} now explains which bookings block which listings: a listing and its parent block each other, listings that share a parent don't, and a chain blocks every listing in it.
    • priceSourceListingID now says that a listing keeps following the other listing's base price (not a one-time copy), that its own calendar rules still apply, and when a change reaches it.
    • Each discount now says which channels it goes to while syncPricing is on: weekly and monthly go to Airbnb, VRBO, Booking.com and Houfy, and non-refundable goes to Airbnb and Booking.com only.
  • Room Details, Beds and Amenities Go to Booking.com:

    • While a listing's content sync is on, maxGuests, space with spaceUnit, and policy.smokingAllowed now go to the listing's room on Booking.com. Turning content sync on sends them straight away. A value the room already has on Booking.com isn't sent.
    • contentSyncStatus has a Booking entry for a listing on Booking.com, with the same lastPushedAt and lastError as the other channels. A value Booking.com refuses is named in lastError, and the other fields still go. A room Booking.com no longer sells gets nothing and no error: its changes go once it's listed again.
    • Booking.com keeps how many of the guests may be adults, children and infants beside the maximum. When maxGuests changes, a limit at its usual place moves with it (adults equal to the guests, children and infants one fewer), and one the host set differently stays, lowered only to still fit.
    • bedroomConfiguration goes too: each bedroom and living room with its beds, replacing the room's on Booking.com. On a room type that is a single room (a double, a studio), every bed of the listing goes as the room's beds, and the other bed choices Booking.com offers on it stay. Beds Booking.com has no type for (a couch, a crib, a murphy bed) aren't sent, a room left without beds is left out, and a twin goes as a single bed.
    • So do the amenities Booking.com lists for a room, such as the kitchen, the TV or a washing machine, each ticked or unticked there.
    • In /api/getListingContentOptions, those amenities and twin_bed now include Booking in their channels. /api/setListing/{listingID} checks the amenities and bed types it adds against Booking.com too, like Airbnb and VRBO, but not the property type, which isn't sent there.
    • Importing a listing from Booking.com now brings its room's amenities, not only the property's.
  • Photos Go to Booking.com:

    • While a listing's content sync is on, photo changes made through the photo endpoints (/api/uploadListingPhoto/{listingID} and the others) now also go to the listing's room on Booking.com. The room's photo gallery ends up with exactly the listing's photos, in the listing's order. Turning content sync on sends them straight away.
    • The property's gallery, which every room of the property shows, ends up with the same photos in the same order, and the listing's first photo becomes the property's main photo, the one guests see in search results. On a property with several rooms, the listing whose photos changed last sets them.
    • Booking.com downloads each new photo from its url and takes a few minutes to process it, so the galleries change a few minutes after the change in Host Tools.
    • Nothing is deleted on Booking.com. A photo that leaves a gallery stays on the property, and in any other room's gallery. The property's smart ordering setting isn't changed, so while it's on, Booking.com may show the property's gallery in an order of its own. Captions aren't sent, as Booking.com has none, so changing only a caption sends nothing there.
    • A photo Booking.com can't process is left out and named in contentSyncStatus.Booking.lastError, and the other photos still go. So is each new photo once the property holds Booking.com's limit of 299, and a property whose connection to Host Tools doesn't include Photos gets none.
  • Property Details and Bathrooms Go to Booking.com:

    • While a listing's content sync is on, these now go to its property on Booking.com: name as the property's name, checkInTime (when check-in starts), checkOutTime (when check-out ends), policy.petPolicy.allowedPets, policy.childrenAllowed, notes.description (the English text) as the property's description, and the amenities Booking.com lists for the whole property, such as a garden, an elevator or a hot tub, each ticked or unticked there. Turning content sync on sends them straight away. A value the property already has isn't sent.
    • Every room of a property shares these. On a property with several rooms they end up as the last synced listing's, and a push sends only the ones changed on its own listing, so editing one listing's beds doesn't send its name over another's.
    • A listing imported from Booking.com is named after the property and the room (Casamare - 727764306): the room's id isn't sent as part of the property's name. The room keeps its own name on Booking.com.
    • A name Booking.com would refuse isn't sent: one with fewer than 3 letters, more than 5 digits in a row, emoji or Chinese characters, or fewer than 3 or more than 255 characters. Punctuation and capitals are fine. /api/setListing/{listingID} still saves it and says why in skipped (see below). A name Booking.com refuses for another reason, such as a word it doesn't allow, is named in contentSyncStatus.Booking.lastError while the other fields still go.
    • When check-in ends and check-out starts stay as Booking.com has them, as do the pets' price type and the children's ages.
    • Booking.com says it may rewrite the description or not use it, and takes 3 hours or more to show a change.
    • An amenity of the property's that the listing doesn't have is unticked, for every room. Parking, the internet, a pool, a restaurant and meals need details Host Tools doesn't hold and aren't sent. Booking.com may untick one amenity along with another it depends on, such as a private beach area with the beach.
    • bathrooms goes to the listing's room, in whole bathrooms, as Booking.com has no half bathroom: 2.5 goes as 2. A missing one is added as a private bathroom inside the unit, and the room's own keep their details.
    • The address isn't sent to Booking.com.
  • What Won't Be Sent:

    • /api/setListing/{listingID} now answers with skipped when the request changed something a channel won't be sent, such as a name Booking.com would refuse or a WiFi password without its network name on Airbnb. Each entry is {channel, label, reason}, with the reason in words you can show the user. The change is still saved in Host Tools. update_listing in the MCP returns the same list in its data.

Version 1.14.0

  • OAuth:

    • Your redirect_uri can now redirect again after it receives the code, for example to your app's dashboard. Before, Chrome blocked that second redirect and the user was left on the Approve button. The consent page now sends the browser to your redirect_uri itself, so POST /oauth/authorize returns the URL as {redirectUrl} instead of a 302. Nothing changes for your app: it still gets code and state on its redirect_uri.
  • Airbnb Messages:

    • Fixed: some Airbnb inquiries lost their messages, including the guest's first message, so the reservation's posts came back empty or missing the guest. It happened when Airbnb sent a thread update with no message in it, such as a pre-approval. Messages are no longer removed this way.
  • Reservation Events:

    • Reservations from /api/getReservation/{reservationID}, /api/getReservations/{listingID}, /api/getAllReservations, reservation webhooks and the MCP get_reservation and get_reservations tools now include events: what happened to the reservation and when, oldest first. Each has a type and a createdAt.
    • The first event is created, with the status the reservation had when Host Tools first saw it. statusChanged gives the status from and to, so an Airbnb inquiry that was pre-approved and then expired shows as inquiry to preapproved, then preapproved to timedout. The other types are checkInChanged, checkOutChanged, guestsChanged, petsChanged and listingChanged (each with from and to), and guestReviewed, hostReviewed, doorUnlocked, lockCodeAdded, lockCodeRemoved and paymentReceived. The API reference describes each one.
    • Events are recorded on every channel, Airbnb, VRBO, Booking.com and Houfy, and on direct and internal reservations, whenever Host Tools sees the change. More types may be added, so ignore any you don't know.
  • Listing Fees and Taxes:

    • /api/getListing/{listingID} and /api/getListings now return the listing's fees and taxes, and /api/setListing/{listingID} takes them. Each replaces the whole list, and null removes it.
    • A fee has a name, a kind (what the fee is, such as cleaning or linens), a feeType (GENERAL, PET_FEE or DEPOSIT), a unit (how often it's charged), a value and a valueType (FLAT, or PERCENT of the stay on a PER_STAY fee). It can also have a taxType and an option, the guests included before a per-guest fee is charged. A tax has a name, a type (SalesTaxIncluded or SalesTaxExcluded) and a value, a percentage. A fee or tax that breaks one of the rules in the API reference returns 400 and saves nothing.
    • Fees imported from Airbnb keep Airbnb's names, such as "Cleaning fee".
    • A fee's kind decides which channel fee it goes as (see below). Send back the kind getListing returned to keep it: a fee written without one gets the kind Host Tools works out from its feeType, unit and name.
    • Host Tools uses them for direct booking quotes and the Google Vacation Rentals feed. While content sync is on, fees also go to Airbnb and VRBO (see below). Taxes aren't sent to channels: Airbnb, VRBO and Booking.com each manage their own.
    • The MCP get_listing and list_listings tools return them and update_listing takes them. A change to them sends a listing.changed webhook.
  • Breaking: All Airbnb Content Waits for Content Sync:

    • Changed: every listing field /api/setListing/{listingID} sends to Airbnb now goes only while the listing's content sync is on (contentSyncEnabled), as VRBO already did. That adds the title, guest capacity, property type, bedroom, bathroom and bed counts, amenities, check-in method and instructions, and check-in and checkout times. Before, those went to Airbnb with content sync off too.
    • With content sync off, no listing content (fields, photos or fees) is sent to Airbnb or VRBO. Prices and availability still follow their own sync settings. Turning it on sends every one of these fields straight away, so Airbnb matches Host Tools from then on.
    • The MCP update_listing tool works the same way.
  • Signed Webhooks:

    • Every webhook request now has an X-HostTools-Signature header, so you can check it came from Host Tools and wasn't changed on the way. It looks like t=1760000000,v1=5257a8...: t is when it was signed (Unix seconds) and v1 is an HMAC-SHA256 of <t>.<raw request body>, keyed with the webhook's secret, in hex.
    • Each webhook URL has its own secret, starting with whsec_. /api/setWebhook and /api/getWebhook now return it as secret. Webhooks set before this change get a secret the first time you call getWebhook (or when the next webhook is sent), so call getWebhook once to read it.
    • Setting the webhook again keeps the same secret, even with a new URL. Send rotateSecret: true to /api/setWebhook to get a new one; the old one stops working straight away.
    • Checking the signature is optional, and an endpoint that ignores the header keeps working. See "Verifying Webhook Signatures" in the webhook docs for a Node.js example. Reject a request whose t is more than 5 minutes old, and compare signatures in constant time.

Version 1.13.0

  • Listing Fees Go to Airbnb and VRBO:

    • While a listing's content sync is on, its fees now go to Airbnb and VRBO. Each goes as the channel's fee of the same kind (cleaning, linens, pet and so on). The kind is picked for each fee in Host Tools' listing editor, so a fee's name doesn't decide where it goes and renaming it changes nothing on a channel. Turning content sync on sends them straight away.
    • A fee kind the listing has is set on the channel, one it had and then deleted is removed there, and a fee the channel has that the listing never had is left as it is.
    • A fee a channel can't take is named in contentSyncStatus.<channel>.lastError: a kind the channel doesn't have, a per-night fee on Airbnb, a percentage, pet fee or deposit on VRBO.
    • Taxes aren't sent to channels.
  • Connected Accounts:

    • New /api/getAccounts and /api/getAccount/{accountID} (scope accounts:read) return the user's connected channel and smart-lock accounts: the channel type, whether Host Tools can still use the channel login (connected, with lastConnectedAt and lastDisconnectedAt), when reservations and Seam locks were last synced (reservationsSyncedAt, locksSyncedAt), any sync failure the account is stuck on (syncErrors.reservations, syncErrors.reservationDetails, syncErrors.verification, each {message, failedAt} like a listing's contentSyncStatus.lastError), and the channel's own ID for the account as id, like channels.<channel>.id on a listing under the same capitalized channel names as channels on a listing (Airbnb.id, the Airbnb host ID, with Airbnb.fullAccess; Booking.id, the Booking.com property ID; Houfy.id; Seam.id with Seam.provider; VRBO gives VRBO.username instead). No passwords, tokens or other credentials. These are the same details the MCP list_accounts and get_account tools return, whose sortBy values are now lastConnectedAt and lastDisconnectedAt.
    • /api/getListing/{listingID}, /api/getListings, listing webhooks and the MCP get_listing and list_listings tools now include accountID next to id under each channel in channels, naming the account the listing comes from. Moving a listing to another account sends a listing.changed webhook.
    • Accounts aren't part of listing groups. To find the accounts behind a group, read its listingIDs and the accountID on each of those listings.
  • Get All Reservations (the backstop for missed webhooks):

    • New /api/getAllReservations (scope reservations:read) returns the reservations, across all of the user's listings, that changed at or after updatedSince (an ISO 8601 date-time, e.g. 2026-10-07T20:00:00Z, required). If your server was down or a webhook didn't arrive, call it to catch up on what changed in the meantime.
    • Reservations come in the same shape as /api/getReservations/{listingID}, from the same listings (disabled listings included, hidden and deleted ones not), oldest change first.
    • It pages: up to limit reservations per call (1 to 200, default 100). Pass the returned nextCursor as cursor, with the same updatedSince, until nextCursor is null. A page can be shorter than limit even when more remain.
    • To poll, save the time just before your first call, minus a minute for clock differences, page until nextCursor is null, and pass the saved time as updatedSince next time.
    • Reservations that are deleted, or whose status changes to one this call doesn't return (for example denied), drop out of the results rather than being reported.
    • The MCP get_reservations tool takes the same optional updatedSince, and can sort by updatedAt. It returns at most 200 results with no paging, so use /api/getAllReservations for a full catch-up.
  • Cancel Airbnb Reservations (Airbnb only for now):

    • /api/cancelReservation/{reservationID} now also cancels Airbnb reservations, on Airbnb. Before, it only cancelled internal and direct reservations. Booking.com and VRBO reservations still have to be cancelled on the channel and return 400.
    • Airbnb needs a reason. New /api/getCancellationOptions/{reservationID} (scope reservations:read) returns the reasons Airbnb accepts for that reservation right now and the host's penaltyAmount (in the listing's currency, left out when Airbnb quotes none). Send one reason (and its subReason, when it has one) exactly as listed. Airbnb shortens the list as check-in gets closer, so read it just before cancelling; a reason that is no longer on it returns 400.
    • A reason marked messageToGuestRequired needs a messageToGuest of 30 to 240 characters, which Airbnb sends the guest. messageToAirbnb is an optional private note to Airbnb.
    • Internal and direct reservations still need no body, and getCancellationOptions returns an empty reasons list for them.
    • Changed: a reservation whose stay has already ended can no longer be cancelled, on any source. It returns 400, the same rule as the Host Tools app.
    • The MCP server has get_cancellation_options, and cancel_reservation takes the same reason, subReason, messageToGuest and messageToAirbnb.
  • Channel Price Adjustments (account settings in the API):

    • /api/getUser now returns channelPriceAdjustments: the percentage by which the price Host Tools sends to each channel (Airbnb, VRBO, Booking, Houfy, direct) is raised, so you net your configured price after the channel's fee, or lowered when negative. Only channels with an adjustment are listed. It's the same setting as Channel Settings in the app and applies to every listing on the account.
    • New /api/setUser (scope user:write, new) changes account settings and returns the user as /api/getUser does. Send channelPriceAdjustments with only the channels to change: a number between -100 and 100 (exclusive) sets a channel, null (or 0) clears it, and an omitted channel keeps its value. An unknown key, channel or value returns 400 and saves nothing. A change re-sends prices to every listing on the account.
    • The MCP get_user tool returns channelPriceAdjustments and the new update_user tool changes them.
  • Breaking: Set Listing Refuses Values the Listing's Channels Don't Support (Airbnb and VRBO):

    • /api/setListing/{listingID} now returns 400 when it would add an amenity or bed type that none of the listing's channels supports, or a property type that one of them doesn't support. Before, the value was saved and those channels just didn't get it. The error names each value and the channels that don't support it, for example Amenity "HAC6043" is not supported on Airbnb or VRBO. or Property type "aparthotel" is not supported on VRBO.
    • An amenity or bed type one of the listing's channels supports is accepted, and each channel is only sent the ones it supports.
    • Only Airbnb and VRBO are checked, because those are the channels Host Tools sends listing content to. Booking.com will be checked once Host Tools sends content there.
    • A value the listing already has is always accepted, so writing back what /api/getListing/{listingID} returned still works.
    • To avoid the error, use amenities and bed types from /api/getListingContentOptions whose channels include at least one channel the listing is on, and a property type whose channels include every channel the listing is on.
    • The MCP update_listing tool follows the same rule.
  • Breaking: Set Listing Replaces Newly Listed VRBO Amenities:

    • 64 amenities VRBO supports that were missing from the options are added (see below). Before, a listing's amenity outside the options was hidden from /api/getListing/{listingID} and kept on every /api/setListing/{listingID}. These 64 are now returned and replaced like any other amenity, so a write that leaves one out removes it from the listing.
    • Read the listing with /api/getListing/{listingID} before sending a full amenities list, so you don't drop amenities a VRBO import added.
  • More Accurate Listing Content Options:

    • Each option's channels in /api/getListingContentOptions now says which channels Host Tools sends it to and reads it from. Amenities VRBO supports are now tagged VRBO.
    • 64 amenities VRBO supports that were missing are added, such as outdoor_pool, safe, ocean_view and kayaking. /api/getListing/{listingID} now returns them when a listing has them.
    • Amenities that were listed once per channel are now one option. The old ids still work in /api/setListing/{listingID}, also when sent beside the id they were merged into, and save as the merged option: electric_car_charging_stations is now ev_charger, board_games_puzzles is board_games, indoor_swimming_pool_all_year and indoor_swimming_pool_seasonal are indoor_pool, outdoor_swimming_pool_all_year and outdoor_swimming_pool_seasonal are outdoor_pool, swimming_pool is pool, fitness_room is gym, outdoor_furniture is outdoor_seating, sun_loungers_or_beach_chairs is sun_loungers, baby_safety_gates is stair_gates, garden is garden_or_backyard, ski_to_door_access is ski_in_ski_out, and accessible_parking is disabled_parking_spot.
    • What listings have saved doesn't change. /api/getListing/{listingID} returns the merged id for a listing that has one of the old ones, and Airbnb and VRBO now also receive an amenity a listing has under an old id (for example from a Booking.com import).
  • What Happened in Reservation Webhooks:

    • Reservation webhooks (type: "reservation") now have an event field next to type and document, the same as listing and review webhooks: reservation.created for a new reservation, reservation.cancelled when it is cancelled, and reservation.changed for anything else (new dates, a different number of guests, another status change).
    • A reservation Host Tools first learns of after it was already cancelled arrives as reservation.cancelled, so event always agrees with document.status.
    • Each change is its own webhook, so a cancel is never folded into a reservation.changed. document is still the reservation as it is when the webhook is sent.
    • Nothing else in the payload changed, so code that ignores event keeps working.
  • Amenities Are Now Called amenities:

    • /api/getListing/{listingID}, /api/getListings and listing webhooks now return a listing's amenities as amenities. Each one has the id that /api/setListing/{listingID} takes, its label from /api/getListingContentOptions and a quantity.
    • /api/setListing/{listingID} now takes amenities, a list of {id, quantity}. As before, it replaces the whole list and null clears it. label is read-only, so leave it out.
    • attributesWithQuantity is now deprecated but still works the same way, for reading and writing, so existing integrations don't need to change. A request that sends both amenities and attributesWithQuantity returns 400.
    • The MCP get_listing, list_listings and update_listing tools use the same names.

Version 1.12.0

  • Listing Photos Go to VRBO:

    • While a listing's content sync is on, photo changes made through the photo endpoints (/api/uploadListingPhoto/{listingID} and the others) now also go to VRBO: new photos, deleted photos, the order (the first is the cover) and captions. VRBO ends up with exactly the listing's photos, as Airbnb does.
    • Turning content sync on sends the listing's photos to VRBO straight away, and VRBO's photos that Host Tools doesn't have are deleted.
    • VRBO needs at least 6 photos. While the listing has fewer, VRBO's other photos aren't deleted, and contentSyncStatus.HomeAway.lastError says why. VRBO takes JPG, PNG or GIF photos of at least 1024×683, up to 20 MB.
    • A photo a channel refuses (too small, a file that can't be downloaded) is now left out on that channel, on Airbnb as on VRBO, and the other photos still go. Before, it stopped the whole photo push. contentSyncStatus.<channel>.lastError names the photo and the reason, and the photo is sent again with the listing's next push.
    • The MCP manage_listing_photos tool works the same way.
  • Changed Listings Only in Get Listings:

    • /api/getListings accepts an optional updatedSince (an ISO 8601 date-time, e.g. 2026-10-07T20:00:00Z) and then returns only the listings that changed at or after that time. An invalid value returns 400.
    • Use it to poll for changes instead of fetching every listing each time: save the time just before each call, minus a minute for clock differences, and pass it on the next call. It works with limit, cursor and the other filters.
    • It doesn't report deleted listings (use the listing.deleted webhook), and a change to a listing group or direct booking site alone doesn't count as a listing change.
  • Sync Switches in Get Listing:

    • /api/getListing/{listingID} and /api/getListings now return messagingEnabled, syncPricing and syncAvailability, the same switches /api/setListing/{listingID} takes, so you can read whether each one is on.
    • syncPricing and syncAvailability read false while messagingEnabled is off, because they only run while messaging is on.
    • The MCP get_listing and list_listings tools return them too, and turning one on or off sends a listing.changed webhook.
  • Review Guests (Airbnb and VRBO):

    • New /api/leaveReview/{reservationID} leaves your review of a guest after their stay. It needs the reservations:write scope.
    • Airbnb: send comments (the public review, required) and optional ratings for cleanliness, communication and houseRules (1 to 5 stars) and recommend (true or false). Airbnb has no overall star for guests, so ratings.overall returns 400.
    • VRBO: send optional ratings for overall, cleanliness, communication and houseRules and recommend (whether you'd rent to the guest again). VRBO reviews of guests have no text, so comments returns 400.
    • A star left out is 5 stars and recommend defaults to true, the same defaults as the review message rules.
    • Booking.com doesn't let hosts review guests, so other channels return 400.
    • The reservation must be booked (status "accepted"), checked out, and not reviewed yet. Otherwise it returns 409, as does a stay the channel isn't taking a review for: reviews open at check-out and close 14 days later.
    • Afterwards the reservation has hostHasLeftReview set, and a review message rule for the stay won't leave a second review.
    • The MCP server has the same action as leave_review.
  • Reply to Guest Reviews (Airbnb, Booking.com and VRBO):

    • New /api/replyToReview/{reservationID} posts your public reply to the review a guest left for their stay. Send reply (the text). It needs the reservations:write scope.
    • Each review takes one reply. A stay with no guest review on the channel yet, or one you already replied to, returns 409.
    • Airbnb: the reply must be under 1,000 characters, and Airbnb only shows a guest's review once both sides have reviewed or the review window has closed.
    • Booking.com: only reviews with written comments take a reply (a score-only review returns 409), and Booking.com checks each reply before guests see it.
    • VRBO: a reply only goes through while VRBO offers one on the review (its "Respond" button), otherwise 409. VRBO checks each reply before guests see it, and refuses replies with contact details or the guest's name.
    • Other channels return 400.
    • The MCP server has the same action as reply_to_review.
  • Review Webhooks:

    • Your webhook URL now also receives type: "review" webhooks with event review.created when Host Tools learns of a new review: a guest reviewed a stay on Airbnb, Booking.com or VRBO (document.reviewer "guest"), or the host reviewed a guest on Airbnb or VRBO (document.reviewer "host"), whether through /api/leaveReview/{reservationID}, a review message rule or the channel itself.
    • document has reservationID, listingID, channel, confirmationCode, reviewer, and when Host Tools has them comments, rating, categoryRatings and submittedAt. VRBO only reports that the host reviewed, so a VRBO host review arrives without text or stars. See /webhooks/review.
    • Each review is sent once. Guest reviews are picked up in the background, so the webhook can come some time after the guest posted. A review posted more than 30 days before Host Tools picked it up (an old stay synced for the first time) is not sent. A review with no date (VRBO host reviews) counts from the stay's check-out instead.
    • If your endpoint only handles other webhooks, make sure it ignores (and still acknowledges with a 2xx) type: "review".
  • VRBO Rooms and Bathrooms in Content Sync:

    • While content sync is on, VRBO now also gets each bedroom's and living room's beds in bedroomConfiguration, and bathrooms as full and half bathrooms.
    • A room goes to the VRBO room that already has the same beds, and the rest in order, so a room's name and description on VRBO stay with its beds.
    • Beds VRBO has no kind for (a couch, an air mattress, a hammock, an extra bed) aren't sent.

Version 1.11.0

  • Accept and Decline Booking Requests (Airbnb only for now):

    • New /api/acceptReservation/{reservationID} accepts an Airbnb request to book, and /api/declineReservation/{reservationID} declines one. Both need the reservations:write scope.
    • Only works on a reservation with source "Airbnb" and status "pending". Other channels return 400.
    • Declining needs a reason (dates_not_available, not_a_good_fit, waiting_for_better_reservation or not_comfortable) and a messageToGuest, which Airbnb sends the guest. messageToAirbnb is an optional private note to Airbnb.
    • A reservation that is no longer pending (already accepted or declined, expired, or an inquiry) returns 409. If Airbnb refuses, its reason comes back in message.
    • Host Tools refreshes the reservation from Airbnb afterwards, so the new status shows up in /api/getReservation/{reservationID}, and the reservation webhook fires, shortly after the call, not in its response.
    • The MCP server has the same actions as accept_booking_request and decline_booking_request.
    • Booking.com: /api/declineReservation/{reservationID} (and decline_booking_request) also declines a Booking.com request to book: a reservation with source "Booking" and status "inquiry". Use one of Booking.com's reasons (DATES_NOT_AVAILABLE, POLICY_DONT_FIT_NEEDS, OUTSIDE_HOURS_CHECKIN, MISSING_INFORMATION or NOT_COMFORTABLE). NOT_COMFORTABLE also needs reasonText, up to 255 characters. Booking.com doesn't take a message to the guest and never shows the guest the reason, so messageToGuest and messageToAirbnb return 400 there. A request that already changed or expired returns 409. The new status shows up shortly after the call. Accepting a Booking.com request is not supported here.
  • Get Reviews is fast and no longer times out:

    • /api/getReviews/{listingID} now returns the copy Host Tools keeps of each guest review instead of asking Airbnb, Booking.com and VRBO for them on every request, which could take over a minute and end with no response at all. It now answers quickly.
    • The response format is unchanged: the same fields, rated reviews only, newest first. confirmationCode is now filled in for Airbnb and Booking.com reviews too.
    • Which reviews come back can differ from before: Airbnb reviews are no longer limited to the 25 most recent, and an older review is only included if Host Tools has collected it.
    • Host Tools collects reviews in the background, so a review that was just posted may not appear straight away. A review is only included when Host Tools has the reservation it belongs to.
    • The MCP get_reviews and get_review_stats tools read the same stored reviews.
  • Error Webhooks:

    • Your webhook URL now also receives type: "error" webhooks when something goes wrong after a request has already succeeded: a channel account disconnects (account.disconnected), VRBO asks the host to verify the account (account.verificationRequired), a channel refuses a price, availability or minimum-nights change (calendar.syncFailed), Airbnb refuses to connect a listing (listing.connectionFailed), a channel refuses a listing content push (listing.contentSyncFailed), or a scheduled message or review fails (message.sendFailed, review.submitFailed).
    • event is error.raised when the problem starts and error.resolved when it clears. document.errorID is the same in both, so you can match them. Deliveries can arrive out of order: apply them by occurredAt and resolvedAt, and ignore a resolve for an errorID you never saw. See /webhooks/error for the full document.
    • OAuth clients only receive the errors their scopes cover, for example accounts:read for account.disconnected.
    • If your endpoint only handles other webhooks, make sure it ignores (and still acknowledges with a 2xx) type: "error", and ignores code values it does not know.
  • Get Errors:

    • Added /api/getErrors (GET), which returns every error currently open for the user, read from the same records the webhooks come from. Use it to recover after a missed webhook. Filter with listingID, code or since.
    • Added the MCP tool list_errors, which returns the same list.
  • Set Calendar:

    • Set Prices is now called Set Calendar, at /api/setCalendar/{listingID}. /api/setPrices/{listingID} still works the same way, so existing integrations don't need to change.
    • Each date can now include blocked. true blocks the date, the same as blocking it on the Host Tools calendar, and false removes the block. It can't open a date held by a reservation or a calendar rule. Blocking works on any listing, whatever its price source.
  • Write Amenities, Property Type and Rooms:

    • /api/setListing/{listingID} now accepts attributesWithQuantity, propertyTypeId and bedroomConfiguration. Each one replaces the whole field, and null clears it.
    • They take ids, not labels. The new /api/getListingContentOptions lists every id with its label.
    • /api/getListing/{listingID} and /api/getListings now return the ids beside the labels: attributesWithQuantity[].attributeId, propertyTypeId and bedroomConfiguration...bed[].bedTypeId. To edit a field, send the ids back, not the labels. propertyType, attribute and bedType are read-only.
    • Changes reach Airbnb in the background: the property type when it has an Airbnb counterpart, the total number of beds, and the amenities that have an Airbnb counterpart. /api/setListing/{listingID} lists which fields go to which channel. Nothing is sent to VRBO, Booking.com or Houfy yet.
  • Listing Photos:

    • /api/getListing/{listingID} and /api/getListings now return photos: the listing's photos in order, each with an id, its url and its caption when it has one. The first photo is the cover. images still returns the same urls, and is deprecated.
    • New /api/reorderListingPhotos/{listingID} takes photoIDs, every photo id on the listing in the new order. The first becomes the cover.
    • New /api/setListingPhoto/{listingID}/{photoID} sets or clears a photo's caption, and isCover: true makes it the cover by moving it first.
    • New /api/deleteListingPhoto/{listingID}/{photoID} removes a photo.
    • New /api/uploadListingPhoto/{listingID} adds a photo as the listing's last, sent as a multipart/form-data file (photo) or downloaded from an https url, with an optional caption. PNG or JPEG up to 10 MB and at least 1024×683 either way round, and at most 50 photos on a listing. It returns the new photo beside photos.
    • Each returns the listing's photos after the change, or 409 when another change added, deleted or moved a photo while the request ran (nothing is saved; get the listing again and retry). A photo id stays the same when photos are reordered or captioned, but changes if the listing's photos are imported from a channel again.
    • The MCP server has the same operations in the new manage_listing_photos tool, which uploads by url.
    • Photo changes show on direct booking sites straight away. While the listing's content sync is on, they also go to Airbnb, which ends up with exactly the listing's photos in its order. They aren't sent to VRBO, Booking.com or Houfy yet.
  • Content Sync:

    • Send contentSyncEnabled: true to make Host Tools' copy the source of the listing's content on every channel. false turns it off.
    • Turning it on pushes every field that waits on it to the listing's channels straight away, so each channel matches Host Tools from then on. Airbnb's photos that Host Tools doesn't have are deleted. A value Host Tools doesn't have, such as an empty text or a photo without a caption, isn't sent, so the channel keeps its own.
    • While it's on, the English summary (notes.shortDescription), house rules (notes.houseRules), neighborhoodOverview and the wifi network and password (policy.internetPolicy.wifi, when the internet is WiFi) also go to Airbnb when they change. notes.description isn't sent: Airbnb builds its description from the summary and its other texts.
    • While it's on, each bedroom's and living room's beds in bedroomConfiguration also go to Airbnb. Rooms are matched in order, so adding a room fills a bedroom Airbnb has without beds, or adds one, and removing one removes the last. If Airbnb has a room without beds before one with beds, no rooms are sent and contentSyncStatus.Airbnb.lastError says so. Beds Airbnb has no counterpart for (a murphy bed, an extra bed) aren't sent, and beds on Airbnb that Host Tools can't name are kept.
    • While it's on, VRBO also gets the name as its headline, the English notes.description as its description, and checkInTime and checkOutTime. Nothing goes to VRBO while it's off. VRBO saves the headline and description together, so when only one changed, the other goes as VRBO has it. The outcome shows in contentSyncStatus.HomeAway.
    • Airbnb's summary and VRBO's description are different fields: notes.shortDescription and notes.description. To show the same text on both, send it in both. /api/setListing/{listingID} lists which field goes to which channel.
  • Listing Name Rules:

    • name must be at least 10 characters on every listing (spaces don't count), and at most 50 on a listing on Airbnb or 80 on one on VRBO. Otherwise /api/setListing/{listingID} and the MCP update_listing tool return 400 and save nothing.
    • Only a name that differs from the listing's is checked, so re-sending a listing's current name is fine, even one saved before these rules.
  • Listing Texts Are Checked:

    • /api/setListing/{listingID} now returns 400 for a neighborhoodOverview, about or notes in the wrong shape. Before, it returned 200 and dropped the parts it didn't know, so {"texts": [...]} sent as neighborhoodOverview replaced the stored overview with {}.
    • neighborhoodOverview and about take a single text, {"language": "en", "value": "..."}. Each notes field takes a list, {"texts": [{"language": "en", "value": "..."}]}, and a notes field that doesn't exist returns 400 too.
    • The API reference showed each notes field as a single text; it now shows the list. Sending notes replaces all of them, so include every field you want to keep.
  • Corrected Bed Types:

    • bedroomConfiguration...bed[].bedType now returns Airbnb's own names for five bed types: couch_bed (was couch), crib_bed (was crib), air_mattress_bed (was air_mattress), floor_mattress_bed (was floor_mattress) and hammock_bed (was hammock). A futon returns futon_bed. bedTypeId is unchanged.
  • Content Sync Status:

    • /api/getListing/{listingID} and /api/getListings now return contentSyncEnabled, and contentSyncStatus with each channel's lastPushedAt and lastError.
    • listing.changed is now also sent when that status changes, for example when Airbnb refuses a push.
  • Send Attachments:

    • /api/sendMessage/{reservationID} now accepts multipart/form-data with up to 5 files (up to 100 MB each) alongside message. JSON text-only requests work as before.
    • JPEG and PNG can be sent on every channel. MP4 and MOV videos can only be sent to Airbnb guests.
    • message is optional when files are attached. On Airbnb each file is delivered as its own message after the text.
    • New 400 errors: Videos can only be sent to Airbnb guests., Contains unsupported file types, File too large and Unexpected field (more than 5 files).
    • The empty-message 400 now returns {status, message} like every other error, instead of {error}.
  • Pre-approve Inquiries (Airbnb, Booking.com and VRBO):

    • New /api/preapproveReservation/{reservationID} pre-approves an inquiry, which tells the guest they may book. It needs the reservations:write scope.
    • On Booking.com, pre-approving means approving the guest's request to book.
    • On VRBO, Host Tools sends the inquiry's quote back unchanged, as the VRBO app does, with the message you send to the guest. message is required on VRBO; Airbnb and Booking.com pre-approvals can't carry one, so a message there returns 400 (send it with /api/sendMessage/{reservationID}). This is built from a captured VRBO app request and has not been tried on a live account yet. The VRBO app also sends an App Check header that Host Tools can't send, so VRBO may refuse it.
    • Only works on a reservation with source "Airbnb", "Booking" or "VRBO" and status "inquiry". Other channels return 400.
    • A reservation that is no longer an inquiry (already pre-approved, booked, declined or expired) returns 409. If the channel refuses, its reason comes back in message.
    • Host Tools refreshes the reservation from the channel afterwards, so the new status (preapproved) shows up in /api/getReservation/{reservationID}, and the reservation webhook fires, shortly after the call, not in its response.
    • The MCP server has the same action as preapprove_inquiry.
  • Send Special Offers (Airbnb and VRBO):

    • New /api/specialOffer/{reservationID} sends a special offer to an inquiry: startDate, endDate, guests (adults, children) and a total price. It needs the reservations:write scope.
    • price is the stay's total including the cleaning fee and the listing's other fees, before taxes and the channel's guest service fee. Airbnb needs a whole number.
    • On VRBO the listing's fees stay as VRBO quotes them for the new dates, and the rent is the price less those fees. An optional message goes to the guest with the offer. Airbnb's special offers can't carry a message, so a message there returns 400; send it with /api/sendMessage/{reservationID}.
    • Works on a reservation with source "Airbnb" or "VRBO" and status "inquiry" or "preapproved". Booking.com has no special offers and returns 400. A reservation that is no longer open returns 409, and a channel refusal returns 405 with its reason.
    • VRBO support is built from a captured VRBO app request and has not been tried on a live account yet. The VRBO app also sends an App Check header that Host Tools can't send, so VRBO may refuse it.
    • The MCP server has the same action as send_special_offer.

Version 1.10.0

  • Change Dates and Guests on a Reservation:
    • /api/setReservation/{reservationID} now accepts startDate, endDate (YYYY-MM-DD), guests (adults, children, infants, pets), hostPayout and guestPrice for reservations with source internal or direct.
    • You can send just one date to move only the check-in or only the check-out.
    • Only the guests fields you send change. adults + children can't exceed the listing's capacity.
    • New dates that overlap another reservation on the listing are rejected with a 400.
    • Scheduled messages and lock codes follow the new dates. So does the calendar on connected channels, when Host Tools syncs the listing's availability.
    • The payout isn't recalculated, and moving a direct booking doesn't re-charge or refund the guest. Send hostPayout and guestPrice if they changed.
    • These fields return a 400 for channel reservations (Airbnb, VRBO, Booking.com, etc.). Change those on the channel.
    • Moving a reservation to another listing isn't supported. Cancel it and create a new one.

Version 1.9.0

  • Listings Pagination and Filters:

    • /api/getListings accepts an optional limit (1-500). When it's set, the response includes a nextCursor. Pass it back as cursor to get the next page, and stop when nextCursor is null. Without limit, every listing is still returned in one response, as before.
    • With startDate and endDate, a page can hold fewer than limit listings even when more remain. Keep paging until nextCursor is null.
    • New filters: listingGroupID returns only the listings in that group (404 if the group doesn't exist), and listingEnabled=true|false returns only enabled or disabled listings.
    • Listings are now always returned newest first (most recently imported first), so the order is the same on every call.
    • The response now always includes nextCursor, which is null when limit isn't set.
  • Video Attachments:

    • Messages from Airbnb guests can now include videos (MP4 or MOV, up to 100 MB) in posts[].attachments, alongside images. They appear in /api/getReservation/{reservationID}, /api/getReservations/... and the message webhook.
    • Each attachment now has a type (image, video or file) and, when known, a mimeType, so you no longer need to guess from the URL.
    • Attachment URLs expire after 1 hour. Download the file, or call /api/getReservation/{reservationID} again for a fresh link.
    • The message webhook is sent once the files are copied into our storage, so a message with a video can arrive a little later than a text-only one.
    • /api/sendMessage/{reservationID} still sends text only. Sending images or videos through the API isn't supported yet.
  • Post Role:

    • Documented posts[].role (guest, host, cohost, cleaner, support or unknown), which the API already returned.

Version 1.8.0

  • Listing and Listing Group Webhooks:

    • Your webhook URL now also receives listing webhooks (type: "listing") with event set to listing.created, listing.changed or listing.deleted. listing.changed is sent when a field returned by /api/getListing/{listingID} changes; several edits within 30 seconds arrive as one webhook with the latest data.
    • It also receives listing group webhooks (type: "listingGroup") with event set to listingGroup.created, listingGroup.changed or listingGroup.deleted. listingGroup.changed carries the group's full current listingIDs, so you can see which listings joined or left.
    • created and changed webhooks carry the same document the matching GET endpoint returns. deleted webhooks carry only _id and userID.
    • If your endpoint only handles reservation and message webhooks, make sure it ignores (and still acknowledges with a 2xx) other type values.
  • Listing Group IDs on Listings:

    • /api/getListings and /api/getListing/{listingID} now return listingGroupIDs, the IDs of the groups that contain each listing.

Version 1.7.0

  • MCP Server:

    • Documented the Model Context Protocol endpoint at https://app.hosttools.com/mcp, which gives MCP-compatible AI assistants the same account data as this API through 49 tools. See MCP Server for the scopes, tools, and transport details.
    • Added /.well-known/oauth-protected-resource/mcp (GET, protected resource metadata per RFC 9728) to the reference. MCP clients read it first to find which authorization server secures the endpoint.
    • The endpoint accepts OAuth Bearer tokens only. The legacy authToken and apiKey headers do not work there, and a sub-user's token is rejected.
  • Send Message Returns the Post ID:

    • /api/sendMessage/{reservationID} now returns the created post's ID as postID alongside success. This is the same identifier published as document.post._id by message webhooks and as posts[]._id by the reservation endpoints, so a message you send can be matched to the webhook you receive for it without comparing message text.
    • Note: for reservations on connected channels, re-syncing a message thread can assign a post a new ID. Treat postID as a short-lived correlation key rather than a value to store long-term.

Version 1.6.0

  • OAuth 2.0 Support:

    • Added a full OAuth 2.0 authorization code flow for third-party integrations: /oauth/register (POST, dynamic client registration per RFC 7591), /oauth/authorize (GET consent page, POST consent decision), /oauth/token (POST, exchange an authorization code or refresh an expired access token), /oauth/token/revoke (POST, per RFC 7009), and /.well-known/oauth-authorization-server (GET, server metadata discovery per RFC 8414).
    • All API endpoints now accept an Authorization: Bearer <token> header. OAuth 2.0 is recommended for new integrations; the legacy authToken header remains supported.
    • Webhook URLs are now scoped to the authenticated client: each OAuth client manages its own webhook via /api/getWebhook, /api/setWebhook, and /api/deleteWebhook. Legacy apiKey webhook behavior is unchanged.
  • New Listing Group Endpoints:

    • Added /api/listingGroups (GET) to list all listing groups for the authenticated user, /api/getListingGroup/{listingGroupID} (GET) to fetch one (including its ownerImportLink), /api/addListingGroup (POST) to create or update a listing group, and /api/deleteListingGroup (POST) to delete one.
    • Added /api/listingGroups/{listingGroupID}/generateOwnerImportToken (POST) to generate or rotate a listing group's owner import link.
  • Enhanced Listing Update Endpoint:

    • Expanded /api/setListing/{listingID} beyond upsellURL with 28 additional updatable fields:
      • Property details: name, about, neighborhoodOverview, notes, space, spaceUnit, bedrooms, bathrooms, maxGuests, address, timeZone, currency
      • Pricing: basePrice, minPrice, weeklyDiscount, monthlyDiscount, nonRefundableDiscount, priceSource, priceSourceListingID
      • Booking & stay settings: minNights, bookingWindow, checkInTime, checkOutTime, listingEnabled, calendars, linkedRoomID, keyCollection, policy
  • Per-Listing Sync Controls:

    • Added messagingEnabled, syncPricing, and syncAvailability to /api/setListing/{listingID}, matching the three sync toggles on the listing Settings page. messagingEnabled is the master switch; listingEnabled remains accepted as its deprecated alias.
    • Turning syncPricing or syncAvailability on returns 400 for listings whose Airbnb account was connected in setup mode, and for co-host listings whose owner hasn't granted sync permission via the owner-permission link. Messaging is never blocked by either condition.
    • Master-gate semantics match the Settings page: turning messaging off turns pricing/availability sync off with it; enabling pricing or availability sync auto-enables messaging; re-enabling messaging on a disabled listing starts from a clean slate — stored sync flags don't silently resume. Changing priceSource counts as enabling sync and is subject to the same guards.
    • When a pricing/availability toggle change triggers an immediate Airbnb push, the response reports it via the new optional syncPushed field.
    • Removed the legacy "Beyond Pricing" price source from the API — use syncPricing: false to stop price pushes. Enabling syncPricing on a listing still carrying the legacy value resets its price source to "Amount".
  • Headless Airbnb Auto-Connect:

    • Added /api/owner-import/auto-connect/airbnb (GET), which redirects the end-user's browser straight to Airbnb's OAuth consent page so partners can connect an owner's Airbnb account without showing the Host Tools import UI.

Version 1.5.0

  • New Cancel Reservation Endpoint:

    • Added /api/cancelReservation/{reservationID} (POST) for cancelling internal or direct reservations by Host Tools reservation ID. Only reservations with source internal or direct can be cancelled through this endpoint; reservations from external channels (Airbnb, VRBO, Booking.com, etc.) must be cancelled through their respective platforms. Returns success if the reservation is already cancelled (idempotent).
  • New Delete Webhook Endpoint:

    • Added /api/deleteWebhook (DELETE) for deleting the webhook URL associated with the user's API key.
  • Enhanced Reservation Update Endpoint:

    • Added accessCode to /api/setReservation/{reservationID}: custom smart lock code for the reservation. Set to null or empty string to clear and use the auto-generated code.
  • Reservation Schema:

    • Added rates array to reservation objects: breakdown of fees, taxes, pricing components, and deposits for the reservation. Each item includes type (fee, tax, price, deposit), amount, name, paidToHost, and paidBy (host or guest).

Version 1.4.0

  • New Listing Update Endpoint:

    • Added /api/setListing/{listingID} endpoint for updating listing details. Currently supports setting the upsellURL field, which can be used with the {{Upsell URL}} message tag to share promotional links with guests.
  • Enhanced Reservation Update Endpoint:

    • Expanded /api/setReservation/{reservationID} with additional updatable fields:
      • firstName - Guest's first name (used in {{Guest First Name}} message tag)
      • lastName - Guest's last name (used in {{Guest Last Name}} message tag)
      • email - Guest's email address
      • phone - Guest's phone number (used in {{Guest Phone}} and {{Guest Lock Code}} tags)
      • checkInTime - Custom check-in time (0-23 hours), affects lock code access scheduling
      • checkOutTime - Custom check-out time (0-23 hours), affects lock code access scheduling
      • notes - Internal notes for the reservation (used in {{Notes}} message tag)
    • Added verificationStatus enum values: signed, approved
    • Improved endpoint documentation explaining how updated values integrate with message tags and lock code scheduling

Version 1.3.0

  • New User Endpoint:

    • Added /api/getUser endpoint that returns current authenticated user information, including userID, email, firstName, and lastName. Empty strings are returned for names when not set.
  • New Reviews Endpoint:

    • Added /api/getReviews/{listingID} endpoint that returns reviews for listings with Airbnb channels connected, including review count, comments, ratings, and reviewer information.
  • Enhanced Listing Endpoints:

    • Enhanced /api/getListings endpoint with optional startDate and endDate query parameters for availability filtering. When both dates are provided, it only returns listings that are available for the specified date range, checking for blocked dates, minimum night requirements, and pricing availability.
  • New Reservation Management Endpoints:

    • Added /api/getQuote/{listingID} endpoint for calculating pricing quotes with availability checking, including base pricing, fees, taxes, and detailed line item breakdowns. Returns 409 status with unavailable dates when conflicts exist.
    • Added /api/createReservation endpoint for programmatically creating internal reservations with full guest details, pricing, and status management.
  • Enhanced Listing Schema:

    • Added region field to provide state/region information
    • Added images array containing listing image URLs
    • Added minNights for minimum booking requirements
    • Added basePrice for base nightly rate
    • Added maxGuests for maximum occupancy
    • Added attributesWithQuantity array for property amenities with quantities
    • Added nearbyAmenities array for nearby attractions with distances
    • Added propertyType field with standardized property types
    • Added bedroomConfiguration object with detailed bedroom and bed information
    • Added space field for property area/size measurement
    • Added spaceUnit field for space measurement units (SQ_M, SQ_FT)
  • New Schema Definitions:

    • Added AmenityEnum with 96+ standardized amenity values across booking platforms
    • Added NearbyAmenityEnum for nearby amenities (Airport, Ferry, Shopping, Railway, Beach)
    • Added PropertyTypeEnum with 43+ property types (apartment, villa, castle, etc.)
    • Added BedTypeEnum with bed types (king_bed, queen_bed, sofa_bed, etc.)
    • Added GetReviews and Review schemas for review functionality
    • Added GetQuoteRequest and GetQuote schemas for pricing quote functionality
    • Added CreateReservation schema for reservation creation with comprehensive guest and pricing details
  • Schema Updates:

    • Updated User, Listing, Reservation, and Price schemas to document new userID fields

Version 1.2.0

  • Enhanced Webhook Documentation: Added better documentation for
    webhook payloads and implementation guidelines.

  • New Reservation Field:

    • posts: Added message/communication thread data to reservation objects. This includes all messages between hosts and guests, with timestamps, attachments, and sender information.
  • New Webhook Type:

  • Message Webhooks: Real-time notifications when new messages or attachments are added to reservation threads. The webhook payload includes message content, sender information, and attachments.

  • Webhook Improvements:

  • Added 30-second timeout for all webhook requests

  • Enhanced webhook payload schemas with detailed examples

Version 1.1.1

  • New Endpoint:
    • Added /api/sendMessage/:reservationID for sending messages to a reservation, currently only available to partners when approved. Feel free to reach out if you would like access.

Version 1.1.0

  • Add rate limiting: Added rate limiting to the API to manage and control the usage and prevent abuse.
  • Authentication Changes
    • Removed apiKey requirement: Now anyone can use our API with a valid authToken from the user's Settings page.
  • New Endpoints:
    • Added /api/setReservation/:reservationID for updating reservation details, currently only guideBookURL is supported.
    • Added /api/getWebhook endpoint for getting webhook URL.
    • Added /api/getReservation/:reservationID endpoint for retrieving individual reservations.
  • Exposed Fields on the Reservation Schema:
    • lockCode: Lock code sent to smart locks.
    • guideBookURL: Guidebook URL
    • notes: Internal reservation notes.
  • Improved error handling for date validation on /api/getReservations.
  • Exposed Fields on the Listing Schema:
    • notes: Expanded to include structured data for description, house rules, fine print, short description, name, and marketing name, each with language and value properties.
    • neighborhoodOverview: Added to provide information about the listing's neighborhood.
    • about: Added to provide general information about the listing.
    • keyCollection: Added to specify key collection details, including type, check-in method, and additional instructions.
    • policy: Added to include detailed policies for internet, parking, pets, children, and smoking.

Version 1.0.0

  • Initial release with basic endpoints for:
    • Listings
    • Calendar
    • Reservations
    • Webhook