Skip to main content

Go SDK

The Bundleport Go SDK provides a type-safe client for the Connect Hotels REST API.

Install

go get github.com/bundleport/connect-hotels-sdk

Initialize the Client

package main

import (
"context"
"time"

"github.com/bundleport/connect-hotels-sdk"
)

func main() {
client := bundleport.NewClient(
bundleport.WithAPIKey("YOUR_API_KEY_HERE"),
bundleport.WithBaseURL("https://api.bundleport.com"), // Optional
bundleport.WithTimeout(30*time.Second), // Optional
)

// Use the client...
}

Booking Operations

Search for Hotels

ctx := context.Background()

searchResult, err := client.Hotels.Search(ctx, bundleport.SearchRequest{
Stay: bundleport.Stay{
CheckIn: "2025-06-15",
CheckOut: "2025-06-17",
},
Destination: bundleport.Destination{
Code: "BCN",
},
Occupancies: []bundleport.Occupancy{
{
Adults: 2,
Children: 1,
ChildrenAges: []int{8},
},
},
Filters: &bundleport.SearchFilters{
Currency: "EUR",
MinPrice: 100,
MaxPrice: 300,
},
Settings: &bundleport.Settings{
AccessIds: []string{"ACCESS_1"},
},
})
if err != nil {
log.Fatal(err)
}

fmt.Printf("Found %d options\n", len(searchResult.Options))

Quote an Option

quoteResult, err := client.Hotels.Quote(ctx, bundleport.QuoteRequest{
OptionRefId: searchResult.Options[0].OptionRefId,
Settings: &bundleport.Settings{
AccessIds: []string{"ACCESS_1"},
},
})
if err != nil {
log.Fatal(err)
}

// Check for price changes
for _, warning := range quoteResult.Warnings {
if warning.Code == "PRICE_CHANGED" {
fmt.Println("Price has changed:", quoteResult.Price)
}
}

Create a Booking

booking, err := client.Hotels.Book(ctx, bundleport.BookRequest{
OptionRefId: quoteResult.OptionQuote.OptionRefId,
Holder: bundleport.Holder{
Name: "John",
Surname: "Doe",
Email: "john.doe@example.com",
Phone: "+34600123456",
},
Rooms: []bundleport.BookRoom{
{
OccupancyRefId: 1,
Paxes: []bundleport.Pax{
{Name: "John", Surname: "Doe", Age: 35},
{Name: "Jane", Surname: "Doe", Age: 33},
},
},
},
PaymentCard: &bundleport.PaymentCard{
Type: "VI",
Number: "4111111111111111",
Expire: bundleport.CardExpire{Month: 12, Year: 2027},
Holder: bundleport.CardHolder{Name: "John", Surname: "Doe"},
},
ClientReference: "BOOKING-2025-001",
})
if err != nil {
log.Fatal(err)
}

fmt.Printf("Booking confirmed: %s\n", booking.Booking.ID)

Retrieve Booking

bookingDetails, err := client.Hotels.GetBooking(ctx, "BK-987654321")
if err != nil {
log.Fatal(err)
}

fmt.Printf("Booking status: %s\n", bookingDetails.Booking.Status)

List Bookings

bookings, err := client.Hotels.ListBookings(ctx, bundleport.BookingListRequest{
Filters: &bundleport.BookingListFilters{
Status: []string{"CONFIRMED"},
DateRange: &bundleport.DateRange{
From: "2025-06-01",
To: "2025-06-30",
},
},
Pagination: &bundleport.Pagination{
Page: 1,
PageSize: 20,
},
})
if err != nil {
log.Fatal(err)
}

fmt.Printf("Found %d bookings\n", len(bookings.Bookings))

Cancel Booking

cancelResult, err := client.Hotels.Cancel(ctx, "BK-987654321", bundleport.CancelRequest{
Reason: "Customer request",
CancelPenalty: bundleport.CancelPenalty{
Apply: true,
},
})
if err != nil {
log.Fatal(err)
}

if cancelResult.Booking.CancelInfo.Penalty != nil {
penalty := cancelResult.Booking.CancelInfo.Penalty
fmt.Printf("Cancellation penalty: %.2f %s\n", penalty.Amount, penalty.Currency)
}

Content Operations

Get Hotels

hotels, err := client.Content.GetHotels(ctx, bundleport.HotelsRequest{
Query: &bundleport.HotelListQuery{
DestinationCodes: []string{"BCN"},
MaxSize: 100,
},
})
if err != nil {
log.Fatal(err)
}

fmt.Printf("Found %d hotels\n", len(hotels.Hotels.Hotels))

Error Handling

import "github.com/bundleport/connect-hotels-sdk/errors"

result, err := client.Hotels.Search(ctx, request)
if err != nil {
var apiErr *errors.APIError
if errors.As(err, &apiErr) {
switch apiErr.Code {
case "UNAUTHORIZED":
log.Fatal("Invalid API key")
case "RATE_LIMIT_EXCEEDED":
log.Printf("Rate limit exceeded, retry after: %d seconds", apiErr.RetryAfter)
default:
log.Printf("API error: %s", apiErr.Message)
}
} else {
log.Fatal(err)
}
}

Next Steps