Developers
Public API reference
Connect your CRM, invoicing system, or other tools to your Book2dream data — bookings, guests, programs, rooms, availability, and fares.
1Getting started
The Book2dream Public API lets a hotel connect its own CRM, invoicing system, or other external tools to its Book2dream data — bookings, guests, programs, rooms, availability, and fares.
Every request goes over HTTPS to https://api.book2dream.com/public/v1, and both requests and responses are JSON.
The API is scoped to a single hotel: a key you create belongs to exactly one property, and every response it returns is limited to that property's data.
2GETAuthentication
Generate a key from your Book2dream dashboard, under Settings → API Keys. The full secret is shown once, at creation — store it somewhere safe, since it can't be retrieved again afterward.
Send it as a bearer token on every request:
Example request
curl https://api.book2dream.com/public/v1/auth/introspect \
-H "Authorization: Bearer sk_live_..."Example response
{
"hotelId": 1034,
"hotelName": "Hotel Example",
"keyName": "Zapier integration",
"permissions": {
"canGetBookingsList": true,
"canGetBooking": true,
"canGetGuestsList": false,
"canGetGuest": false,
"canGetPrograms": true,
"canGetRooms": true,
"canGetAvailability": true,
"canGetFares": true,
"canPostFare": false
},
"expiresAt": null
}3Permissions model
Keys are scoped per endpoint, not just per resource: when you create a key, you choose exactly which of the endpoints below it may call. There's no implicit read/write split — Get Bookings and Get Booking, for example, are two separate permissions, so a key can list bookings without ever seeing an individual booking's guest details.
A request to an endpoint your key isn't permitted for returns a 403 with a machine-readable error body (see below). Authentication itself isn't a permission — any active, non-revoked key can always call the introspection endpoint above.
- Every error on this API — including permission and rate-limit errors — follows the same shape: { "error": { "code", "message", "statusCode" } }.
- Requests are rate-limited per key. If you exceed your limit you'll get a 429 with a Retry-After header.
4GETGET /bookings
Returns a paginated list of this hotel's bookings.
Permission required: Get Bookings (list)
| Name | Type | Required | Description |
|---|---|---|---|
| pageNumber | integer | Optional | 1-indexed page number. Defaults to 1. |
| pageSize | integer | Optional | Results per page, up to 50. Defaults to 30. |
Example request
curl "https://api.book2dream.com/public/v1/bookings?pageSize=30" \
-H "Authorization: Bearer sk_live_..."Example response
{
"data": [
{
"id": 58231,
"reservationCode": "B2D-58231",
"date": "2026-08-12",
"checkIn": "2026-09-01",
"checkOut": "2026-09-05",
"bookingStatus": "CONFIRMED",
"guestBookingStatus": "PENDING_CHECK_IN",
"adults": 2,
"children": 0,
"infants": 0,
"numberOfRooms": 1,
"numberOfnights": 4,
"subtotal": "620.00",
"taxes": "0.00",
"finalPrice": "620.00",
"bookingChannel": "DIRECT"
}
],
"metadata": { "count": 214, "pageSize": 30, "pageNumber": 1, "totalPages": 8 }
}Personal data: This endpoint does not include guest personal data — see GET Booking for the single-resource form, which does.
5GETGET /bookings/{id}
Returns one booking, including the full guest record attached to it.
Permission required: Get Booking (single)
Example request
curl https://api.book2dream.com/public/v1/bookings/58231 \
-H "Authorization: Bearer sk_live_..."Example response
{
"id": 58231,
"reservationCode": "B2D-58231",
"checkIn": "2026-09-01",
"checkOut": "2026-09-05",
"bookingStatus": "CONFIRMED",
"finalPrice": "620.00",
"especialRequest": "Late check-in, arriving around 11pm",
"guest": {
"id": 9021,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com",
"phone": "+1 555 0100",
"country": "US",
"status": "CONFIRMED"
}
}Personal data: Includes the guest's name, contact details, and other personal data. Requires the Get Booking permission specifically — separate from Get Bookings (list).
6GETGET /guests
Returns a paginated list of guests who have booked at this hotel.
Permission required: Get Guests (list)
| Name | Type | Required | Description |
|---|---|---|---|
| pageNumber | integer | Optional | 1-indexed page number. Defaults to 1. |
| pageSize | integer | Optional | Results per page, up to 50. Defaults to 30. |
Example request
curl "https://api.book2dream.com/public/v1/guests?pageSize=30" \
-H "Authorization: Bearer sk_live_..."Example response
{
"data": [
{ "id": 9021, "status": "CONFIRMED" }
],
"metadata": { "count": 512, "pageSize": 30, "pageNumber": 1, "totalPages": 18 }
}Personal data: The list form omits personal data entirely — no name, email, or phone. See GET Guest for the single-resource form, which includes it.
7GETGET /guests/{id}
Returns one guest's full record.
Permission required: Get Guest (single)
Example request
curl https://api.book2dream.com/public/v1/guests/9021 \
-H "Authorization: Bearer sk_live_..."Example response
{
"id": 9021,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com",
"phone": "+1 555 0100",
"fiscalNumber": "",
"city": "Austin",
"country": "US",
"state": "TX",
"postalCode": "78701",
"status": "CONFIRMED"
}Personal data: Includes the guest's personal data. Requires the Get Guest permission specifically — separate from Get Guests (list).
8GETGET /programs
Returns every rate program available at this hotel.
Permission required: Get Programs
Example request
curl https://api.book2dream.com/public/v1/programs \
-H "Authorization: Bearer sk_live_..."Example response
[
{
"id": 595,
"name": "Room Only",
"description": "Non-refundable, room only",
"minNightsStay": 2,
"minBookingAnticipation": 0,
"externalCode": "NRF-RO",
"channexMealType": "NONE"
}
]9GETGET /rooms
Returns every room type configured at this hotel.
Permission required: Get Rooms
Example request
curl https://api.book2dream.com/public/v1/rooms \
-H "Authorization: Bearer sk_live_..."Example response
[
{
"id": 586,
"name": "Single Room",
"isActive": true,
"quantity": 6,
"bedroomsQuantity": 1,
"bathroomsQuantity": 1,
"maximumGuests": 2,
"limitOnChildren": 1,
"limitOnAdults": 2,
"externalCode": "SGL"
}
]10GETGET /availability
Returns per-day stock for one or more rooms over a date range. A date with no explicit stock row is still bookable — it falls back to the room's total quantity — so `availableStock` always reflects what's actually left to sell, not just what's been explicitly configured.
Permission required: Get Availability
| Name | Type | Required | Description |
|---|---|---|---|
| roomIds | integer[] | Required | Comma-separated room ids, all must belong to your hotel. |
| dateFrom | date | Required | Inclusive start date, YYYY-MM-DD. |
| dateTo | date | Required | Exclusive end date, YYYY-MM-DD. |
Example request
curl "https://api.book2dream.com/public/v1/availability?roomIds=586&dateFrom=2026-09-01&dateTo=2026-09-05" \
-H "Authorization: Bearer sk_live_..."Example response
[
{ "roomId": 586, "date": "2026-09-01", "roomQuantity": 6, "fixedStock": 6, "bookingCount": 2, "availableStock": 4 },
{ "roomId": 586, "date": "2026-09-02", "roomQuantity": 6, "fixedStock": 6, "bookingCount": 3, "availableStock": 3 }
]11GETGET /fares
Returns every fare configured at this hotel, across all rooms and programs.
Permission required: Get Fares (list)
Example request
curl https://api.book2dream.com/public/v1/fares \
-H "Authorization: Bearer sk_live_..."Example response
[
{
"id": 4410,
"name": "Standard Rate",
"adults": 2,
"children": 0,
"infants": 0,
"validFrom": "2026-01-01",
"validTo": "2026-12-31",
"checkInFrom": "2026-01-01",
"checkInTo": "2026-12-31",
"isActive": true,
"fixedPrice": false,
"mondayPrice": "120.00",
"roomId": 586,
"segmentId": 12,
"programId": 595,
"paymentPolicyId": 3,
"cancellationPolicyId": 2
}
]12POSTPOST /fares
Creates a fare — the only mutating endpoint in v1. It has the same field surface as the internal admin's fare creation, including day-of-week pricing and the linked room, program, segment, cancellation policy, and payment policy: every id you send must belong to (or be usable by) your hotel, or the request is rejected with a 400.
A successful call creates a real, versioned fare — the same immutable-snapshot mechanism the internal admin panel relies on for rate history — so treat it with the same care you would a change made directly in the dashboard.
Permission required: Post Fare (create)
| Name | Type | Required | Description |
|---|---|---|---|
| roomId | integer | Required | Must belong to your hotel. |
| segmentId | integer | Required | Must belong to your hotel. |
| programId | integer | Required | Must be assigned to roomId. |
| paymentPolicyId | integer | Required | Must be available for segmentId. |
| cancellationPolicyId | integer | Required | Must be available for segmentId. |
| name | string | Required | Fare name. |
| adults / children / infants | integer | Required | Party size this fare is priced for. |
| fixedPrice | boolean | Optional | When true, price is per room regardless of party size. |
| validFrom / validTo | date | Required | When the fare can be booked. |
| checkInFrom / checkInTo | date | Required | Which check-in dates this fare covers. |
| mondayPrice … sundayPrice | decimal | Optional | Per-day-of-week base price. |
Example request
curl -X POST https://api.book2dream.com/public/v1/fares \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Standard Rate",
"description": "Standard flexible rate",
"adults": 2,
"children": 0,
"infants": 0,
"fixedPrice": false,
"validFrom": "2026-01-01",
"validTo": "2026-12-31",
"checkInFrom": "2026-01-01",
"checkInTo": "2026-12-31",
"mondayPrice": 120,
"tuesdayPrice": 120,
"wednesdayPrice": 120,
"thursdayPrice": 120,
"fridayPrice": 150,
"saturdayPrice": 150,
"sundayPrice": 130,
"roomId": 586,
"segmentId": 12,
"programId": 595,
"paymentPolicyId": 3,
"cancellationPolicyId": 2,
"seasonFaresId": []
}'Example response
{
"id": 4489,
"name": "Standard Rate",
"isActive": true,
"fixedPrice": false,
"roomId": 586,
"segmentId": 12,
"programId": 595,
"paymentPolicyId": 3,
"cancellationPolicyId": 2
}