Skip to main content

C# SDK

The Bundleport C# SDK provides a type-safe client for the Connect Hotels REST API with full .NET support and dependency injection.

Install

dotnet add package Bundleport.ConnectHotels.Sdk

Initialize the Client

Direct Instantiation

using Bundleport.ConnectHotels;

var client = new BundleportClient(new ClientOptions
{
ApiKey = "YOUR_API_KEY_HERE",
BaseUrl = "https://api.bundleport.com", // Optional
Timeout = TimeSpan.FromSeconds(30), // Optional
});

Dependency Injection (ASP.NET Core)

using Bundleport.ConnectHotels;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddBundleportClient(options =>
{
options.ApiKey = builder.Configuration["Bundleport:ApiKey"];
options.BaseUrl = "https://api.bundleport.com";
options.Timeout = TimeSpan.FromSeconds(30);
});

Inject IBundleportClient in your controllers:

public class HotelsController : ControllerBase
{
private readonly IBundleportClient _client;

public HotelsController(IBundleportClient client) => _client = client;

[HttpPost("/search")]
public async Task<IActionResult> Search([FromBody] SearchRequest request)
{
var response = await _client.Hotels.SearchAsync(request);
return Ok(response);
}
}

Booking Operations

Search for Hotels

var searchRequest = new SearchRequest
{
Stay = new Stay
{
CheckIn = "2025-06-15",
CheckOut = "2025-06-17"
},
Destination = new Destination
{
Code = "BCN"
},
Occupancies = new List<Occupancy>
{
new Occupancy
{
Adults = 2,
Children = 1,
ChildrenAges = new List<int> { 8 }
}
},
Filters = new SearchFilters
{
Currency = "EUR",
MinPrice = 100,
MaxPrice = 300
},
Settings = new Settings
{
AccessIds = new List<string> { "ACCESS_1" }
}
};

var searchResult = await client.Hotels.SearchAsync(searchRequest);
Console.WriteLine($"Found {searchResult.Options.Count} options");

Quote an Option

var quoteRequest = new QuoteRequest
{
OptionRefId = searchResult.Options[0].OptionRefId,
Settings = new Settings
{
AccessIds = new List<string> { "ACCESS_1" }
}
};

var quoteResult = await client.Hotels.QuoteAsync(quoteRequest);

// Check for price changes
if (quoteResult.Warnings?.Any(w => w.Code == "PRICE_CHANGED") == true)
{
Console.WriteLine($"Price has changed: {quoteResult.Price.Net}");
}

Create a Booking

var bookRequest = new BookRequest
{
OptionRefId = quoteResult.OptionQuote.OptionRefId,
Holder = new Holder
{
Name = "John",
Surname = "Doe",
Email = "john.doe@example.com",
Phone = "+34600123456"
},
Rooms = new List<BookRoom>
{
new BookRoom
{
OccupancyRefId = 1,
Paxes = new List<Pax>
{
new Pax { Name = "John", Surname = "Doe", Age = 35 },
new Pax { Name = "Jane", Surname = "Doe", Age = 33 }
}
}
},
PaymentCard = new PaymentCard
{
Type = "VI",
Number = "4111111111111111",
Expire = new CardExpire { Month = 12, Year = 2027 },
Holder = new CardHolder { Name = "John", Surname = "Doe" }
},
ClientReference = "BOOKING-2025-001"
};

var booking = await client.Hotels.BookAsync(bookRequest);
Console.WriteLine($"Booking confirmed: {booking.Booking.Id}");

Retrieve Booking

var bookingDetails = await client.Hotels.GetBookingAsync("BK-987654321");
Console.WriteLine($"Booking status: {bookingDetails.Booking.Status}");

List Bookings

var listRequest = new BookingListRequest
{
Filters = new BookingListFilters
{
Status = new List<string> { "CONFIRMED" },
DateRange = new DateRange
{
From = "2025-06-01",
To = "2025-06-30"
}
},
Pagination = new Pagination
{
Page = 1,
PageSize = 20
}
};

var bookings = await client.Hotels.ListBookingsAsync(listRequest);
Console.WriteLine($"Found {bookings.Bookings.Count} bookings");

Cancel Booking

var cancelResult = await client.Hotels.CancelAsync("BK-987654321", new CancelRequest
{
Reason = "Customer request",
CancelPenalty = new CancelPenalty { Apply = true }
});

if (cancelResult.Booking.CancelInfo?.Penalty != null)
{
var penalty = cancelResult.Booking.CancelInfo.Penalty;
Console.WriteLine($"Cancellation penalty: {penalty.Amount} {penalty.Currency}");
}

Content Operations

Get Hotels

var hotelsRequest = new HotelsRequest
{
Query = new HotelListQuery
{
DestinationCodes = new List<string> { "BCN" },
MaxSize = 100
}
};

var hotels = await client.Content.GetHotelsAsync(hotelsRequest);
Console.WriteLine($"Found {hotels.Hotels.Hotels.Count} hotels");

Error Handling

using Bundleport.Exceptions;

try
{
var result = await client.Hotels.SearchAsync(request);
}
catch (UnauthorizedException)
{
Console.Error.WriteLine("Invalid API key");
}
catch (RateLimitException ex)
{
Console.Error.WriteLine($"Rate limit exceeded, retry after: {ex.RetryAfter} seconds");
}
catch (BundleportException ex)
{
Console.Error.WriteLine($"API error: {ex.Message}");
}

Next Steps