Content Catalog Overview
The Content API provides access to static and semi-static hotel catalog data. Use it to build search filters, display hotel information, and synchronize your local catalog.
What is Content API?
The Content API serves catalog data that doesn't change frequently:
- Hotels – Hotel information, descriptions, amenities, media, and geo enrichment (canonical city, country, closest destinations, region)
- Rooms – Room types, descriptions, images, occupancy details
- Destinations – Cities, regions, airports with hierarchical structure
- Boards – Meal plans (RO, BB, HB, FB, AI)
- Categories – Hotel categories and classifications
Hotel responses include location enrichment when available: countryName, canonicalCityPlaceId, region, closestDestinations (e.g. city and region names), locationPath (breadcrumb like "Madrid, Community of Madrid, Spain"), and optional POI distances (airport, beach, train station).
Content vs Transactional
Content API (Static/Semi-Static)
- Update Frequency: Daily or on-demand sync
- Use Case: Display hotel information, build search filters
- Endpoints:
/content/hotels/v1/* - Caching: Safe to cache for hours or days
Booking API (Dynamic)
- Update Frequency: Real-time per request
- Use Case: Search availability, book, cancel
- Endpoints:
/hotels/v1/* - Caching: Not recommended (always real-time)
Content Structure
Content Catalog
├── Hotels
│ ├── Basic info (name, description, location)
│ ├── Amenities, media, rooms
│ ├── Geo enrichment (canonical city, country, region, closest destinations)
│ └── Optional: POI distances, locationPath, imageBaseUrl
├── Rooms
│ ├── Description, images, occupancy, bed configuration
├── Destinations
│ ├── Hierarchical structure (country → region → city)
│ └── Geographic coordinates
├── Boards
│ └── Meal plan definitions
└── Categories
└── Hotel classifications
Hotel endpoints
POST /content/hotels/v1/hotels– List or get hotels by query (connection, codes, destination, etc.). Preferscopeoverqueryfor filters.POST /content/hotels/v1/hotels/by-base-codes– Get hotel content by Bundleport base codes (e.g. for mapping/base-code–based UIs). Supports preferred content source and multiple sources per hotel.POST /content/hotels/v1/hotels/filter– Filter hotel codes by criteria (canonical city, country, categories, boards, nearby, etc.) with keyset pagination. Use before availability search to reduce payload.
Common Use Cases
1. Build Search Filters
// Get available destinations for dropdown
const destinations = await getDestinations({
query: { maxSize: 100 },
});
// Get available board types
const boards = await getBoards({
query: {},
});
// Build search UI with filters
buildSearchFilters({
destinations: destinations.destinations.destinations,
boards: boards.boards.boards,
});
2. Display Hotel Information
// Get hotel details for detail page
const hotel = await getHotels({
query: {
hotelCodes: ['12345'],
},
});
// Display hotel information
displayHotelDetails({
name: hotel.hotels.hotels[0].hotelName,
description: hotel.hotels.hotels[0].descriptions,
amenities: hotel.hotels.hotels[0].amenities,
images: hotel.hotels.hotels[0].media,
});
3. Synchronize Local Catalog
// Initial sync - get all hotels
let token = null;
let allHotels = [];
do {
const result = await getHotels({
query: { maxSize: 1000 },
token,
});
allHotels.push(...result.hotels.hotels);
token = result.hotels.token;
} while (token);
// Store in local database
await syncHotelsToDatabase(allHotels);
Filtering and Pagination
All content endpoints support:
- Filtering by connection code - Get content for specific providers
- Filtering by codes - Get specific hotels, rooms, destinations
- Pagination - Use tokens for large result sets
- Max size - Limit number of results per request
Example: Filtered query (prefer scope)
{
"scope": {
"connectionCode": "CONN_1",
"hotelCodes": ["12345", "67890"],
"maxSize": 50
},
"token": null
}
Use scope as the preferred field for filters; query is supported for backwards compatibility. When connectionCode is set, the provider is resolved automatically (use X-Environment: test or prod as needed).
Pagination with Tokens
Content API uses token-based pagination:
// First page
const page1 = await getHotels({
query: { maxSize: 100 },
token: null,
});
// Next page
const page2 = await getHotels({
query: { maxSize: 100 },
token: page1.hotels.token, // Use token from previous response
});
// Continue until token is null
Important:
- Tokens are valid for 4 minutes
- Tokens are tied to the original query criteria
- If query changes, start with a new token (null)
Best Practices
1. Cache Content Data
// Cache destinations for 24 hours
const destinations = await cache.get('destinations', async () => {
return await getDestinations({ query: {} });
}, { ttl: 24 * 60 * 60 * 1000 }); // 24 hours
2. Incremental Sync
// Sync only changed content
const auditHistory = await getScopeAuditHistory({
contentType: 'hotel',
contentID: '12345',
limit: 100,
});
// Update only changed hotels
for (const record of auditHistory.auditRecords) {
if (record.action === 'updated') {
await syncHotel(record.contentID);
}
}
3. Batch Requests
// Get multiple hotels in one request
const hotels = await getHotels({
query: {
hotelCodes: ['12345', '67890', '11111'],
maxSize: 100,
},
});
Endpoints
| Endpoint | Description |
|---|---|
| Hotels | List/get hotels; pagination with token |
| Hotels by base codes | Get content by Bundleport base codes |
| Hotel filter | Filter hotel codes (geo, categories, boards, etc.) |
| Rooms | Room types and details |
| Destinations | Locations and hierarchy |
| Boards | Meal plans |
| Categories | Hotel categories |
Next Steps
- Hotels Catalog – Access hotel information, by-base-codes, and filter
- Rooms Catalog – Get room type details
- Content API Reference – Full request/response schemas and parameters