Reservations V3 Booking Flow
A guide to creating quotes and direct bookings with the Open API
Read First
If you are developing a new booking website or application, or if you want to update your current integration to align with Guesty's best practices and latest updates, you have two options:
- Guesty's Booking Engine API: This provides a straightforward booking flow.
- The new Reservations V3 API that offers a wider range of customization.
Overview
On a booking website or application, typically, every reservation begins with a guest visiting a listing page, where they can select the check-in and check-out dates. For this, there can be two possible booking flows:
- A customizable reservation quote flow, and
- A quick reservation flow for when you don't need a lot of customization or options.
The two phases of the typical booking flow are:
- Discovery - Search properties and check availability.
- Checkout - The guest accepts the quote, details are collected, and the booking is completed.
The diagram below gives an overview of the booking flow from discovery to checkout:
Step 1: Discovery
Follow the Query Available Listings guide to learn how to retrieve available listings.
Availability
It is crucial that your application accurately confirms if and when reservations are possible. Create Webhooks to receive relevant notifications whenever calendar availability changes, a new reservation is created, or when a reservation is updated.
Step 2: Creating the Quote
If you choose the simplified reservation flow, you can skip this step and continue with Step 3b below.
This step is part of Guesty's recommended approach, whereby you create a quote and then make the reservation based on the quote the guest has accepted. It allows you to select from the available rate plans and coupons to present the guest with your best offer.
Key Endpoints
Method | Endpoint URL |
---|---|
POST | /v1/quotes |
GET | /v1/quotes/{quoteId} |
Follow the Create reservation with quote documentation to generate a quote. You can then retrieve it with the Get quote by quote id request to present to the potential guest for acceptance.
Request Example
curl 'https://open-api.guesty.com/v1/quotes' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'Authorization: Bearer {token}' \
--data '
{
"numberOfGuests": {
"numberOfChildren": 0,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"listingId": "66afac773445df0013074d3b",
"checkInDateLocalized": "2024-12-29",
"checkOutDateLocalized": "2025-01-03",
"source": "OAPI",
"guestsCount": 2,
"ignoreTerms": false,
"ignoreCalendar": false,
"ignoreBlocks": false
}
'
const myHeaders = new Headers();
myHeaders.append("accept", "application/json");
myHeaders.append("content-type", "application/json");
myHeaders.append("Authorization", "Bearer {token}");
const raw = JSON.stringify({
"numberOfGuests": {
"numberOfChildren": 0,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"listingId": "66afac773445df0013074d3b",
"checkInDateLocalized": "2024-12-29",
"checkOutDateLocalized": "2025-01-03",
"source": "OAPI",
"guestsCount": 2,
"ignoreTerms": false,
"ignoreCalendar": false,
"ignoreBlocks": false
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "manual"
};
fetch("https://open-api.guesty.com/v1/quotes", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
var https = require('follow-redirects').https;
var fs = require('fs');
var options = {
'method': 'POST',
'hostname': 'open-api.guesty.com',
'path': '/v1/quotes',
'headers': {
'accept': 'application/json',
'content-type': 'application/json',
'Authorization': 'Bearer {token}'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = JSON.stringify({
"numberOfGuests": {
"numberOfChildren": 0,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"listingId": "66afac773445df0013074d3b",
"checkInDateLocalized": "2024-12-29",
"checkOutDateLocalized": "2025-01-03",
"source": "OAPI",
"guestsCount": 2,
"ignoreTerms": false,
"ignoreCalendar": false,
"ignoreBlocks": false
});
req.write(postData);
req.end();
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://open-api.guesty.com/v1/quotes',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'
{
"numberOfGuests": {
"numberOfChildren": 0,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"listingId": "66afac773445df0013074d3b",
"checkInDateLocalized": "2024-12-29",
"checkOutDateLocalized": "2025-01-03",
"source": "OAPI",
"guestsCount": 2,
"ignoreTerms": false,
"ignoreCalendar": false,
"ignoreBlocks": false
}
',
CURLOPT_HTTPHEADER => array(
'accept: application/json',
'content-type: application/json',
'Authorization: Bearer {token}',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import http.client
import json
conn = http.client.HTTPSConnection("open-api.guesty.com")
payload = json.dumps({
"numberOfGuests": {
"numberOfChildren": 0,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"listingId": "66afac773445df0013074d3b",
"checkInDateLocalized": "2024-12-29",
"checkOutDateLocalized": "2025-01-03",
"source": "OAPI",
"guestsCount": 2,
"ignoreTerms": False,
"ignoreCalendar": False,
"ignoreBlocks": False
})
headers = {
'accept': 'application/json',
'content-type': 'application/json',
'Authorization': 'Bearer {token}',
}
conn.request("POST", "/v1/quotes", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Overriding Property Stay Parameters
To ensure that your quotes don't ignore the property's stay parameters, include the
ignoreCalendar
,ignoreTerms
, andignoreBlocks
fields withfalse
values. By default, Guesty ignores the property's terms.
Quote Payload
The first level _id
field represents the quote ID and.ratePlans.ratePlan.id
, the rate plan ID. A property can have multiple rate plans. In this example, there are three rate plans, but only the Flexible and Strict plans are applicable and can be offered to the prospective guest.
{
"_id": "675893fc754a15b1234cf325",
"createdAt": "2024-12-10T19:18:20.540Z",
"expiresAt": "2024-12-11T19:18:20.540Z",
"accountId": "66053c21dd2adbdfb3b383b7",
"guestsCount": 2,
"channel": "manual_reservations",
"source": "OAPI",
"unitTypeId": "66afac773445df0013074d3b",
"unitId": "66afac773445df0013074d3b",
"checkInDateLocalized": "2024-12-29",
"checkOutDateLocalized": "2025-01-03",
"rates": {
"ratePlans": [
{
"days": [
{
"date": "2024-12-29",
"currency": "USD",
"rateStrategy": 0,
"ratePlan": -3.6,
"minNights": 3,
"maxNights": 28,
"basePrice": 120,
"lengthOfStay": 0,
"price": 116.4
},
{
"date": "2024-12-30",
"currency": "USD",
"rateStrategy": 0,
"ratePlan": -3.6,
"minNights": 3,
"maxNights": 28,
"basePrice": 120,
"lengthOfStay": 0,
"price": 116.4
},
{
"date": "2024-12-31",
"currency": "USD",
"rateStrategy": 0,
"ratePlan": -3.6,
"minNights": 3,
"maxNights": 28,
"basePrice": 120,
"lengthOfStay": 0,
"price": 116.4
},
{
"date": "2025-01-01",
"currency": "USD",
"rateStrategy": 0,
"ratePlan": -3.6,
"minNights": 3,
"maxNights": 28,
"basePrice": 120,
"lengthOfStay": 0,
"price": 116.4
},
{
"date": "2025-01-02",
"currency": "USD",
"rateStrategy": 0,
"ratePlan": -3.6,
"minNights": 3,
"maxNights": 28,
"basePrice": 120,
"lengthOfStay": 0,
"price": 116.4
}
],
"notApplicable": {
"active": false,
"advanceNotice": false,
"bookingWindow": false,
"closed": true,
"minNights": false,
"maxNights": false,
"cta": false,
"ctd": false,
"manual": false,
"preparationTime": false,
"byDefault": false,
"hardBlocked": false,
"allotment": false
},
"ratePlan": {
"mealPlans": [
"breakfast"
],
"name": "Flexible",
"priceAdjustment": {
"type": "percent",
"direction": "decrease",
"amount": 3
},
"type": "custom",
"minNights": 3,
"availabilityRules": {
"restrictedDates": [
"2024-12-20T00:00:00.000Z",
"2024-12-21T00:00:00.000Z",
"2024-12-22T00:00:00.000Z",
"2024-12-23T00:00:00.000Z",
"2024-12-24T00:00:00.000Z",
"2024-12-25T00:00:00.000Z",
"2024-12-26T00:00:00.000Z",
"2024-12-27T00:00:00.000Z",
"2024-12-28T00:00:00.000Z",
"2024-12-29T00:00:00.000Z",
"2024-12-30T00:00:00.000Z",
"2024-12-31T00:00:00.000Z",
"2025-01-01T00:00:00.000Z",
"2025-01-02T00:00:00.000Z",
"2025-01-03T00:00:00.000Z",
"2025-01-04T00:00:00.000Z",
"2025-01-05T00:00:00.000Z",
"2025-01-06T00:00:00.000Z",
"2025-01-07T00:00:00.000Z"
],
"advanceNotice": 4,
"bookingWindow": 3
},
"active": true,
"accountId": "66053c21dd2adbdfb3b383b7",
"createdAt": "2024-09-09T14:46:47.271Z",
"updatedAt": "2024-12-10T19:01:29.677Z",
"cancellationPolicy": "moderate",
"cancellationFee": 0,
"_id": "66df0a57a26418df2310812f"
},
"money": {
"_id": "675893fc41bd41000e0188f3",
"expiresAt": "2024-12-11T19:18:20.535Z",
"rateId": "66df0a57a26418df2310812f",
"money": {
"fareAccommodationBundleFeesApplied": 0,
"channelCommissionRules": null,
"altered": false,
"_id": "675893fc41bd41000e0188f4",
"platform": "manual",
"source": "OAPI",
"settingsSnapshot": {
"currency": {
"rate": 1,
"rateDate": "2024-12-10T19:18:20.458Z",
"from": "USD",
"to": "USD"
},
"monthlyPriceFactor": 1,
"weeklyPriceFactor": 1,
"additionalFees": [
{
"isPercentage": false,
"automationSources": [],
"automationPlatforms": [],
"RUSources": [],
"isAutomated": true,
"allPlatforms": false,
"allRUSources": false,
"allSources": true,
"isSyncToSupportedChannelsEnabled": true,
"_id": "6735b3e9d253690010ab30d3",
"type": "PET",
"name": "Pet fee",
"value": 360,
"isDeducted": false,
"multiplier": "PER_STAY",
"listingId": "66afac773445df0013074d3b",
"accountId": "66053c21dd2adbdfb3b383b7",
"createdAt": "2024-11-14T08:25:13.809Z",
"updatedAt": "2024-11-14T08:25:13.809Z"
}
],
"taxes": [],
"markup": null,
"channelCommission": {
"manual": []
},
"useAccountRevenueShare": true,
"useAccountAdditionalFees": false,
"guestsIncludedInRegularFee": 2,
"extraPersonFee": 65,
"cleaningFee": 50,
"financials": {
"cleaningFee": {
"value": {
"_id": "6735b3ea390bc90010cce262",
"multiplier": "PER_STAY",
"formula": 50,
"valueType": "FIXED"
},
"lastUpdated": "2024-11-14T08:25:14.247Z"
},
"petFee": {
"value": {
"_id": "6735b3ea390bc90010cce263",
"multiplier": "PER_PET_PER_STAY",
"formula": 0,
"valueType": "FIXED"
},
"lastUpdated": "2024-11-14T08:25:14.248Z"
},
"channelCommission": {
"useAccountSettings": true,
"_id": "673349736d8308d981935fa2",
"manual": [],
"createdAt": "2024-11-12T12:26:27.302Z",
"updatedAt": "2024-12-05T16:10:59.510Z"
}
}
},
"invoiceItems": [
{
"_id": "675893fc41bd41000e0188f0",
"normalType": "AF",
"amount": 582,
"title": "Accommodation fare",
"currency": "USD",
"origin": "AUTOMATIC",
"isLocked": true,
"type": "ACCOMMODATION_FARE",
"refId": "03e6c73b-7f00-4152-8cc7-867a110d8a9a"
},
{
"_id": "675893fc41bd41000e0188f1",
"normalType": "CF",
"amount": 50,
"title": "Cleaning fee",
"currency": "USD",
"origin": "AUTOMATIC",
"isLocked": true,
"type": "CLEANING_FEE",
"baseAmount": 50,
"refId": "78f2318b-4146-4fb0-9cb1-d3b3c745bc11"
},
{
"_id": "675893fc41bd41000e0188f2",
"normalType": "AFE",
"amount": 360,
"title": "Pet fee",
"currency": "USD",
"origin": "AUTOMATIC",
"secondIdentifier": "PET",
"type": "ADDITIONAL",
"isLocked": true,
"isAutoAdditionalFee": true,
"baseAmount": 360,
"refId": "e41071ff-41db-4ff1-810c-143c47fdf0f2"
}
],
"currency": "USD",
"version": 1,
"fareAccommodation": 582,
"channelAfBreakdown": [
{
"_id": "675893fc41bd41000e0188f9",
"date": "Sun Dec 29 2024 00:00:00 GMT+0000 (Coordinated Universal Time)",
"price": 116.4
},
{
"_id": "675893fc41bd41000e0188fa",
"date": "Mon Dec 30 2024 00:00:00 GMT+0000 (Coordinated Universal Time)",
"price": 116.4
},
{
"_id": "675893fc41bd41000e0188fb",
"date": "Tue Dec 31 2024 00:00:00 GMT+0000 (Coordinated Universal Time)",
"price": 116.4
},
{
"_id": "675893fc41bd41000e0188fc",
"date": "Wed Jan 01 2025 00:00:00 GMT+0000 (Coordinated Universal Time)",
"price": 116.4
},
{
"_id": "675893fc41bd41000e0188fd",
"date": "Thu Jan 02 2025 00:00:00 GMT+0000 (Coordinated Universal Time)",
"price": 116.4
}
],
"fareCleaning": 50,
"fareAccommodationAdjustment": 0,
"fareAccommodationDiscount": 0,
"fareAccommodationAdjusted": 582,
"deductedFees": [],
"hostServiceFee": 0,
"hostServiceFeeTax": 0,
"hostServiceFeeIncTax": 0,
"totalFees": 410,
"subTotalPrice": 992,
"hostPayout": 992,
"hostPayoutUsd": 992,
"totalTaxes": 0,
"useAccountRevenueShare": true,
"netIncomeFormula": "host_payout",
"netIncome": 992,
"commissionFormula": "net_income",
"commission": 992,
"commissionTaxPercentage": 0,
"commissionTax": 0,
"commissionIncTax": 992,
"ownerRevenueFormula": "net_income - pm_commission",
"ownerRevenue": 0,
"nightlyRateInvoiceItems": [
{
"isCalculatedByGuesty": false,
"_id": "675893fc41bd41000e0188f0",
"normalType": "AF",
"nightsBreakdown": [
{
"_id": "675893fc41bd41000e0188ff",
"date": "2024-12-29",
"basePrice": 116.4
},
{
"_id": "675893fc41bd41000e018900",
"date": "2024-12-30",
"basePrice": 116.4
},
{
"_id": "675893fc41bd41000e018901",
"date": "2024-12-31",
"basePrice": 116.4
},
{
"_id": "675893fc41bd41000e018902",
"date": "2025-01-01",
"basePrice": 116.4
},
{
"_id": "675893fc41bd41000e018903",
"date": "2025-01-02",
"basePrice": 116.4
}
],
"adjustments": [],
"includedAdjustments": [],
"totalPrice": 582,
"totalNightsPrice": 582,
"title": "Accommodation fare",
"refId": "03e6c73b-7f00-4152-8cc7-867a110d8a9a",
"origin": "AUTOMATIC"
},
{
"isCalculatedByGuesty": true,
"_id": "675893fc41bd41000e0188f1",
"normalType": "CF",
"nightsBreakdown": [
{
"_id": "675893fc41bd41000e018905",
"basePrice": 10,
"date": "2024-12-29"
},
{
"_id": "675893fc41bd41000e018906",
"basePrice": 10,
"date": "2024-12-30"
},
{
"_id": "675893fc41bd41000e018907",
"basePrice": 10,
"date": "2024-12-31"
},
{
"_id": "675893fc41bd41000e018908",
"basePrice": 10,
"date": "2025-01-01"
},
{
"_id": "675893fc41bd41000e018909",
"basePrice": 10,
"date": "2025-01-02"
}
],
"adjustments": [],
"includedAdjustments": [],
"totalPrice": 50,
"totalNightsPrice": 50,
"title": "Cleaning fee",
"multiplier": "PER_STAY",
"refId": "78f2318b-4146-4fb0-9cb1-d3b3c745bc11",
"origin": "AUTOMATIC"
},
{
"isCalculatedByGuesty": true,
"_id": "675893fc41bd41000e0188f2",
"normalType": "AFE",
"nightsBreakdown": [
{
"_id": "675893fc41bd41000e01890b",
"basePrice": 72,
"date": "2024-12-29"
},
{
"_id": "675893fc41bd41000e01890c",
"basePrice": 72,
"date": "2024-12-30"
},
{
"_id": "675893fc41bd41000e01890d",
"basePrice": 72,
"date": "2024-12-31"
},
{
"_id": "675893fc41bd41000e01890e",
"basePrice": 72,
"date": "2025-01-01"
},
{
"_id": "675893fc41bd41000e01890f",
"basePrice": 72,
"date": "2025-01-02"
}
],
"adjustments": [],
"includedAdjustments": [],
"totalPrice": 360,
"totalNightsPrice": 360,
"title": "Pet fee",
"secondIdentifier": "PET",
"multiplier": "PER_STAY",
"refId": "e41071ff-41db-4ff1-810c-143c47fdf0f2",
"origin": "AUTOMATIC"
}
],
"listingId": "66afac773445df0013074d3b",
"accountId": "66053c21dd2adbdfb3b383b7",
"bundledFees": []
},
"__v": 0
}
}
],
"unitTypeId": "66afac773445df0013074d3b",
"fromDate": "2024-12-29",
"toDate": "2025-01-03"
},
"coupons": [],
"numberOfGuests": {
"numberOfChildren": 0,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"__v": 0,
"status": "valid"
}
The Quote Response Payload Explained
Body Parameter | Type | Description |
---|---|---|
_id | string | The Guesty quote ID. |
createdAt | string | The ISO 8601 quote creation date and time. E.g., "2024-08-29T09:31:44.997Z" |
expiresAt | string | The ISO 8601 quote expiration date and time. E.g., "2024-08-30T09:31:44.997Z" |
accountId | string | Your Guesty account ID. |
guestsCount | number | The total number of guests quoted for. |
channel | string | The booking channel: E.g., "manual_reservations." |
source | string | Describes the source of the quote. E.g., "xmas ny campaign." |
unitTypeId | string | The Guesty listing ID of the property - single or sub-unit. |
unitId | string | The Guesty listing ID of the property - single or multi-unit. |
checkInDateLocalized | string | The selected check-in date. |
checkOutDateLocalized | string | The selected check-out date. |
rates | object | It contains all the rate plans available per the stay parameters. The following table breaks down the rate plan. |
rates.ratePlans | [object] | An array of available rate plans. See the following table for more details. |
rates.unitTypeId | string | The Guesty listing ID of the property. |
rates.fromDate | string | The start date for calculating the rate plan. |
rates.toDate | string | The end date for calculating the rate plane. |
coupons | [strings] | Holds any coupons that are applied to the quote. |
numberOfGuests | object | Contains the breakdown of guests into: numberOfChildren , numberOfInfants and numberOfAdults . |
status | string | Indicates whether the quote is within its validation period (valid ) or expired . |
The ratePlans
Object Array Explained
ratePlans
Object Array ExplainedDefault Rate Plan
A property without an active rate plan will return quotes with a
standard
plan whose ID is,default-rateplan-id
.
Body Parameter | Type | Description |
---|---|---|
days | [object] | Array of dates and pricing data. See this section below for an additional breakdown. |
notApplicable | object | Only if the rate plan has availability rules preventing the stay for the quoted dates will it contain data. Otherwise, it returns null . A breakdown of its fields is explained in the following table. |
ratePlan | object | Contains the rate plan details. |
ratePlan.mealPlans | [object] | An array of meal plans (breakfast , lunch , or dinner , or all of them) when configured. Otherwise, it is empty. |
ratePlan.name | string | The name you assigned the rate plan. |
ratePlan.priceAdjustment | object | Nightly rate adjustment configuration. |
ratePlan.priceAdjustment.type | string | It can be one of two types of adjustment: percent or flat . |
ratePlan.priceAdjustment.direction | string | Describes whether the adjustment leads to a price increase or decrease . |
ratePlan.priceAdjustment.amount | number | Either the percentage adjustment or fixed price adjustment. |
ratePlan.type | string | Rate plan type. |
ratePlan.minNights | number | The rate plan's minimum stay requirement. |
ratePlan.availabilityRules | object | Contains any custom availability terms. Such as restrictedDates , advanceNotice , and bookingWindow . |
ratePlan.active | boolean | Defines whether the rate plan is active and applicable. |
ratePlan.accountId | string | Your Guesty account ID. |
ratePlan.createdAt | string | The ISO 8601 date and time the rate plan was created. |
ratePlan.updatedAt | string | The ISO 8601 date and time the rate plan was updated. |
ratePlan.maxNights | number | The rate plan's maximum stay requirement. |
ratePlan.cancellationPolicy | string | The name of the cancellation policy assigned to the plan. |
ratePlan.cancellationFee | number | Will be null when one doesn't exist or is built into the cancelation policy. |
ratePlan._id | string | The rate plan's ID. |
money | object | It contains a breakdown of the calculated fees for the guest invoice, the expected host payout, and more. |
The notApplicable
Object Explained
notApplicable
Object ExplainedThe not applicable object contains a list of the property's availability rules and terms. It is only populated when one or more rules/terms are true
indicating the listing isn't available.
Reminder
Only if the rate plan has availability customization will it contain data. Otherwise, it returns
null
.
Body Parameter | Type | Description |
---|---|---|
notApplicable.active | boolean | true means the listing isn't active. |
notApplicable.advancedNotice | boolean | true means there's an advance notice block on the dates quoted. |
notApplicable.bookingWindow | boolean | true indicates that some or all dates are outside the rate plan's booking window. |
notApplicable.closed | boolean | true if the property is unlisted. |
notApplicable.minNights | boolean | true when the quote overrides the property's minimum stay restriction. |
notApplicable.maxNights | boolean | true when the quote override the property's maximum stay restriction. |
notApplicable.cta | boolean | Closed for arrival. This will be true when the start date of the quote doesn't align with a property's check-in day rule. |
notApplicable.ctd | boolean | Closed for departure. This will be true when the end dates doesn't align with the property's restricted check-out day rule. |
notApplicable.manual | boolean | true when a manual block exists across all or part of the quoted dates. |
notApplicable.preparationTime | boolean | true when the dates encompass a preparation time block. |
notApplicable.byDefault | boolean | true when the property's calendar is blocked by default and the quote dates are outside any rental periods. |
notApplicable.hardBlocked | boolean | true when blocked by a reservation, smart calendar rule, owner's stay, or is reserved for an unassigned multi-unit booking. This type of block cannot be overridden. |
notApplicable.allotment | boolean | true when the listing is a multi-unit and has no available sub-units (allotment=0) for the quoted dates. |
The days
Object Explained
days
Object ExplainedBody Parameter | Type | Description |
---|---|---|
days.date | string | The ISO 8601 date (YYYY-MM-DD ) of the day included in the booking range. |
days.currency | string | The three-letter currency code. |
days.ratePlan | number | The price adjustment to the base nightly rate by the rate plan. For example, if this is -3.6 and the base price is 120, it will decrease the price to 116.4. |
days.minNights | number | The minimum stay restriction. |
days.maxNights | number | The maximum stay restriction |
days.basePrice | number | The nightly rate before rate plans and other add-on financial calculations are applied. |
days.lengthOfStay | number | The price adjustment to the base nightly rate resulted from a length-of-stay discount. |
days.price | number | The calculated rate plan price for this date. |
Step 3a: Creating a Reservation
This request creates a reservation from the quote you generated in step 2.
Key Endpoints
Method | Endpoint URL |
---|---|
POST | /v1/reservations-v3/quote |
GET | /v1/reservations-v3 |
Follow the Create reservation with quote documentation to create a reservation from the quote. The example below demonstrates the quote from the previous step converted to a confirmed booking. If a quote has multiple valid rate plans, specify the selected one by its ratePlanId
.
Example Request
curl --request POST \
--url https://open-api.guesty.com/v1/reservations-v3/quote \
--header 'accept: application/json' \
--header 'authorization: Bearer {accessToken}' \
--header 'content-type: application/json' \
--data '
{
"status": "confirmed",
"reservedUntil": -1,
"guest": {
"firstName": "Michael",
"lastName": "Johnson",
"phones": [
"+12073897654"
],
"email": "[email protected]"
},
"quoteId": "667bc383b119a5cd5f3bfbf6",
"ratePlanId": "667bc2a7ba0b99c80ed92c04",
"ignoreCalendar": false,
"ignoreTerms": false,
"ignoreBlocks": false
}
'
Response Example
{
"reservationId": "667bc9e0319654c49fde9aff"' \
--header 'accept: application/json' \
--header 'authorization: Bearer {accessToken}' \
"quoteId": "667bc383b119a5cd5f3bfbf6",
"confirmationCode": "GY-aJ3WEcJU",
"status": "confirmed",
"guestId": "667bc9e0faaefa084c8bf6ed",
"numberOfGuests": {
"numberOfChildren": 2,
"numberOfInfants": 0,
"numberOfAdults": 2
},
"unitId": "66054019764cbb000f37c450",
"confirmedAt": "2024-06-26T07:57:20.562Z",
"creationTime": "2024-06-26T07:57:20.564Z",
"checkInDate": "2024-07-15T15:00:00.000Z",
"checkOutDate": "2024-07-20T10:00:00.000Z",
"unitTypeId": "66054019764cbb000f37c450",
"source": "summer-campaign",
"channel": "manual_reservations",
"guestsCount": 4
}
Use the Get reservations by IDs request to retrieve the complete reservation details.
Example
curl --globoff 'https://open-api.guesty.com/v1/reservations-v3?reservationIds[]=667bc9e0319654c49fde9aff' \
--header 'accept: application/json' \
--header 'authorization: Bearer {accessToken}'
const myHeaders = new Headers();
myHeaders.append("accept", "application/json");
myHeaders.append("authorization", "Bearer {accessToken}");
const requestOptions = {
method: "GET",
headers: myHeaders,
redirect: "manual"
};
fetch("https://open-api.guesty.com/v1/reservations-v3?reservationIds[]=667bc9e0319654c49fde9aff", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
var https = require('follow-redirects').https;
var fs = require('fs');
var options = {
'method': 'GET',
'hostname': 'open-api.guesty.com',
'path': '/v1/reservations-v3?reservationIds%5B%5D=667bc9e0319654c49fde9aff',
'headers': {
'accept': 'application/json',
'authorization': 'Bearer {accessToken}'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
req.end();
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://open-api.guesty.com/v1/reservations-v3?reservationIds[]=667bc9e0319654c49fde9aff',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'accept: application/json',
'authorization: Bearer {accessToken}'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import http.client
conn = http.client.HTTPSConnection("open-api.guesty.com")
payload = ''
headers = {
'accept': 'application/json',
'authorization': 'Bearer {accessToken}'
}
conn.request("GET", "/v1/reservations-v3?reservationIds%5B%5D=667bc9e0319654c49fde9aff", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Step 3b: Creating a Reservation Without a Quote
This request provides a quicker booking flow when you don't require extensive customization or options.
Key Endpoints
Method | Endpoint URL |
---|---|
POST | /v1/reservations-v3 |
GET | /v1/reservations-v3 |
To manually specify the invoice items under the money object, follow the structure in the Create new Invoice item document.
Request Example
curl 'https://open-api.guesty.com/v1/reservations-v3' \
--header 'accept: application/json' \
--header 'authorization: Bearer {accessToken}' \
--header 'content-type: application/json' \
--data-raw '{
"guest": {
"firstName": "Shaquille",
"lastName": "O'\''Neal",
"phones": [
"+12135049876"
],
"email": "[email protected]"
},
"status": "confirmed",
"numberOfGuests": {
"numberOfAdults": 2
},
"applyPromotions": true,
"ignoreCalendar": false,
"ignoreTerms": false,
"ignoreBlocks": false,
"checkInDateLocalized": "2024-07-05",
"checkOutDateLocalized": "2024-07-22",
"listingId": "66054aa58ea6df0012a20b5e",
"source": "Booking Agent",
"guestsCount": 2
}'
const myHeaders = new Headers();
myHeaders.append("accept", "application/json");
myHeaders.append("authorization", "Bearer {accessToken}");
myHeaders.append("content-type", "application/json");
const raw = JSON.stringify({
"guest": {
"firstName": "Shaquille",
"lastName": "O'Neal",
"phones": [
"+12135049876"
],
"email": "[email protected]"
},
"status": "confirmed",
"numberOfGuests": {
"numberOfAdults": 2
},
"applyPromotions": true,
"ignoreCalendar": false,
"ignoreTerms": false,
"ignoreBlocks": false,
"checkInDateLocalized": "2024-07-05",
"checkOutDateLocalized": "2024-07-22",
"listingId": "66054aa58ea6df0012a20b5e",
"source": "Booking Agent",
"guestsCount": 2
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "manual"
};
fetch("https://open-api.guesty.com/v1/reservations-v3", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
var https = require('follow-redirects').https;
var fs = require('fs');
var options = {
'method': 'POST',
'hostname': 'open-api.guesty.com',
'path': '/v1/reservations-v3',
'headers': {
'accept': 'application/json',
'authorization': 'Bearer {accessToken}',
'content-type': 'application/json'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = JSON.stringify({
"guest": {
"firstName": "Shaquille",
"lastName": "O'Neal",
"phones": [
"+12135049876"
],
"email": "[email protected]"
},
"status": "confirmed",
"numberOfGuests": {
"numberOfAdults": 2
},
"applyPromotions": true,
"ignoreCalendar": false,
"ignoreTerms": false,
"ignoreBlocks": false,
"checkInDateLocalized": "2024-07-05",
"checkOutDateLocalized": "2024-07-22",
"listingId": "66054aa58ea6df0012a20b5e",
"source": "Booking Agent",
"guestsCount": 2
});
req.write(postData);
req.end();
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://open-api.guesty.com/v1/reservations-v3',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"guest": {
"firstName": "Shaquille",
"lastName": "O\'Neal",
"phones": [
"+12135049876"
],
"email": "[email protected]"
},
"status": "confirmed",
"numberOfGuests": {
"numberOfAdults": 2
},
"applyPromotions": true,
"ignoreCalendar": false,
"ignoreTerms": false,
"ignoreBlocks": false,
"checkInDateLocalized": "2024-07-05",
"checkOutDateLocalized": "2024-07-22",
"listingId": "66054aa58ea6df0012a20b5e",
"source": "Booking Agent",
"guestsCount": 2
}',
CURLOPT_HTTPHEADER => array(
'accept: application/json',
'authorization: Bearer {accessToken}',
'content-type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import http.client
import json
conn = http.client.HTTPSConnection("open-api.guesty.com")
payload = json.dumps({
"guest": {
"firstName": "Shaquille",
"lastName": "O'Neal",
"phones": [
"+12135049876"
],
"email": "[email protected]"
},
"status": "confirmed",
"numberOfGuests": {
"numberOfAdults": 2
},
"applyPromotions": True,
"ignoreCalendar": False,
"ignoreTerms": False,
"ignoreBlocks": False,
"checkInDateLocalized": "2024-07-05",
"checkOutDateLocalized": "2024-07-22",
"listingId": "66054aa58ea6df0012a20b5e",
"source": "Booking Agent",
"guestsCount": 2
})
headers = {
'accept': 'application/json',
'authorization': 'Bearer {accessToken}',
'content-type': 'application/json'
}
conn.request("POST", "/v1/reservations-v3", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Response Example
{
"reservationId": "667bd0e80453caa11dd1628a",
"quoteId": "667bd0e60453caa11dd16283",
"confirmationCode": "GY-xaSEq3JG",
"status": "confirmed",
"guestId": "667bd0e635165f8770570547",
"numberOfGuests": {
"numberOfAdults": 2
},
"confirmedAt": "2024-06-26T08:27:20.104Z",
"creationTime": "2024-06-26T08:27:20.106Z",
"checkInDate": "2024-07-05T15:00:00.000Z",
"checkOutDate": "2024-07-22T10:00:00.000Z",
"unitTypeId": "66054aa58ea6df0012a20b5e",
"source": "Booking Agent",
"channel": "manual_reservations",
"guestsCount": 2
}
Use the Get reservations by IDs endpoint to retrieve the complete reservation details.
curl --globoff 'https://open-api.guesty.com/v1/reservations-v3?reservationIds[]=667bd0e80453caa11dd1628a' \
--header 'accept: application/json' \
--header 'authorization: Bearer {accessToken}'
const myHeaders = new Headers();
myHeaders.append("accept", "application/json");
myHeaders.append("authorization", "Bearer {accessToken}");
const requestOptions = {
method: "GET",
headers: myHeaders,
redirect: "manual"
};
fetch("https://open-api.guesty.com/v1/reservations-v3?reservationIds[]=667bd0e80453caa11dd1628a", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
var https = require('follow-redirects').https;
var fs = require('fs');
var options = {
'method': 'GET',
'hostname': 'open-api.guesty.com',
'path': '/v1/reservations-v3?reservationIds%5B%5D=667bd0e80453caa11dd1628a',
'headers': {
'accept': 'application/json',
'authorization': 'Bearer {accessToken}'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
req.end();
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://open-api.guesty.com/v1/reservations-v3?reservationIds[]=667bd0e80453caa11dd1628a',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'accept: application/json',
'authorization: Bearer {accessToken}'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import http.client
conn = http.client.HTTPSConnection("open-api.guesty.com")
payload = ''
headers = {
'accept': 'application/json',
'authorization': 'Bearer {accessToken}'
}
conn.request("GET", "/v1/reservations-v3?reservationIds%5B%5D=667bd0e80453caa11dd1628a", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Payment Method Validation
To validate whether the supplied payment method was accepted, add the query parameter:
payments=true
to your reservation retrieval request and an additionalpaymentMethods
array will be returned.
Reservation Updates
Queuing Subsequent Reservation Requests
Guesty recommends queuing your reservation updates with a 5 to 25 second delay between requests to allow Guesty to complete the processing of each one. Run tests to find your optimal delay.
The new API permits and provides dedicated endpoints for the following reservation updates:
- Update the booking status - Assign the appropriate status to a booking so that you're always up-to-date and aware of it at a glance.
- Update the guest stay status - Assign a status to reflect the progress of the guest's stay.
- Update reservation source - Change the source and point of sale field to reflect its origin and any related campaigns or interests.
- Update guest breakdown - Differentiate between, adults, children and infants.
- Alter stay dates - Shorten or lengthen the reservation as required.
- Add reservation notes - Add notes relevant to the stay to the reservation to ensure a smooth stay and turnover afterward.
- Populate custom fields - Upload the necessary information to the relevant reservation custom fields. You can retrieve the field IDs with the Get All Custom Fields request.
- Price Adjustments - Manually adjust existing invoice items.
- Invoice Items - Add an additional fee or tax to the reservation.
Payments
For GuestyPay and Stripe integrations, follow the guidance in these tokenization guides:
To record external payments or refunds and to learn how to post payments manually, refer to the following guides:
- Posting a Guest Payment
- Canceling or Editing a Scheduled Payment
- Refunding a Guest Payment
- Recording an External Guest Payment/Refund
Subscribe to our failed payments webhook to be notified of any reservation payment issues.
Troubleshooting
My quote returns a hardBlock
. What can it be?
Check your listing's calendar for any smart calendar rule block, owner's stay, or even another reservation. Check if your multi-unit has a reservation that is awaiting unit assignment.
Why is my reservation missing the supplied payment method?
Your payment processor rejected the provided payment method. Guesty will still create a reservation, regardless of the validity of the payment method. To receive alerts about payment issues, subscribe to our payment webhooks.
Why did Guesty accept a booking when my listing wasn't available?
Guesty permits you to override flexible blocks (not a hardBlock
). Check the quote response for any nonApplicable
rules that are true
and decide whether you wish to permit that block to be overridden else, treat it as unavailable, and don't proceed with the reservation creation.
Updated 2 days ago