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.

In short

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, message says why, and the rate fields are null rather than a made-up 0.
  • 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 in If-None-Match and an unchanged answer is a 304 with 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

  1. Get the run reference. It is the subscriptionId you already use. Find the newest completed run with that reference and keep its id.
  2. Call /v1. Send the same filters to GET /v1/runs/{id}/rates with a read key.
  3. Map the fields. Use the tables above. Check message to tell a date with no rate, instead of looking for a value of 0.
  4. 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"