A hotel shortlist is easier to compare when the destination, stay dates, currency and collection time travel with the prices. This guide connects a Booking.com search to Google Sheets using an Apify Actor and n8n.
I'm Luka, the builder behind Luminar. I maintain the Actor and the published workflow used here.
What the result looks like
Here are five real results collected on 26 August 2026, for a 15–17 September 2026 stay in Tivat. They are historical search results, not current offers or checkout-confirmed prices.
| Property | Reported stay total | Guest score |
|---|---|---|
| Apartments Family | EUR 100.00 | 8.5 |
| Eden apartments | EUR 208.70 | 9.0 |
| Sea and Sunshine 100m to beach,free parking,centar,View | EUR 139.13 | 9.6 |
| Adriatic Dream | EUR 107.39 | 9.0 |
| Apartment Nada | EUR 86.09 | 8.8 |
The sample is capped at five properties. It is not an exhaustive comparison of accommodation in Tivat.
1. Get the workflow and sample files
Open the published n8n template, or download booking-workflow.json from the GitHub demo folder.
The folder also contains:
-
sheet-header.csv: the column names for your new Sheet. -
sample-hotels.csv: the five saved results. -
index.html: an offline walkthrough. Download the repository and open this file locally; GitHub itself displays the source.
The offline walkthrough makes no paid API calls. Running the actual workflow does.
You need an Apify account, an n8n instance and a Google account with access to the destination spreadsheet. The template is free to download. Apify usage and n8n hosting or plan charges may apply.
2. Connect your accounts
Import the JSON into a new, empty n8n workflow.
If n8n reports an unavailable Apify node, install the verified Apify community node using the community-node controls supported by your instance. Then select your Apify credential on every Apify node, and your Google Sheets credential on the Sheets node.
Keep credentials in n8n. Do not paste tokens into the workflow JSON or a public repository.
3. Prepare Google Sheets
Create a blank tab named Booking Shortlist and import sheet-header.csv into its first row.
Keep the headers exactly as supplied. They include property identity, stay dates, prices, currency, collection time, coverage and the run receipt.
The key column is upsertKey. The node Upsert dated shortlist in Google Sheets uses Append or Update Row, matching only that column. Matching by a hotel's display name would be less reliable because names can change or be shared.
4. Set a small search
Open Shortlist settings and configure:
| Setting | Initial value |
|---|---|
| destination | Tivat, Montenegro, or your destination |
| checkIn | Your future arrival date, in YYYY-MM-DD format |
| checkOut | Your future departure date, after checkIn |
| adults / rooms | 2 / 1, or your requirements |
| maxProperties | 5 — change the template's default of 20 |
| currency | EUR, or another supported currency |
| spreadsheetId | The ID from your Google Sheets URL |
| sheetName | Booking Shortlist |
| maxCostPerRunUsd | Keep 0.10 for the first test |
Use the spreadsheet ID between /d/ and /edit in its URL, not the whole URL. Replace both date placeholders before running.
The $0.10 setting is a maximum Actor charge per run, not a quoted price for five properties or a cap on your n8n hosting bill.
5. Run manually and inspect the receipt
Start with Test manually. Leave the daily schedule inactive.
The workflow calls the pinned Actor once, retrieves its output, reconciles the returned rows and coverage, and then either writes verified rows or returns a no-write receipt. It does not automatically retry the paid Actor call.
Inspect the Sheet and the final receipt together. A successful execution alone does not mean the whole destination was searched.
- CAPPED means the result was bounded. You can use the shortlist while retaining that limitation.
- Missing source prices should remain blank; do not turn them into zero-cost stays.
- A no-write receipt should be investigated before starting another paid run.
- Keep
priceBasis,checkoutVerified, currency and stay dates visible when comparing amounts.
6. Check a repeat run
For a sequential repeat with the same settings, compare upsertKey values and the number of data rows before and after.
Matching properties update existing rows. Newly returned properties or a changed search scope can legitimately add rows. This workflow maintains a shortlist; it does not create a new historical price observation on every run.
In the recorded repeat test, five rows were updated, the Sheet remained at six total data rows, and duplicate keys remained at zero. The five-property CSV is a saved sample, not a claim that the test Sheet contained only those five rows. This evidence does not establish safety for overlapping concurrent executions.
If something does not work
Check the failing node before rerunning the whole workflow:
| Symptom | First check |
|---|---|
| Preflight stops | Replace placeholders, check date order and spreadsheet ID |
| Apify node is unavailable | Install the required node and select its credential |
| Sheets access fails | Confirm the selected Google account can edit the spreadsheet |
| Wrong columns or mapping | Compare the first row with the supplied header CSV |
| Duplicate property rows | Confirm the matching column is only upsertKey and inspect whether search scope changed |
| Fewer results than expected | Inspect coverage and limits before increasing the search |
Version and next step
This walkthrough uses the unchanged published workflow pinned to Actor build 0.10.1. The recording and repeat proof apply to that version; they are not a new test of the Actor's current latest build.
Start with the workflow and saved example. Once the small manual run produces the rows you need, decide whether to expand the search or keep it as an occasional shortlist.
Top comments (0)