Moving from Lighthouse to /v1
Your Lighthouse-compatible endpoints keep working. The /v1 API gives you more: extra fields on every rate, every room and rate behind
it, and answers that are easy to read, by people and by code.
This page shows where each Lighthouse parameter and field lives in Beacon's own /v1 API. Your Lighthouse-style endpoints keep working,
so moving is optional.
It is worth it if you want more on each rate, such as the meal plan, the cancellation deadline and partner offers. Only developers need the tables.
From Lighthouse to /v1
Both families read the same runs, so the data agrees. The tables show where each Lighthouse parameter and field lives in /v1. The
Lighthouse side is in Switching from Lighthouse. The /v1 side is in the field dictionary.
Parameters
| Lighthouse | On /v1 | Note |
|---|---|---|
subscriptionId |
The run, in the path: GET /v1/runs/{id}/rates |
Your subscription id is the run's reference. Find the newest completed run with
GET /v1/runs?reference=client-42&status=completed. Every rates answer repeats it as run.reference.
|
X-Oi-Authorization header |
Authorization: Bearer KEY |
Lighthouse clients already send the X-Oi-Authorization header. It also works on /v1, so a client can keep sending it. |
ota |
ota |
Same default, bookingdotcom. Use bookingdotcom, travelodge or premierinn.
branddotcom is for the Lighthouse endpoints only.
|
los |
los |
Same default, 1. A run captures one stay length, so send the run's nights. |
fromDate, shopLength |
fromDate, shopLength |
Same names and defaults. /v1 answers only for the dates the run covers. It doesn't add a general.missing record
for a date outside the run.
|
persons |
persons |
Same: keeps rooms that take at least this many guests. Default 2. |
mealType |
mealType |
Takes a name: any, room_only, breakfast, half_board, full_board,
all_inclusive, breakfast_lunch, lunch_dinner, dinner or lunch. The
Lighthouse codes 0 to 5 are still accepted.
|
roomType |
roomType |
/v1 has its own list: suite, apartment, studio, family,
triple, twin, double, single, dormitory or standard. A
Lighthouse value such as premium answers 400.
|
bar |
bar |
Same: true keeps the public flexible rate. The field that marks the best flexible rate is bestFlex, see the next
table.
|
compsetIds |
compsetIds |
/v1 takes only 1, every property in the run. A list such as -1,1 answers 400. |
currency, changeDays |
None | Not /v1 parameters. Prices are in the run's currency, in the currency field. |
format=csv |
None on rates |
/v1 rates answer JSON. For a whole run, GET /v1/runs/{id}/results?format=ndjson streams one JSON object per line.
|
GET /hotels |
GET /v1/reports, GET /v1/runs |
Reports list their properties and latest run. Runs list their progress and reference. |
POST /liveupdate, GET /liveupdate/{id} (live shop) |
POST /v1/runs, GET /v1/runs/{id} |
The Lighthouse-compatible API has POST /lighthouse/v3/liveupdate and GET /lighthouse/v3/liveupdate/{id}. They
start and follow an ordinary run of the subscription's report, charged like POST /v1/runs. On /v1 you start the
run and poll it yourself, then read GET /v1/runs/{id}/rates once it has completed. See Live shop.
|
Fields
| Lighthouse | On /v1 | Note |
|---|---|---|
hotelId, hotelName |
hotelId, hotelName |
Same Beacon property id. propertyId is also sent, and joins to propertyId on result rows. |
arrivalDate |
checkIn |
Date, YYYY-MM-DD. |
los |
nights |
Stay length in nights. |
value |
price |
The price for the whole stay. null when message is set. Lighthouse fills 0. |
currency, shopCurrency |
currency |
The run's currency. shopCurrency was always the same value, so there is no second field. |
cancellable |
freeCancellation |
The booking can be cancelled free of charge. |
best_flex |
bestFlex |
The chosen rate is free to cancel, and no cheaper free-cancellation rate passes your filters. roomType doesn't narrow it on
/v1.
|
extractDateTime |
fetchedAt |
UTC, written with a Z. null when the date was never fetched. Lighthouse fills the time the run finished. |
message |
message |
Same codes, such as rates.soldout and rates.restrictionlosN. null when there is a rate. Lighthouse
fills empty text.
|
roomName |
roomName |
The room's name. null when message is set. |
roomType |
roomType |
Beacon's classification of the room from its name, using the /v1 list in the table above. The same room can have a different type from Lighthouse's.
|
maxPersons |
maxOccupancy |
The most guests the room takes. null when message is set. |
mealTypeIncluded |
mealType |
A name instead of the code 0 to 5. Nine plans, so breakfast and lunch is not folded into half board. See
what /v1 adds.
|
vatIncl, otherTaxesIncl |
None | Lighthouse always sends null for these. Whether a price includes VAT or other taxes isn't captured. |
cityTaxIncl |
profile.cityTaxIncluded |
The Lighthouse-compatible API sends true on every Premier Inn rate and null for Booking.com and Travelodge. On
/v1 city tax is not on the rate. It is on the property, as profile.cityTaxIncluded, which is set per hotel and is
false where the hotel has no city tax.
|
stars, brand_code (on GET /hotels) |
profile.stars, profile.brand on each report property |
The Lighthouse-compatible API fills stars where it is known, for the hotel and its competitors, and
brand_code for Premier Inn (PI, PID, HUB or ZIP). /v1 gives the same values in
profile, with more. See what /v1 adds.
|
Rates CSV: HotelID, Value, Best_Flex and the other columns |
The JSON field in the same row above |
/v1 has no rates CSV. Each CSV column is the JSON field named in its row, so a spreadsheet or warehouse loader needs only a
rename.
|
What /v1 adds
Each of these is in /v1 today and not in the Lighthouse-compatible answers. Rates is
GET /v1/runs/{id}/rates. Results is GET /v1/runs/{id}/results, every room and rate that the run found.
| Field | Where | Why it matters |
|---|---|---|
originalPrice |
Rates, results | The struck-through price the site shows, or null when it shows none. Shows how deep a competitor is discounting. |
nonRefundable |
Rates, results | Tells a non-refundable rate from a flexible one, so you don't compare unlike rates. |
mealType |
Rates, results |
The meal plan by name: room_only, breakfast, half_board, full_board,
all_inclusive, breakfast_lunch, lunch_dinner, dinner or lunch. You compare
like with like.
|
breakfastIncluded |
Rates, results | A plain yes or no on breakfast. It is set independently of mealType. |
geniusPrice |
Results |
Booking.com shows a Genius member discount for the rate. price is the public price, except on a members-only preview price, where
price is the member price and originalPrice the public price.
|
roomsLeft, limitedAvailability |
Results | How many rooms are left, and whether the site says it is running low. An early sign that a competitor is filling up. What roomsLeft holds depends on the source. |
partnerOffer, undercutsDirect, undercutBy |
Results | A partner sells the room for less than the property does, and by how much. This is rate parity, ready to report. |
availability |
Results |
Why a date has no rooms: sold out, min stay N nights, not fetched, past or
not fetched yet. You see the minimum stay and the fetch status on the row.
|
done, soldOut, failed, past, restricted, remaining |
Run | The fetch status of the whole run, in every run document. You know whether the data is complete before you report on it. |
payNow, onSale, hasOffer |
Results | Whether the rate is paid at booking, and whether the site shows it as a sale or a deal. |
cheapestOfDay, cheapestOwnRate, excludedReason |
Results | Which row is cheapest, and why a row is left out of comparisons, such as partner-offer. |
conditions |
Results | The rate's cancellation and payment terms, as text from the site. |
roomId, rateId |
Results | The site's own ids, so you can follow one room and rate across runs. |
cancellationDeadline, cancellationDeadlineTime |
Rates, results |
The date free cancellation ends, and the time of day as text, on Booking.com, Premier Inn and Travelodge. Booking.com
and Premier Inn give the time as HH:MM, such as 18:00. The time is
null when the site gives a date only. You see when a free rate stops being free.
|
flexibility |
Rates, results |
How flexible the rate is: flexible, semi_flexible or non_flexible, or null when Beacon
can't tell. It doesn't change freeCancellation or
nonRefundable.
|
reschedulable |
Rates, results |
All three sources. true when the source says the booking can be moved to other dates (a change fee still counts). false when it says it cannot be moved, or says nothing. null only where there is no rate.
|
profile |
Report properties |
What is known about each property's hotel: stars, review score and count, location, city, postcode, country, property type, brand,
check-in and check-out times, breakfast price, city tax and facilities. null until the property has been checked. Each source
fills what it shows, see the field dictionary.
|
reference |
Run, rates | Your own label for the client or market. List every run for it with GET /v1/runs?reference=. |
perRoomType=1 |
Rates | One rate for each room type, so you compare doubles with doubles. |
Built for API and LLM ingestion
-
Typed fields. Numbers are numbers, flags are booleans, and anything not known is
null. Nothing needs parsing out of text. -
No silent gaps. Every property and date in the run has a record. When there is no rate,
messagesays why, and the rate fields arenullrather than a made-up0. - Plain names. One field name means one thing in rates, results and the docs. The field dictionary says when each field is empty.
- JSON and ndjson. Rates are JSON. A whole run comes as pages of JSON, or as an ndjson stream with one row on each line, which is easy to feed to a model or a warehouse.
-
Cheap to repeat. A rates answer carries an
ETag. Send it back inIf-None-Matchand an unchanged answer is a304with no body. See caching rates. - Described for machines. The OpenAPI file and llms.txt are served without a key.
One record from GET /v1/runs/{id}/rates, and one for a date with no rate:
{"hotelId": 57, "propertyId": 2291, "hotelName": "Harbour View Hotel", "checkIn": "2026-10-05",
"fetchedAt": "2026-10-05T08:00:19Z", "nights": 1, "currency": "GBP", "price": 109.8,
"originalPrice": 129.2, "roomName": "Twin Room", "roomType": "twin", "maxOccupancy": 2,
"breakfastIncluded": false, "mealType": "room_only", "freeCancellation": true,
"nonRefundable": false, "bestFlex": true, "message": null,
"cancellationDeadline": "2026-10-03", "cancellationDeadlineTime": "18:00",
"flexibility": "flexible", "reschedulable": true}
{"hotelId": 58, "propertyId": 2292, "hotelName": "Quayside Inn", "checkIn": "2026-10-06",
"fetchedAt": "2026-10-05T08:00:36Z", "nights": 1, "currency": "GBP", "price": null,
"originalPrice": null, "roomName": null, "roomType": null, "maxOccupancy": null,
"breakfastIncluded": null, "mealType": null, "freeCancellation": null,
"nonRefundable": null, "bestFlex": null, "message": "rates.soldout",
"cancellationDeadline": null, "cancellationDeadlineTime": null,
"flexibility": null, "reschedulable": null}
How to switch
-
Get the run reference. It is the
subscriptionIdyou already use. Find the newest completed run with that reference and keep itsid. - Call /v1. Send the same filters to
GET /v1/runs/{id}/rateswith a read key. -
Map the fields. Use the tables above. Check
messageto tell a date with no rate, instead of looking for avalueof0. - Keep the Lighthouse endpoint running until you're done. Compare a few dates side by side, then switch one report at a time.
curl -H "Authorization: Bearer $BEACON_READ_KEY" \ "https://api.pro.getbeacon.cloud/v1/runs?reference=client-42&status=completed&limit=1" curl -H "Authorization: Bearer $BEACON_READ_KEY" \ "https://api.pro.getbeacon.cloud/v1/runs/1204/rates?persons=2"