Java SDK
The Bundleport Java SDK provides a type-safe client for the Connect Hotels REST API with support for both reactive (Spring WebFlux) and blocking operations.
Install
Gradle
dependencies {
implementation("com.bundleport:connect-hotels-sdk:<version>")
}
Maven
<dependency>
<groupId>com.bundleport</groupId>
<artifactId>connect-hotels-sdk</artifactId>
<version>${bundleport.version}</version>
</dependency>
Initialize the Client
Blocking Client
import com.bundleport.client.BundleportClient;
import com.bundleport.client.ClientConfig;
import java.time.Duration;
ClientConfig config = ClientConfig.builder()
.apiKey("YOUR_API_KEY_HERE")
.baseUrl("https://api.bundleport.com") // Optional
.timeout(Duration.ofSeconds(30)) // Optional
.build();
BundleportClient client = new BundleportClient(config);
Reactive Client (Spring WebFlux)
import com.bundleport.client.reactive.ReactiveBundleportClient;
import org.springframework.web.reactive.function.client.WebClient;
WebClient webClient = WebClient.builder()
.baseUrl("https://api.bundleport.com")
.build();
ReactiveBundleportClient client = new ReactiveBundleportClient(
webClient,
"YOUR_API_KEY_HERE"
);
Booking Operations
Search for Hotels
SearchRequest request = SearchRequest.builder()
.stay(Stay.builder()
.checkIn("2025-06-15")
.checkOut("2025-06-17")
.build())
.destination(Destination.builder()
.code("BCN")
.build())
.occupancies(List.of(
Occupancy.builder()
.adults(2)
.children(1)
.childrenAges(List.of(8))
.build()
))
.filters(SearchFilters.builder()
.currency("EUR")
.minPrice(100)
.maxPrice(300)
.build())
.settings(Settings.builder()
.accessIds(List.of("ACCESS_1"))
.build())
.build();
SearchResponse result = client.hotels().search(request);
System.out.println("Found " + result.getOptions().size() + " options");
Quote an Option
QuoteRequest quoteRequest = QuoteRequest.builder()
.optionRefId(result.getOptions().get(0).getOptionRefId())
.settings(Settings.builder()
.accessIds(List.of("ACCESS_1"))
.build())
.build();
QuoteResponse quoteResult = client.hotels().quote(quoteRequest);
// Check for price changes
boolean priceChanged = quoteResult.getWarnings().stream()
.anyMatch(w -> "PRICE_CHANGED".equals(w.getCode()));
if (priceChanged) {
System.out.println("Price has changed: " + quoteResult.getPrice());
}
Create a Booking
BookRequest bookRequest = BookRequest.builder()
.optionRefId(quoteResult.getOptionQuote().getOptionRefId())
.holder(Holder.builder()
.name("John")
.surname("Doe")
.email("john.doe@example.com")
.phone("+34600123456")
.build())
.rooms(List.of(
BookRoom.builder()
.occupancyRefId(1)
.paxes(List.of(
Pax.builder().name("John").surname("Doe").age(35).build(),
Pax.builder().name("Jane").surname("Doe").age(33).build()
))
.build()
))
.paymentCard(PaymentCard.builder()
.type("VI")
.number("4111111111111111")
.expire(CardExpire.builder().month(12).year(2027).build())
.holder(CardHolder.builder().name("John").surname("Doe").build())
.build())
.clientReference("BOOKING-2025-001")
.build();
BookResponse booking = client.hotels().book(bookRequest);
System.out.println("Booking confirmed: " + booking.getBooking().getId());
Reactive Usage
import reactor.core.publisher.Mono;
Mono<SearchResponse> searchMono = reactiveClient.hotels().search(request);
Mono<QuoteResponse> quoteMono = searchMono.flatMap(result ->
reactiveClient.hotels().quote(QuoteRequest.builder()
.optionRefId(result.getOptions().get(0).getOptionRefId())
.build())
);
quoteMono.subscribe(
quote -> System.out.println("Quote received: " + quote.getPrice()),
error -> System.err.println("Error: " + error.getMessage())
);
Content Operations
Get Hotels
HotelsRequest hotelsRequest = HotelsRequest.builder()
.query(HotelListQuery.builder()
.destinationCodes(List.of("BCN"))
.maxSize(100)
.build())
.build();
HotelsResponse hotels = client.content().getHotels(hotelsRequest);
System.out.println("Found " + hotels.getHotels().getHotels().size() + " hotels");
Error Handling
import com.bundleport.exceptions.BundleportException;
import com.bundleport.exceptions.UnauthorizedException;
import com.bundleport.exceptions.RateLimitException;
try {
SearchResponse result = client.hotels().search(request);
} catch (UnauthorizedException e) {
System.err.println("Invalid API key");
} catch (RateLimitException e) {
System.err.println("Rate limit exceeded, retry after: " + e.getRetryAfter() + " seconds");
} catch (BundleportException e) {
System.err.println("API error: " + e.getMessage());
}
Next Steps
- REST API Reference - Complete endpoint documentation
- Content API Reference - Content catalog endpoints
- Error Handling Guide - Learn how to handle errors