Skip to main content
OpenBookings takes you from a blank search box to a confirmed reservation in a handful of steps. This guide walks through each stage of the flow, explains what information you’ll see at every point, and shows you how to replicate the same search programmatically using the public API.

The booking flow at a glance

1

Open the app and enter a destination

When you land on OpenBookings, you’ll see a search panel in the bottom-right corner. Click the Destination field and start typing a city name. A typeahead list of matching cities appears — select the one you want. The app records the destination’s geographic coordinates (latitude and longitude) internally; these are what drive the hotel search radius.
2

Select your check-in and check-out dates

Click the date field (labelled From / Till) to open the calendar picker. Tap your check-in date first, then your check-out date. Both dates are stored in YYYY-MM-DD format. The number of nights is derived automatically from the difference between the two dates.
Dates are interpreted in your local timezone. The calendar always shows the date as you selected it — no UTC conversion surprises.
3

Set your guest count and number of rooms

Click the guests field to open the Guest Selector. Use the + and buttons to set:
FieldDefinitionMinimum
AdultsGuests aged 13 or above0
ChildrenGuests aged 0–120
RoomsNumber of separate rooms needed1
The selector defaults to 2 adults, 0 children, 1 room on first load. Only rooms whose max_adults ≥ your adult count and max_children ≥ your child count are returned in results — the API filters unsuitable rooms before they ever reach you.
4

Run the search

Click Find my trip. The app sends your destination coordinates, dates, and guest counts to GET /api/query and displays the matching hotels.
5

Review search results

Each result card shows the best-priced available room for that hotel. Here’s what every field on a result means:
FieldWhat it tells you
hotel_name / property_nameThe name of the hotel
cityThe city the hotel is in
room_nameThe specific room type being quoted
room_descriptionA short description of the room
price_per_nightThe starting nightly rate (base price before modifiers) displayed on the card
total_priceThe full stay cost after all applicable pricing modifiers
currencyISO 4217 currency code (e.g. EUR, USD)
is_refundableWhether the rate allows cancellation for a refund
cancellation_policyHuman-readable cancellation terms
rate_plan_nameThe name of the rate plan that produced this price
Results are sorted by total_price ascending, and only the cheapest available room per hotel is shown. If a hotel has multiple room types, you’ll see whichever one costs least for your dates and guest count.
The price shown on the card already includes all active modifiers — weekend surcharges, last-minute fees, length-of-stay discounts, and extra-guest charges. What you see is what you pay.
6

Choose a room and proceed to book

Click Explore on the hotel card you want. You’ll see the full room details and a booking button.
7

Sign in to complete the booking

OpenBookings uses email magic-link authentication — no password required. If you’re not already signed in, enter your email address and click the link sent to your inbox. You’ll be redirected back to complete the booking.
Your search state is preserved through the sign-in redirect so you don’t have to start over.
8

Confirm your booking

Review the booking summary (hotel, room, dates, total price, cancellation policy) and confirm. You’ll receive a confirmation email once the reservation is placed.

Calling the API directly

You can reproduce any search programmatically with a single GET request to /api/query. All parameters are passed as URL query strings.

Required parameters

ParameterTypeDescription
latnumberLatitude of the destination
lonnumberLongitude of the destination
checkinstringArrival date in YYYY-MM-DD format
checkoutstringDeparture date in YYYY-MM-DD format
adultsnumberNumber of adult guests (age 13+)
roomsnumberNumber of rooms required

Optional parameters

ParameterTypeDescription
childrennumberNumber of child guests (age 0–12); defaults to 0 if omitted
curl "https://openbookings.co/api/query?lat=48.8566&lon=2.3522&checkin=2026-08-01&checkout=2026-08-05&adults=2&children=1&rooms=1"

Example response

The endpoint returns a JSON array. Each element represents the best-priced room for one hotel. Fields are sorted by total_price ascending.
[
  {
    "hotel_id": "a1b2c3d4-...",
    "hotel_name": "Hôtel du Marais",
    "hotel_slug": "hotel-du-marais",
    "city": "Paris",
    "country": "France",
    "room_id": "r-0001",
    "room_name": "Classic Double",
    "room_description": "A comfortable double room with city views.",
    "base_occupancy": 2,
    "max_adults": 2,
    "max_children": 1,
    "rate_plan_id": "rp-standard",
    "rate_plan_name": "Standard Rate",
    "currency": "EUR",
    "is_refundable": true,
    "cancellation_policy": "Free cancellation until 48 hours before arrival.",
    "min_stay": 1,
    "max_stay": null,
    "subtotal": 520.00,
    "total_price": 468.00,
    "applied_modifiers": ["length_of_stay"]
  }
]
subtotal is the sum of all nightly base prices (plus any per-night surcharges). total_price is the final amount after booking-level discounts. applied_modifiers lists which modifier types changed the price — see the pricing modifiers guide for details.

Error responses

If a required parameter is missing or invalid, the API returns HTTP 400 with an errors array:
{
  "errors": [
    "lat is required",
    "checkin is required"
  ]
}
A 500 response indicates a server-side error and will include a single error string.

When no results are returned

The API returns an empty array ([]) when no rooms match your search. This can happen for several reasons:
  • No hotels within 250 km of the destination coordinates have available inventory for your dates.
  • No room fits your guest count — every room within range has a max_adults or max_children lower than what you requested.
  • Stay length constraints — the room’s min_stay is longer than your selected stay, or your stay exceeds max_stay.
An empty result set is a valid 200 OK response — your code should always check the array length before rendering results.
If you’re integrating the API and want to show a helpful empty state, check results.length === 0 and prompt the user to adjust their dates, guest count, or destination.