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:
cancellationRequestedDateis cleared, acancellationRequestWithdrawnentry is added to the reservation'sevents, and areservation.changedwebhook is sent. A later request on the same booking setscancellationRequestedDateagain 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.
- When a VRBO guest withdraws a request to cancel and the booking stays live, Host Tools now records it:
-
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 (
unitPER_DAY) or per stay (PER_STAY), as long as the listing allows pets (policy.petPolicy.allowedPetsisAllowedorAllowedOnRequest). A pet fee charged per pet, or on a listing that doesn't allow pets, still isn't sent, andskippedsays 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/getListingContentOptionsnow listsVRBOin thepetfee kind'schannels.- Importing a VRBO listing brings its pet fee in as a pet fee (
kindpet,feeTypePET_FEE), so direct booking quotes charge it only for guests with pets.
- While content sync is on, a listing's pet fee now goes to VRBO as VRBO's own pet fee, charged per night (
-
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 atype: "error"webhook. Nothing went wrong, and the host couldn't fix it without deleting a fee other channels use. - The write's
skippedstill 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/getListingsnow hasnotSentTo: 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.
- 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
-
Listing groups only take your own listings, and turnover codes have a minimum length:
/api/addListingGroupnow answers400whenlistingIDsnames a listing that isn't in this account, and lists those ids indata.listingIDs. Nothing is saved.accessCodemust be at least 20 characters, or an empty string to turn the turnover link off. A shorter code is a400. 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/registernow accepts only clients whoseredirect_urisall 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 a400naming 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_namecontaining "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 withstatus"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,
messageToGuestgoes 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
409with VRBO's words. A warning VRBO wants confirmed on vrbo.com first, such as a calendar conflict, is a400. - The
accept_booking_requestanddecline_booking_requestMCP 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/airbnbnow shows them a Host Tools page that counts their listings as they import, then sends them to yourredirectwhen the import finishes. An account with a few hundred listings used to end on a504timeout 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.changedwebhook still reports the listings joining the group.
- After the owner approves on Airbnb,
-
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/getListingsreturn a newpublishingfield, which holds the publish while it runs, and the listing then shows up inchannels.Airbnb. - A new error code,
listing.publishFailed, carries Airbnb's reason when it refuses the listing (atype: "error"webhook and/api/getErrors). Host Tools deletes what it created on Airbnb first, so the listing can be published again. It needs thelistings:readscope, like the other listing errors. - The MCP server has a matching
publish_listingtool.
- New
-
Publish a Listing to Booking.com as a New Room:
/api/publishListing/{listingID}now takes"channel": "Booking", with theaccountIDof 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.roomTypeis the room's type, one ofapartment,holiday_home,villa,chalet,bungalow,mobile_homeandstudio; by default it's the one the listing's property type is, elseapartment.- 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
400saying 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.publishFailedcarries 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. publishingcan now have aBookingentry, and the listing then shows up inchannels.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 theaccountIDof one of the user's VRBO accounts and a requiredhostType,privateorprofessional, plus the property's short-term rentalregistrationNumberwhere 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 withhostTypeandregistrationNumber, 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 withlisting.publishFailedsaying 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.
publishingcan now have aHomeAwayentry, and the listing then shows up inchannels.HomeAway. The MCPpublish_listingtool takes the samehostTypeandregistrationNumber.
-
Check-in and Checkout Times on Every Listing:
- Breaking:
/api/setListing/{listingID}now refuses acheckInTimeoutside 8–23 or acheckOutTimeoutside 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.
- Breaking:
-
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:guestorhost) and the price of the stay if it is accepted:hostPayout,guestPriceand itemizedrates, the same way as the reservation's own. It'snullwhen 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 withhostPayout,guestPriceandrates, Airbnb's own price next to atotalPriceof 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.changedwebhook, with a newalterationRequestedentry in the reservation'sevents. - When the request closes (accepted, declined, withdrawn or voided),
alterationRequestgoes back tonulland anotherreservation.changedwebhook follows, with analterationRequestClosedentry inevents. - Answering a request that Airbnb has already closed is a
409that 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_alterationandrespond_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.
- Reservations now have
-
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: thereasons(each avalueto send and alabelto show, with therefundOptionsvalues VRBO allows for it and VRBO'snotesfor it), therefundOptions(each with therefundTotalVRBO quotes and itsbreakdown: booking amount, booking commission, guest service fee, lodging taxes), thebookingAmountandcurrency, thecustomReasonLengthVRBO requires, and VRBO'swarnings. 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
reasonwith acustomReasonof the required length, and one of that reason'srefundOptionsasrefundPercentType.refundAmountdefaults to the chosen option'srefundTotaland is required when it has none.messageis 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
customReasonof the wrong length is a400before anything is sent. When VRBO refuses the cancellation, the answer is a409with VRBO's text. As on Airbnb, the reservation'sstatusbecomescancelledand areservation.changedwebhook follows. - VRBO counts a cancellation sent this way as the host's, whoever asked for it. When a guest has asked to cancel (
cancellationRequestedDateis set), VRBO's own advice, returned inwarnings, 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 reasonGUEST_NEEDS_TO_CANCELis the fallback. - The MCP server's
get_cancellation_optionsandcancel_reservationdo 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:
cancellationRequestedDateon the reservation (in/api/getReservation,/api/getReservationsand the webhook document) and acancellationRequestedentry in itsevents. Areservation.changedwebhook 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
accepteduntil the host approves the request on VRBO; thenstatusbecomescancelledand areservation.cancelledwebhook is sent, as before. The date is set once and isn't cleared if the guest withdraws the request or the host declines it.
- When a VRBO guest asks to cancel a booking, the reservation now records 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.houseRulesset 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.houseRulesorpolicy.childrenAllowed, as Airbnb no longer returns either.
- Airbnb's API stopped taking a listing's house rules text in its 2026.06.30 version, which Host Tools now uses.
-
Property Type on VRBO:
- While a listing's content sync is on, its
propertyTypeIdnow 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/getListingContentOptionstheguest_houseandhostelproperty types no longer listVRBOin theirchannels. On a listing on VRBO,/api/setListing/{listingID}now refuses them, unless the listing already has one.
- While a listing's content sync is on, its
-
Property Type, Rooms, Size and Photos on Houfy:
- While a listing's content sync is on, its
propertyTypeIdnow 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) andspacewithspaceUnit(in whole units) now go to Houfy too, each only when Houfy has another. Aspaceof 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 apropertyTypeIdwhosechannelsin/api/getListingContentOptionsleave outHoufy(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.lastErrorand sent again on the next push.
- While a listing's content sync is on, its
-
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 andmessagingEnabledare 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'sskippedwith 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: incontentSyncStatus.<channel>.lastErrorfrom/api/getListing/{listingID}, as atype: "error"webhook with the codelisting.contentSyncFailed, and in/api/getErrors. skipped[].channelcan beHoufy, for a fee Houfy doesn't take. The docs listed onlyAirbnb,VRBOandBooking.- House rules too long for VRBO's 3 rules of 150 characters are listed in
skippedwhen the request changes them, as well as incontentSyncStatus.HomeAway.lastErrorafter 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
skippedwhen the request changes which fees can't be sent.
- No behavior change. The endpoint now says what happens to a change it doesn't refuse with a
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,amenitiesandfees. "Content sync" on/api/setListing/{listingID}lists what each becomes there, andcontentSyncStatushas aHoufyentry. - 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.lastErrornames it until it's removed there. - In
/api/getListingContentOptions, the amenities, property types and fee kinds Houfy has now listHoufyin theirchannels. 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.
- While a listing's content sync is on, its content now goes to Houfy too:
-
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,parkingandpoolgo. 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'scontentSyncStatuserror.- In
/api/getListingContentOptions, thosefeeKindsnow listBookingin theirchannels.
- 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
-
Fee Kinds in the Listing Content Options:
/api/getListingContentOptionsnow also returnsfeeKinds: thekinds a fee takes on/api/setListing/{listingID}, with each one's label and the channels (Airbnb, VRBO) that have it.otheris a fee no channel has, so itschannelsare empty.
-
Airbnb's Other Description Sections:
- A listing's
noteshas 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") andtransit("Getting around"). Each is{"texts": [{"language": "en", "value": "..."}]}, likeshortDescription. - Importing a listing from Airbnb now brings them in, and
/api/getListing/{listingID}and/api/getListingsreturn them. A section that's empty on Airbnb is left out. /api/setListing/{listingID}takes them innotes. As for every note,notesreplaces 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.descriptionas its description.
- A listing's
-
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:maxGuestsas the maximum guests;policy.childrenAllowed,policy.smokingAllowedandpolicy.petPolicy.allowedPetsas whether children, smoking and pets are allowed (pets on request go as allowed); and the Englishnotes.houseRulesas its custom rules, at most 3 of up to 150 characters each. House rules too long for that aren't sent, andcontentSyncStatus.HomeAway.lastErrorsays why. - VRBO's other house rules (events, the minimum age, the children's ages) stay as VRBO has them.
- While a listing's content sync is on, VRBO already gets these as its house rules, and the content sync table in
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 thepricing:readscope, the otherspricing: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,afterReservationLengthandbeforeReservationLength. - 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-DDon the listing's calendar. AspecificDatesend date is not included, like a check-out day; ayearlyDatesend date is. - A rule from a calendar rule group (
calendarRuleGroupNameset) 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 isAPI; calendar rules apply whatever the price source.
- New endpoints to read and manage a listing's calendar rules:
-
Calendar Rules in the MCP:
- The tools are now
get_calendar_rulesandcreate_calendar_rule, plus newupdate_calendar_rule,pause_calendar_rule,move_calendar_ruleanddelete_calendar_rule, matching the endpoints above. The old namesget_pricing_rulesandcreate_pricing_rulestill work. - Fixed: rules made with
create_pricing_rulenever applied, because no weekdays were saved with them. A rule now applies on every day unlesslimitDaysnames some. An older rule with no weekdays shows an emptylimitDays; editing it gives it every day. - Fixed:
specificDatesStartDateandspecificDatesEndDatewere 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 asYYYY-MM-DD. - Fixed: the
blockedscale did nothing. A rule created with it is now saved as anavailabilityrule withblocked: true, which blocks the dates. An olderblockedrule turns into one when it's edited. get_calendar_rulesreturns VRBO asVRBO(notHomeAway), weekdays and months as lists, andcalendarRuleGroupNamein place ofpriceRuleGroupName.set_pricesnow says that its prices only apply to listings whose price source isAPI.
- The tools are now
-
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/getListingsno longer returnprivateBathroomon each room inbedroomConfiguration.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
bedroomConfigurationnow 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.lastErrorasked 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.
- While a listing's content sync is on, each room in
-
Rooms, and Photos in Rooms:
/api/getListing/{listingID}now returns anidon each bedroom inbedroomConfiguration.bedrooms, and a newroomslist for the listing's other rooms (a living room without beds, bathrooms, kitchen, patio and so on; a living room with beds stays inbedroomConfiguration), each with anid, atypeIdand alabel. Each photo inphotoshas aroomIDwhen it's in a bedroom or room./api/getListingContentOptionshas a newroomTypeslist: the kinds of roomroomstakes, with the channels each goes to./api/setListing/{listingID}now takesrooms, and anidon each bedroom so a bedroom keeps its photos when the list changes. A bedroom or room sent without anidmatches the one at its place in the list; anidthe listing doesn't have is refused. Whenroomshas any bathrooms,bathroomsis set from them (a half bathroom counts as 0.5)./api/setListingPhoto/{listingID}/{photoID}and/api/uploadListingPhoto/{listingID}take aroomIDto put the photo in a bedroom or room.nulltakes 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 torooms, so the count they set stays the listing's. - In the MCP,
update_listingtakesroomsand bedroom ids,manage_listing_photostakes aroomIdonuploadandupdate, andget_listing_content_optionslistsroomTypes.
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_homeandstudionow includeBookingin theirchannels. Booking.com still isn't sent a property type, so/api/setListing/{listingID}doesn't check it there.
- Importing a listing from Booking.com now brings a holiday home in as
-
Content Held on a Disabled Listing Goes Once It's Enabled:
- Fixed: nothing is pushed while a listing is disabled, and enabling it (
messagingEnabled: trueon/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
contentSyncStatusentry has a newwaitingFor:listingEnabledwhile the listing is disabled with content sync on, so alastPushedAtof null there means the push is waiting, and null otherwise.
- Fixed: nothing is pushed while a listing is disabled, and enabling it (
-
14 More Amenities Go to Airbnb:
- These
amenitiesnow 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_golfandgame_room, plus four new ones:outdoor_shower,bidet,mosquito_netandhome_theater. - In
/api/getListingContentOptionsthey includeAirbnbin theirchannels, 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.
- These
-
House on Listings on Airbnb and VRBO:
/api/setListing/{listingID}now acceptspropertyTypeId: "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_homeis now labelled "House", as both channels call it, and itschannelsincludeVRBO. Its id doesn't change. /api/getListing/{listingID}and/api/getListingsreturnpropertyType: "House"for it, where they returned "Vacation home". A listing whosepropertyTypeis the "house" an import stored now haspropertyTypeId: "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/getListingsnow documentlinkedRoomID,priceSource,priceSourceListingID,weeklyDiscount,monthlyDiscount,nonRefundableDiscount,minPriceandbookingWindow. They were already returned; only the docs were missing.linkedRoomIDon/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.priceSourceListingIDnow 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
syncPricingis 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,spacewithspaceUnit, andpolicy.smokingAllowednow 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. contentSyncStatushas aBookingentry for a listing on Booking.com, with the samelastPushedAtandlastErroras the other channels. A value Booking.com refuses is named inlastError, 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
maxGuestschanges, 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. bedroomConfigurationgoes 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
amenitiesBooking.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 andtwin_bednow includeBookingin theirchannels./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.
- While a listing's content sync is on,
-
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.
- While a listing's content sync is on, photo changes made through the photo endpoints (
-
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:
nameas 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 theamenitiesBooking.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 inskipped(see below). A name Booking.com refuses for another reason, such as a word it doesn't allow, is named incontentSyncStatus.Booking.lastErrorwhile 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.
bathroomsgoes 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.
- While a listing's content sync is on, these now go to its property on Booking.com:
-
What Won't Be Sent:
/api/setListing/{listingID}now answers withskippedwhen 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_listingin the MCP returns the same list in itsdata.
Version 1.14.0
-
OAuth:
- Your
redirect_urican 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 yourredirect_uriitself, soPOST /oauth/authorizereturns the URL as{redirectUrl}instead of a 302. Nothing changes for your app: it still getscodeandstateon itsredirect_uri.
- Your
-
Airbnb Messages:
- Fixed: some Airbnb inquiries lost their messages, including the guest's first message, so the reservation's
postscame 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.
- Fixed: some Airbnb inquiries lost their messages, including the guest's first message, so the reservation's
-
Reservation Events:
- Reservations from
/api/getReservation/{reservationID},/api/getReservations/{listingID},/api/getAllReservations, reservation webhooks and the MCPget_reservationandget_reservationstools now includeevents: what happened to the reservation and when, oldest first. Each has atypeand acreatedAt. - The first event is
created, with thestatusthe reservation had when Host Tools first saw it.statusChangedgives the statusfromandto, so an Airbnb inquiry that was pre-approved and then expired shows asinquirytopreapproved, thenpreapprovedtotimedout. The other types arecheckInChanged,checkOutChanged,guestsChanged,petsChangedandlistingChanged(each withfromandto), andguestReviewed,hostReviewed,doorUnlocked,lockCodeAdded,lockCodeRemovedandpaymentReceived. 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.
- Reservations from
-
Listing Fees and Taxes:
/api/getListing/{listingID}and/api/getListingsnow return the listing'sfeesandtaxes, and/api/setListing/{listingID}takes them. Each replaces the whole list, andnullremoves it.- A fee has a
name, akind(what the fee is, such ascleaningorlinens), afeeType(GENERAL,PET_FEEorDEPOSIT), aunit(how often it's charged), avalueand avalueType(FLAT, orPERCENTof the stay on aPER_STAYfee). It can also have ataxTypeand anoption, the guests included before a per-guest fee is charged. A tax has aname, atype(SalesTaxIncludedorSalesTaxExcluded) and avalue, a percentage. A fee or tax that breaks one of the rules in the API reference returns400and saves nothing. - Fees imported from Airbnb keep Airbnb's names, such as "Cleaning fee".
- A fee's
kinddecides which channel fee it goes as (see below). Send back thekindgetListingreturned to keep it: a fee written without one gets the kind Host Tools works out from itsfeeType,unitandname. - 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_listingandlist_listingstools return them andupdate_listingtakes them. A change to them sends alisting.changedwebhook.
-
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_listingtool works the same way.
- Changed: every listing field
-
Signed Webhooks:
- Every webhook request now has an
X-HostTools-Signatureheader, so you can check it came from Host Tools and wasn't changed on the way. It looks liket=1760000000,v1=5257a8...:tis when it was signed (Unix seconds) andv1is 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/setWebhookand/api/getWebhooknow return it assecret. Webhooks set before this change get a secret the first time you callgetWebhook(or when the next webhook is sent), so callgetWebhookonce to read it. - Setting the webhook again keeps the same secret, even with a new URL. Send
rotateSecret: trueto/api/setWebhookto 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
tis more than 5 minutes old, and compare signatures in constant time.
- Every webhook request now has an
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/getAccountsand/api/getAccount/{accountID}(scopeaccounts:read) return the user's connected channel and smart-lock accounts: the channeltype, whether Host Tools can still use the channel login (connected, withlastConnectedAtandlastDisconnectedAt), 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'scontentSyncStatus.lastError), and the channel's own ID for the account asid, likechannels.<channel>.idon a listing under the same capitalized channel names aschannelson a listing (Airbnb.id, the Airbnb host ID, withAirbnb.fullAccess;Booking.id, the Booking.com property ID;Houfy.id;Seam.idwithSeam.provider; VRBO givesVRBO.usernameinstead). No passwords, tokens or other credentials. These are the same details the MCPlist_accountsandget_accounttools return, whosesortByvalues are nowlastConnectedAtandlastDisconnectedAt. /api/getListing/{listingID},/api/getListings, listing webhooks and the MCPget_listingandlist_listingstools now includeaccountIDnext toidunder each channel inchannels, naming the account the listing comes from. Moving a listing to another account sends alisting.changedwebhook.- Accounts aren't part of listing groups. To find the accounts behind a group, read its
listingIDsand theaccountIDon each of those listings.
- New
-
Get All Reservations (the backstop for missed webhooks):
- New
/api/getAllReservations(scopereservations:read) returns the reservations, across all of the user's listings, that changed at or afterupdatedSince(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
limitreservations per call (1 to 200, default 100). Pass the returnednextCursorascursor, with the sameupdatedSince, untilnextCursorisnull. A page can be shorter thanlimiteven when more remain. - To poll, save the time just before your first call, minus a minute for clock differences, page until
nextCursorisnull, and pass the saved time asupdatedSincenext 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_reservationstool takes the same optionalupdatedSince, and can sort byupdatedAt. It returns at most 200 results with no paging, so use/api/getAllReservationsfor a full catch-up.
- New
-
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 return400.- Airbnb needs a reason. New
/api/getCancellationOptions/{reservationID}(scopereservations:read) returns thereasonsAirbnb accepts for that reservation right now and the host'spenaltyAmount(in the listing's currency, left out when Airbnb quotes none). Send onereason(and itssubReason, 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 returns400. - A reason marked
messageToGuestRequiredneeds amessageToGuestof 30 to 240 characters, which Airbnb sends the guest.messageToAirbnbis an optional private note to Airbnb. - Internal and direct reservations still need no body, and
getCancellationOptionsreturns an emptyreasonslist 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, andcancel_reservationtakes the samereason,subReason,messageToGuestandmessageToAirbnb.
-
Channel Price Adjustments (account settings in the API):
/api/getUsernow returnschannelPriceAdjustments: 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(scopeuser:write, new) changes account settings and returns the user as/api/getUserdoes. SendchannelPriceAdjustmentswith only the channels to change: a number between -100 and 100 (exclusive) sets a channel,null(or0) clears it, and an omitted channel keeps its value. An unknown key, channel or value returns400and saves nothing. A change re-sends prices to every listing on the account. - The MCP
get_usertool returnschannelPriceAdjustmentsand the newupdate_usertool changes them.
-
Breaking: Set Listing Refuses Values the Listing's Channels Don't Support (Airbnb and VRBO):
/api/setListing/{listingID}now returns400when 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 exampleAmenity "HAC6043" is not supported on Airbnb or VRBO.orProperty 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/getListingContentOptionswhosechannelsinclude at least one channel the listing is on, and a property type whosechannelsinclude every channel the listing is on. - The MCP
update_listingtool 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 fullamenitieslist, so you don't drop amenities a VRBO import added.
- 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
-
More Accurate Listing Content Options:
- Each option's
channelsin/api/getListingContentOptionsnow says which channels Host Tools sends it to and reads it from. Amenities VRBO supports are now taggedVRBO. - 64 amenities VRBO supports that were missing are added, such as
outdoor_pool,safe,ocean_viewandkayaking./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_stationsis nowev_charger,board_games_puzzlesisboard_games,indoor_swimming_pool_all_yearandindoor_swimming_pool_seasonalareindoor_pool,outdoor_swimming_pool_all_yearandoutdoor_swimming_pool_seasonalareoutdoor_pool,swimming_poolispool,fitness_roomisgym,outdoor_furnitureisoutdoor_seating,sun_loungers_or_beach_chairsissun_loungers,baby_safety_gatesisstair_gates,gardenisgarden_or_backyard,ski_to_door_accessisski_in_ski_out, andaccessible_parkingisdisabled_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).
- Each option's
-
What Happened in Reservation Webhooks:
- Reservation webhooks (
type: "reservation") now have aneventfield next totypeanddocument, the same as listing and review webhooks:reservation.createdfor a new reservation,reservation.cancelledwhen it is cancelled, andreservation.changedfor 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, soeventalways agrees withdocument.status. - Each change is its own webhook, so a cancel is never folded into a
reservation.changed.documentis still the reservation as it is when the webhook is sent. - Nothing else in the payload changed, so code that ignores
eventkeeps working.
- Reservation webhooks (
-
Amenities Are Now Called
amenities:/api/getListing/{listingID},/api/getListingsand listing webhooks now return a listing's amenities asamenities. Each one has theidthat/api/setListing/{listingID}takes, itslabelfrom/api/getListingContentOptionsand aquantity./api/setListing/{listingID}now takesamenities, a list of{id, quantity}. As before, it replaces the whole list andnullclears it.labelis read-only, so leave it out.attributesWithQuantityis now deprecated but still works the same way, for reading and writing, so existing integrations don't need to change. A request that sends bothamenitiesandattributesWithQuantityreturns400.- The MCP
get_listing,list_listingsandupdate_listingtools 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.lastErrorsays 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>.lastErrornames the photo and the reason, and the photo is sent again with the listing's next push. - The MCP
manage_listing_photostool works the same way.
- While a listing's content sync is on, photo changes made through the photo endpoints (
-
Changed Listings Only in Get Listings:
/api/getListingsaccepts an optionalupdatedSince(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 returns400.- 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,cursorand the other filters. - It doesn't report deleted listings (use the
listing.deletedwebhook), 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/getListingsnow returnmessagingEnabled,syncPricingandsyncAvailability, the same switches/api/setListing/{listingID}takes, so you can read whether each one is on.syncPricingandsyncAvailabilityreadfalsewhilemessagingEnabledis off, because they only run while messaging is on.- The MCP
get_listingandlist_listingstools return them too, and turning one on or off sends alisting.changedwebhook.
-
Review Guests (Airbnb and VRBO):
- New
/api/leaveReview/{reservationID}leaves your review of a guest after their stay. It needs thereservations:writescope. - Airbnb: send
comments(the public review, required) and optionalratingsforcleanliness,communicationandhouseRules(1 to 5 stars) andrecommend(true or false). Airbnb has no overall star for guests, soratings.overallreturns400. - VRBO: send optional
ratingsforoverall,cleanliness,communicationandhouseRulesandrecommend(whether you'd rent to the guest again). VRBO reviews of guests have no text, socommentsreturns400. - A star left out is 5 stars and
recommenddefaults 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 returns409, 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
hostHasLeftReviewset, and a review message rule for the stay won't leave a second review. - The MCP server has the same action as
leave_review.
- New
-
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. Sendreply(the text). It needs thereservations:writescope. - 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.
- New
-
Review Webhooks:
- Your webhook URL now also receives
type: "review"webhooks witheventreview.createdwhen 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. documenthasreservationID,listingID,channel,confirmationCode,reviewer, and when Host Tools has themcomments,rating,categoryRatingsandsubmittedAt. 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".
- Your webhook URL now also receives
-
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, andbathroomsas 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.
- While content sync is on, VRBO now also gets each bedroom's and living room's beds in
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 thereservations:writescope. - Only works on a reservation with
source"Airbnb" andstatus"pending". Other channels return400. - Declining needs a
reason(dates_not_available,not_a_good_fit,waiting_for_better_reservationornot_comfortable) and amessageToGuest, which Airbnb sends the guest.messageToAirbnbis 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 inmessage. - 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_requestanddecline_booking_request. - Booking.com:
/api/declineReservation/{reservationID}(anddecline_booking_request) also declines a Booking.com request to book: a reservation withsource"Booking" andstatus"inquiry". Use one of Booking.com's reasons (DATES_NOT_AVAILABLE,POLICY_DONT_FIT_NEEDS,OUTSIDE_HOURS_CHECKIN,MISSING_INFORMATIONorNOT_COMFORTABLE).NOT_COMFORTABLEalso needsreasonText, up to 255 characters. Booking.com doesn't take a message to the guest and never shows the guest the reason, somessageToGuestandmessageToAirbnbreturn400there. A request that already changed or expired returns409. The new status shows up shortly after the call. Accepting a Booking.com request is not supported here.
- New
-
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.
confirmationCodeis 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_reviewsandget_review_statstools 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). eventiserror.raisedwhen the problem starts anderror.resolvedwhen it clears.document.errorIDis the same in both, so you can match them. Deliveries can arrive out of order: apply them byoccurredAtandresolvedAt, and ignore a resolve for anerrorIDyou never saw. See/webhooks/errorfor the fulldocument.- OAuth clients only receive the errors their scopes cover, for example
accounts:readforaccount.disconnected. - If your endpoint only handles other webhooks, make sure it ignores (and still acknowledges with a 2xx)
type: "error", and ignorescodevalues it does not know.
- Your webhook URL now also receives
-
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 withlistingID,codeorsince. - Added the MCP tool
list_errors, which returns the same list.
- Added
-
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.trueblocks the date, the same as blocking it on the Host Tools calendar, andfalseremoves 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.
- Set Prices is now called Set Calendar, at
-
Write Amenities, Property Type and Rooms:
/api/setListing/{listingID}now acceptsattributesWithQuantity,propertyTypeIdandbedroomConfiguration. Each one replaces the whole field, andnullclears it.- They take ids, not labels. The new
/api/getListingContentOptionslists every id with its label. /api/getListing/{listingID}and/api/getListingsnow return the ids beside the labels:attributesWithQuantity[].attributeId,propertyTypeIdandbedroomConfiguration...bed[].bedTypeId. To edit a field, send the ids back, not the labels.propertyType,attributeandbedTypeare 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/getListingsnow returnphotos: the listing's photos in order, each with anid, itsurland itscaptionwhen it has one. The first photo is the cover.imagesstill returns the same urls, and is deprecated.- New
/api/reorderListingPhotos/{listingID}takesphotoIDs, 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'scaption, andisCover: truemakes 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 amultipart/form-datafile (photo) or downloaded from an httpsurl, with an optionalcaption. 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 newphotobesidephotos. - Each returns the listing's
photosafter the change, or409when 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_photostool, 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: trueto make Host Tools' copy the source of the listing's content on every channel.falseturns 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),neighborhoodOverviewand the wifi network and password (policy.internetPolicy.wifi, when the internet is WiFi) also go to Airbnb when they change.notes.descriptionisn'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
bedroomConfigurationalso 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 andcontentSyncStatus.Airbnb.lastErrorsays 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
nameas its headline, the Englishnotes.descriptionas its description, andcheckInTimeandcheckOutTime. 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 incontentSyncStatus.HomeAway. - Airbnb's summary and VRBO's description are different fields:
notes.shortDescriptionandnotes.description. To show the same text on both, send it in both./api/setListing/{listingID}lists which field goes to which channel.
- Send
-
Listing Name Rules:
namemust 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 MCPupdate_listingtool return400and save nothing.- Only a
namethat 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 returns400for aneighborhoodOverview,aboutornotesin the wrong shape. Before, it returned200and dropped the parts it didn't know, so{"texts": [...]}sent asneighborhoodOverviewreplaced the stored overview with{}.neighborhoodOverviewandabouttake a single text,{"language": "en", "value": "..."}. Eachnotesfield takes a list,{"texts": [{"language": "en", "value": "..."}]}, and anotesfield that doesn't exist returns400too.- The API reference showed each
notesfield as a single text; it now shows the list. Sendingnotesreplaces all of them, so include every field you want to keep.
-
Corrected Bed Types:
bedroomConfiguration...bed[].bedTypenow returns Airbnb's own names for five bed types:couch_bed(wascouch),crib_bed(wascrib),air_mattress_bed(wasair_mattress),floor_mattress_bed(wasfloor_mattress) andhammock_bed(washammock). A futon returnsfuton_bed.bedTypeIdis unchanged.
-
Content Sync Status:
/api/getListing/{listingID}and/api/getListingsnow returncontentSyncEnabled, andcontentSyncStatuswith each channel'slastPushedAtandlastError.listing.changedis now also sent when that status changes, for example when Airbnb refuses a push.
-
Send Attachments:
/api/sendMessage/{reservationID}now acceptsmultipart/form-datawith up to 5files(up to 100 MB each) alongsidemessage. 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.
messageis optional when files are attached. On Airbnb each file is delivered as its own message after the text.- New
400errors:Videos can only be sent to Airbnb guests.,Contains unsupported file types,File too largeandUnexpected field(more than 5 files). - The empty-message
400now 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 thereservations:writescope. - 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
messageyou send to the guest.messageis required on VRBO; Airbnb and Booking.com pre-approvals can't carry one, so amessagethere returns400(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" andstatus"inquiry". Other channels return400. - 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 inmessage. - 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.
- New
-
Send Special Offers (Airbnb and VRBO):
- New
/api/specialOffer/{reservationID}sends a special offer to an inquiry:startDate,endDate,guests(adults,children) and a totalprice. It needs thereservations:writescope. priceis 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
messagegoes to the guest with the offer. Airbnb's special offers can't carry a message, so amessagethere returns400; send it with/api/sendMessage/{reservationID}. - Works on a reservation with
source"Airbnb" or "VRBO" andstatus"inquiry" or "preapproved". Booking.com has no special offers and returns400. A reservation that is no longer open returns409, and a channel refusal returns405with 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.
- New
Version 1.10.0
- Change Dates and Guests on a Reservation:
/api/setReservation/{reservationID}now acceptsstartDate,endDate(YYYY-MM-DD),guests(adults,children,infants,pets),hostPayoutandguestPricefor reservations with sourceinternalordirect.- You can send just one date to move only the check-in or only the check-out.
- Only the
guestsfields you send change.adults+childrencan'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
hostPayoutandguestPriceif 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/getListingsaccepts an optionallimit(1-500). When it's set, the response includes anextCursor. Pass it back ascursorto get the next page, and stop whennextCursorisnull. Withoutlimit, every listing is still returned in one response, as before.- With
startDateandendDate, a page can hold fewer thanlimitlistings even when more remain. Keep paging untilnextCursorisnull. - New filters:
listingGroupIDreturns only the listings in that group (404 if the group doesn't exist), andlistingEnabled=true|falsereturns 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 isnullwhenlimitisn'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,videoorfile) and, when known, amimeType, 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.
- Messages from Airbnb guests can now include videos (MP4 or MOV, up to 100 MB) in
-
Post Role:
- Documented
posts[].role(guest,host,cohost,cleaner,supportorunknown), which the API already returned.
- Documented
Version 1.8.0
-
Listing and Listing Group Webhooks:
- Your webhook URL now also receives listing webhooks (
type: "listing") witheventset tolisting.created,listing.changedorlisting.deleted.listing.changedis 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") witheventset tolistingGroup.created,listingGroup.changedorlistingGroup.deleted.listingGroup.changedcarries the group's full currentlistingIDs, so you can see which listings joined or left. createdandchangedwebhooks carry the samedocumentthe matching GET endpoint returns.deletedwebhooks carry only_idanduserID.- If your endpoint only handles reservation and message webhooks, make sure it ignores (and still acknowledges with a 2xx) other
typevalues.
- Your webhook URL now also receives listing webhooks (
-
Listing Group IDs on Listings:
/api/getListingsand/api/getListing/{listingID}now returnlistingGroupIDs, 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
authTokenandapiKeyheaders do not work there, and a sub-user's token is rejected.
- Documented the Model Context Protocol endpoint at
-
Send Message Returns the Post ID:
/api/sendMessage/{reservationID}now returns the created post's ID aspostIDalongsidesuccess. This is the same identifier published asdocument.post._idby message webhooks and asposts[]._idby 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
postIDas 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 legacyauthTokenheader 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. LegacyapiKeywebhook behavior is unchanged.
- Added a full OAuth 2.0 authorization code flow for third-party integrations:
-
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 itsownerImportLink),/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.
- Added
-
Enhanced Listing Update Endpoint:
- Expanded
/api/setListing/{listingID}beyondupsellURLwith 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
- Property details:
- Expanded
-
Per-Listing Sync Controls:
- Added
messagingEnabled,syncPricing, andsyncAvailabilityto/api/setListing/{listingID}, matching the three sync toggles on the listing Settings page.messagingEnabledis the master switch;listingEnabledremains accepted as its deprecated alias. - Turning
syncPricingorsyncAvailabilityon 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
priceSourcecounts 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
syncPushedfield. - Removed the legacy
"Beyond Pricing"price source from the API — usesyncPricing: falseto stop price pushes. EnablingsyncPricingon a listing still carrying the legacy value resets its price source to"Amount".
- Added
-
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.
- Added
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 sourceinternalordirectcan 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).
- Added
-
New Delete Webhook Endpoint:
- Added
/api/deleteWebhook(DELETE) for deleting the webhook URL associated with the user's API key.
- Added
-
Enhanced Reservation Update Endpoint:
- Added
accessCodeto/api/setReservation/{reservationID}: custom smart lock code for the reservation. Set tonullor empty string to clear and use the auto-generated code.
- Added
-
Reservation Schema:
- Added
ratesarray to reservation objects: breakdown of fees, taxes, pricing components, and deposits for the reservation. Each item includestype(fee, tax, price, deposit),amount,name,paidToHost, andpaidBy(host or guest).
- Added
Version 1.4.0
-
New Listing Update Endpoint:
- Added
/api/setListing/{listingID}endpoint for updating listing details. Currently supports setting theupsellURLfield, which can be used with the{{Upsell URL}}message tag to share promotional links with guests.
- Added
-
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 addressphone- 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 schedulingcheckOutTime- Custom check-out time (0-23 hours), affects lock code access schedulingnotes- Internal notes for the reservation (used in{{Notes}}message tag)
- Added
verificationStatusenum values:signed,approved - Improved endpoint documentation explaining how updated values integrate with message tags and lock code scheduling
- Expanded
Version 1.3.0
-
New User Endpoint:
- Added
/api/getUserendpoint that returns current authenticated user information, includinguserID,email,firstName, andlastName. Empty strings are returned for names when not set.
- Added
-
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.
- Added
-
Enhanced Listing Endpoints:
- Enhanced
/api/getListingsendpoint with optionalstartDateandendDatequery 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.
- Enhanced
-
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/createReservationendpoint for programmatically creating internal reservations with full guest details, pricing, and status management.
- Added
-
Enhanced Listing Schema:
- Added
regionfield to provide state/region information - Added
imagesarray containing listing image URLs - Added
minNightsfor minimum booking requirements - Added
basePricefor base nightly rate - Added
maxGuestsfor maximum occupancy - Added
attributesWithQuantityarray for property amenities with quantities - Added
nearbyAmenitiesarray for nearby attractions with distances - Added
propertyTypefield with standardized property types - Added
bedroomConfigurationobject with detailed bedroom and bed information - Added
spacefield for property area/size measurement - Added
spaceUnitfield for space measurement units (SQ_M, SQ_FT)
- Added
-
New Schema Definitions:
- Added
AmenityEnumwith 96+ standardized amenity values across booking platforms - Added
NearbyAmenityEnumfor nearby amenities (Airport, Ferry, Shopping, Railway, Beach) - Added
PropertyTypeEnumwith 43+ property types (apartment, villa, castle, etc.) - Added
BedTypeEnumwith bed types (king_bed, queen_bed, sofa_bed, etc.) - Added
GetReviewsandReviewschemas for review functionality - Added
GetQuoteRequestandGetQuoteschemas for pricing quote functionality - Added
CreateReservationschema for reservation creation with comprehensive guest and pricing details
- Added
-
Schema Updates:
- Updated
User,Listing,Reservation, andPriceschemas to document newuserIDfields
- Updated
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/:reservationIDfor sending messages to a reservation, currently only available to partners when approved. Feel free to reach out if you would like access.
- Added
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
apiKeyrequirement: Now anyone can use our API with a validauthTokenfrom the user's Settings page.
- Removed
- New Endpoints:
- Added
/api/setReservation/:reservationIDfor updating reservation details, currently onlyguideBookURLis supported. - Added
/api/getWebhookendpoint for getting webhook URL. - Added
/api/getReservation/:reservationIDendpoint for retrieving individual reservations.
- Added
- Exposed Fields on the Reservation Schema:
lockCode: Lock code sent to smart locks.guideBookURL: Guidebook URLnotes: 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