Skip to main content

Create a Booking

The book endpoint creates a hotel reservation. Always quote the option immediately before booking to ensure accurate pricing and availability.

Endpoint

POST /connect/hotels/v1/booking

Request

Request Body Structure

The request body contains input and settings:

ParameterTypeDescription
inputobjectBooking input data (required)
settingsobjectRequest settings (required)

Booking Input

ParameterTypeDescription
optionRefIdstringOption reference ID from prebooking quote (required)
holderobjectBooking holder (main guest) information (required)
roomsarrayRoom configurations with guest details (required)
paymentCardobjectPayment card information (if required)
clientReferencestringYour internal booking reference
remarksarrayBooking remarks
priceDeltanumberPrice difference tolerance
additionalDataobjectAdditional parameters (optional)

Additional Data Parameters

ParameterTypeDescription
skipMarkupstringWhen "true", skip margin calculation. Suggested price equals net price.

Example Request

{
"input": {
"optionRefId": "OPT-123456789",
"holder": {
"name": "John",
"surname": "Doe",
"title": "MR"
},
"rooms": [
{
"occupancyRefId": 1,
"paxes": [
{
"name": "John",
"surname": "Doe",
"age": 35
},
{
"name": "Jane",
"surname": "Doe",
"age": 33
}
]
}
],
"paymentCard": {
"type": "VI",
"number": "4111111111111111",
"expire": {
"month": 12,
"year": 2027
},
"holder": {
"name": "John",
"surname": "Doe",
"contactInfo": {
"email": "john.doe@example.com",
"phone": {
"countryCode": "+34",
"number": "600123456"
}
}
}
},
"clientReference": "BOOKING-2025-001",
"remarks": [
{
"type": "GENERAL",
"value": "Late check-in requested"
}
]
},
"settings": {
"connectionCodes": ["testb-hbds-1876"],
"requestId": "book-001"
}
}

Response

Success Response

{
"booking": {
"bookingID": "BK-987654321",
"status": "CONFIRMED",
"clientReference": "BOOKING-2025-001",
"hotel": {
"code": "12345",
"name": "Example Hotel Barcelona"
},
"stay": {
"checkIn": "2025-06-15",
"checkOut": "2025-06-17"
},
"rooms": [
{
"description": "Standard Double Room",
"boardCode": "BB",
"confirmationReference": "ROOM-001",
"paxes": [
{
"name": "John",
"surname": "Doe",
"age": 35
},
{
"name": "Jane",
"surname": "Doe",
"age": 33
}
]
}
],
"holder": {
"name": "John",
"surname": "Doe",
"email": "john.doe@example.com",
"phone": "+34600123456"
},
"price": {
"currency": "EUR",
"net": 150.00,
"suggested": 150.00,
"gross": 150.00,
"markupGross": 180.00,
"markupNet": 180.00,
"markupCurrency": "EUR",
"markupBinding": true,
"marginAmount": 30.00,
"marginPercent": 20.0,
"marginType": "PERCENTAGE"
},
"cancelPolicy": {
"refundable": true,
"cancelPenalties": []
},
"remarks": ["Late check-in requested"],
"createdAt": "2025-06-01T10:30:00Z",
"updatedAt": "2025-06-01T10:30:00Z"
},
"warnings": [],
"errors": []
}

On Request Response

Some bookings require provider confirmation:

{
"booking": {
"bookingID": "BK-987654321",
"status": "ON_REQUEST",
"reference": {
"bookingID": "BK-987654321"
},
...
},
"warnings": [
{
"code": "ON_REQUEST",
"description": "Booking requires provider confirmation"
}
]
}

Key Fields

Booking Status

StatusDescription
CONFIRMEDBooking confirmed by provider
PENDINGBooking request submitted, awaiting confirmation
ON_REQUESTProvider needs to manually confirm
FAILEDBooking could not be completed

Booking References

Store these references for later operations:

  • bookingID - Bundleport booking ID (use for retrieve, cancel)
  • clientReference - Your internal reference
  • clientReference - Your internal booking reference (if provided)

Holder Information

The holder is the main guest and booking contact:

  • Required: name, surname, email
  • Optional: phone, nationality
  • Used for: booking confirmation, hotel communication

Guest Information (Paxes)

For each room, provide guest details:

  • Adults: name, surname, age (optional)
  • Children: name, surname, age (required)
  • Type: "ADULT" or "CHILD"

Payment Card

Required for some providers. Include:

  • Type: Card type (VI, MC, AX, etc.)
  • Number: Card number
  • Expire: Expiration month and year
  • Holder: Cardholder name

Best Practices

1. Always Quote Before Booking

// ✅ Good - Quote then book
const quote = await quoteOption(optionRefId);
if (quote.errors?.length > 0) {
throw new Error('Option no longer available');
}
const booking = await bookOption(optionRefId, travellerData);

// ❌ Bad - Book without quoting
const booking = await bookOption(optionRefId, travellerData);
// May fail if price changed or option expired

2. Store All References

const booking = await bookOption(optionRefId, travellerData);

// Store all references
await saveBooking({
bundleportId: booking.booking.bookingID,
clientReference: booking.booking.clientReference,
status: booking.booking.status,
});

3. Handle On Request Bookings

const booking = await bookOption(optionRefId, travellerData);

if (booking.booking.status === 'ON_REQUEST') {
// Inform user that confirmation is pending
await notifyUser({
message: 'Your booking is being confirmed. You will receive an email when confirmed.',
bookingId: booking.booking.bookingID,
});

// Set up webhook or polling to check status
await monitorBookingStatus(booking.booking.bookingID);
}

4. Validate Guest Information

function validateGuests(rooms, occupancies) {
for (let i = 0; i < rooms.length; i++) {
const room = rooms[i];
const occupancy = occupancies[i];

// Check total guests match
const totalGuests = room.paxes.length;
const expectedTotal = occupancy.adults + (occupancy.children || 0);

if (totalGuests !== expectedTotal) {
throw new Error(`Room ${i + 1}: Expected ${expectedTotal} guests, got ${totalGuests}`);
}

// Check children ages
const children = room.paxes.filter(p => p.type === 'CHILD' || p.age < 18);
if (children.length !== (occupancy.children || 0)) {
throw new Error(`Room ${i + 1}: Children count mismatch`);
}
}
}

Code Examples

curl -X POST https://api.bundleport.com/connect/hotels/v1/booking \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"optionRefId": "OPT-123456789",
"holder": {
"name": "John",
"surname": "Doe",
"title": "MR"
},
"rooms": [
{
"occupancyRefId": 1,
"paxes": [
{ "name": "John", "surname": "Doe", "age": 35 },
{ "name": "Jane", "surname": "Doe", "age": 33 }
]
}
]
},
"settings": {
"connectionCodes": ["testb-hbds-1876"]
}
}'

Next Steps