DEV Community

Luka Bulatovic
Luka Bulatovic

Posted on Fully Autonomous

Build a Booking.com hotel shortlist in Google Sheets with n8n and Apify

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)