Hotel Price Comparison & Deal Finder avatar

Hotel Price Comparison & Deal Finder

Under maintenance

Pricing

from $20.00 / 1,000 deal analysis reports

Go to Apify Store
Hotel Price Comparison & Deal Finder

Hotel Price Comparison & Deal Finder

Under maintenance

Compare hotel prices from Booking.com, Expedia, Agoda, Trip.com & more in one run. Normalizes rooms, currencies and taxes, then ranks offers with a 0–100 Deal Score to reveal where a hotel is truly cheapest. Free — just paste the hotel's TripAdvisor link.

Pricing

from $20.00 / 1,000 deal analysis reports

Rating

0.0

(0)

Developer

Alper

Alper

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

8 days ago

Last modified

Share

Hotel Deal Arbitrage Finder — OTA Price Comparison & Deal Intelligence API

Find where a hotel is actually cheapest — and whether the price is truly a deal.

A hotel price comparison and hotel rate arbitrage engine, not another hotel scraper. Give it a hotel name and city; it finds the property, pulls real rates across booking sites (Booking.com, Expedia, Agoda, Trip.com and more), normalizes currency, taxes and room conditions, and ranks every offer with a transparent 0–100 Deal Score — flagging suspiciously low prices on the way. Scan one hotel or a bulk list of 20, and turn it into a hotel price monitoring service with webhook/Telegram alerts.

INPUT OUTPUT (real run, Aug 2026)
───── ──────
Charisma De Luxe Hotel 🔥 4 booking sites checked
Kusadasi · Aug 25 → 31 Agoda €1,494 ← cheapest
3 adults Trip.com €1,848
Booking €2,556
RUN (~30 seconds) ─────────────────────────────
You save €1,062 (41.5%) vs Booking
Deal Score · savings % · booking link

That 41.5% gap is not a typo — it's what the same room, same dates actually cost across sites when we ran this. Nobody spots these gaps manually. This Actor finds them automatically.

What it does

  • Hotel price comparison across OTAs — Booking.com, Expedia, Agoda, Trip.com rates via TripAdvisor's public rate-comparison data
  • Automatic hotel identification — just name + city; the TripAdvisor page is resolved automatically (URL/key optional, but 100% reliable when given)
  • Bulk Hotel Arbitrage Scanner — scan up to 20 hotels in one run, get a ranked table of the biggest OTA price gaps
  • Deal Score (0–100) — documented, configurable scoring: price advantage vs median, offer quality (refundable/board/taxes), data confidence
  • Price anomaly detection — offers far below the market median get flagged "verify before booking", never silently trusted
  • Hotel price monitoring — schedule runs and get webhook or Telegram alerts when price/savings/score conditions hit
  • Honest normalization — currency (live ECB rates), taxes, board basis, refundability; unknown values are labeled unknown, never guessed
  • Fails gracefully: one source going down never kills the run

Why it beats a plain hotel scraper

A hotel price scraper gives you a pile of numbers. This gives you decisions:

QuestionAnswer in the output
Where is this hotel cheapest?cheapestOffer
How much cheaper?deal.savingsAmount, deal.savingsPercent
Is it really a good deal?deal.dealScore + label
Which of my 20 hotels has the biggest OTA price gap?bulk ranking table
Are compared offers actually equivalent?comparisonGroupId — a non-refundable room-only rate never unfairly "beats" a refundable breakfast rate
Is the price suspiciously low?anomaly / possiblePricingError flags
Cheapest vs best value?both returned, with a human explanation of the trade-off

Real case study (live data, August 2026)

Hotel (4 nights, 2 adults)CheapestMost expensiveGap
Charisma De Luxe, Kusadasi (6 n)€1,494 Agoda€2,556 Booking41.5%
Hotel 54, Sakarya€228 Agoda€320 Booking28.8%
Hotel ON7, Sakarya€280 Trip.com€416 Booking32.7%
Ramada Thermal Sapanca€648 (all sites)€6480% — perfect parity

Same rooms, same dates. The engine found every gap — and correctly reported the Ramada as "no arbitrage here".

Quick start (no API keys, no URLs)

{
"hotelName": "Charisma De Luxe Hotel",
"destination": "Kusadasi, Turkey",
"checkIn": "2026-08-25",
"checkOut": "2026-08-31",
"adults": 3,
"currency": "EUR"
}

That's it — the Actor finds the hotel's TripAdvisor page itself and compares OTA rates. For guaranteed identification (recommended for production), add the hotel's TripAdvisor URL:

{ "tripAdvisorUrl": "https://www.tripadvisor.com/Hotel_Review-g297972-d633631-Reviews-Charisma_De_Luxe_Hotel-Kusadasi.html" }

Bulk Hotel Arbitrage Scanner

Scan a whole list and rank the deals — for travel agencies, deal sites and affiliates hunting underpriced hotel rates:

{
"destination": "Kusadasi, Turkey",
"checkIn": "2026-08-25",
"checkOut": "2026-08-31",
"adults": 2,
"minimumSavingsPercent": 15,
"hotels": [
{ "hotelName": "Charisma De Luxe Hotel" },
{ "hotelName": "Hotel 54", "destination": "Sakarya, Turkey" },
{ "hotelName": "Ramada Resort Thermal Sapanca", "destination": "Sapanca, Turkey" }
]
}

Output: a ranked table (recordType: "hotel-summary" per hotel in the Dataset, full ranking in the Key-Value Store):

# Hotel Cheapest Median Saving Score Via
1 Charisma De Luxe Hotel 1494 EUR 1848 19.2% 87 Agoda.com
2 Hotel 54 228 EUR 276 17.4% 56 Agoda.com
3 Ramada Thermal Sapanca 648 EUR 648 0% 16 Booking.com

Hotels below minimumSavingsPercent are flagged belowSavingsThreshold. Up to 20 hotels per run (cost control). For bulk scans, providing tripAdvisorUrl/tripAdvisorHotelKey per hotel (or a rapidApiKey) makes identification faster and fully reliable.

Hotel price monitoring & alerts

Combine with Apify Schedules (e.g. every 6–12 hours) and configure alerts:

{
"alerts": {
"maxTotalPrice": 750,
"minSavingsPercent": 20,
"webhookUrl": "https://your-app.com/hooks/hotel-deals",
"telegramBotToken": "123456:ABC...",
"telegramChatId": "-100123456"
}
}

When a run finds a matching deal, a JSON payload hits your webhook and/or a formatted message lands in Telegram — price drop tracking for hotels, without building anything. Conditions: maxTotalPrice, minSavingsPercent, minDealScore (any match triggers; with no conditions set, every successful run notifies).

Use with AI agents (MCP)

This Actor is pay-per-event priced and fully usable from AI agents through the Apify MCP server — connect Apify to Claude, Cursor or any MCP-capable agent and ask:

"Find the cheapest booking site for Charisma De Luxe Hotel, Aug 25–31, 2 adults — and tell me if it's actually a good deal."

The agent calls the Actor with structured input and gets back the full deal report (cheapest source, savings, Deal Score, anomaly flags) as JSON.

How hotels are identified

  1. tripAdvisorHotelKey (e.g. g297972-d633631) — explicit, always wins
  2. tripAdvisorUrl — the hotel's tripadvisor.com page URL; key extracted automatically
  3. Automatic by name + city — via Xotelo's Search API when rapidApiKey is set (free tier at rapidapi.com, most reliable automatic option), otherwise via a single polite search-engine lookup of the hotel's public TripAdvisor page (keyless, best-effort — can be rate-limited under bulk load)

Automatic candidates are ranked with the same fuzzy matcher used everywhere else (Jaro-Winkler + token sets, handles "Charisma De Luxe" ≡ "Charisma Deluxe Kuşadası") and rejected below a 0.6 confidence threshold — the engine refuses to guess the wrong hotel.

Price sources (honest status)

Provider idSourceStatusRequirements
xoteloXotelo — free public API exposing TripAdvisor's OTA rate comparison (Booking.com, Expedia, Agoda, Trip.com, …)✅ Working, verified livenone (hotel identification as above)
google-hotelsGoogle Hotels via SerpApi (documented, authorized commercial API)✅ Implemented, parser fixture-tested; requires your keyserpApiKey input (secret) or SERPAPI_API_KEY env var
mockDeterministic demo offers🚫 Not registered in the production Actor; unit tests only

No provider bypasses CAPTCHAs, logins, or anti-bot systems. Adding a new source is a one-file job (src/providers/provider-template.ts documents the rules).

Note on Xotelo: rates are average nightly base rates per OTA; room name, board and refundability are not exposed, so those offers carry honest unknown values and a conservative confidence score. Totals derived from nightly averages can differ from checkout totals — always verify on the booking page.

Input

Required: checkIn, checkOut (ISO dates, checkout after checkin, max 30 nights, not in the past), plus either hotelName + destination (single mode) or a non-empty hotels list (bulk mode).

Optional (defaults in parentheses): adults (2), children (0), childrenAges, rooms (1), currency (EUR), market, language (en), tripAdvisorUrl, tripAdvisorHotelKey, hotelUrls, hotels, alerts, rapidApiKey, serpApiKey, maximumPrice, minimumSavingsPercent, filters (refundableOnly, breakfastIncludedOnly, allInclusiveOnly, taxesIncludedOnly, providers), sortBy (dealScore | price | bestValue | savingsPercent), maxOffersPerProvider (25), enabledProviders, includeRawData (false), timeoutSecs (120), cacheTtlMinutes (20), dealScoreWeights.

Output

Dataset: one record per normalized offer (recordType: "offer"), plus "summary" (single mode) or "hotel-summary" ranking rows (bulk mode). Key-Value Store: DEAL_REPORT (full JSON) and DEAL_SUMMARY_TEXT (human-readable).

{
"status": "success",
"cheapestOffer": { "provider": "xotelo", "subSource": "Agoda.com", "normalizedPrice": 1494, "pricePerNight": 249, "dealScore": 87, "bookingUrl": "https://..." },
"bestValueOffer": { "...": "may differ from cheapestOffer, with bestValueReason explaining why" },
"deal": { "dealScore": 87, "label": "Excellent deal", "savingsAmount": 354, "savingsPercent": 19.2 },
"marketStats": { "lowestPrice": 1494, "medianPrice": 1848, "highestPrice": 2556, "providersChecked": 1, "validOffers": 3, "currency": "EUR" },
"comparisonGroups": [], "offers": [], "warnings": [], "fetchedAt": "..."
}

Deal Score explained

ComponentMaxHow
Price Advantage60vs the median of equivalent offers only (same comparison group). Savings saturate at 30%; being group-cheapest adds an undercut bonus vs the second-cheapest. A lone offer gets a neutral 35% — no market evidence.
Offer Quality20refundable +0.40 · all-inclusive +0.30 / full board +0.25 / half board +0.20 / breakfast +0.15 · taxes confirmed +0.20 · pay at property +0.10
Confidence / Freshness200.5 × offer data quality + 0.35 × hotel-match confidence + 0.15 × freshness (cached results decay)

90–100 Exceptional · 80–89 Excellent · 70–79 Good · 60–69 Fair · 0–59 Normal/weak. Weights configurable via dealScoreWeights.

API usage

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('alpercsv/hotel-deal-arbitrage-finder').call({
hotelName: 'Charisma De Luxe Hotel',
destination: 'Kusadasi, Turkey',
checkIn: '2026-08-25',
checkOut: '2026-08-31',
adults: 3,
currency: 'EUR',
});
const report = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('DEAL_REPORT');
console.log(report.value.deal, report.value.cheapestOffer);

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("alpercsv/hotel-deal-arbitrage-finder").call(run_input={
"destination": "Kusadasi, Turkey",
"checkIn": "2026-08-25", "checkOut": "2026-08-31", "adults": 2,
"hotels": [{"hotelName": "Charisma De Luxe Hotel"}, {"hotelName": "Hotel 54", "destination": "Sakarya, Turkey"}],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("recordType") == "hotel-summary":
print(item["rank"], item["hotelName"], item.get("cheapestPrice"), item.get("savingsPercent"))

Use cases

  • Travel agencies — quote the genuinely best bookable rate, with conditions
  • Hotel deal websites & newsletters — auto-surface only offers above a Deal Score threshold
  • Price-alert / price-drop services — scheduled runs + webhook/Telegram alerts out of the box
  • Affiliate sites & travel bloggers — real OTA price-gap data for content and link ranking
  • Travel SaaS & OTA intelligence — rate-parity and competitive monitoring via API
  • AI agents — hotel deal answers through Apify's MCP integration
  • Consumers & travel data analysts — one run before booking; normalized, deduplicated data

Limitations

  • Rate coverage comes from TripAdvisor's comparison surface (via Xotelo); niche OTAs may be missing. Google Hotels adds coverage with a SerpApi key.
  • Automatic name-based identification is best-effort without a rapidApiKey; for bulk scans provide URLs/keys or a RapidAPI key.
  • Prices are snapshots (fetchedAt), cached at most cacheTtlMinutes; FX uses daily ECB reference rates.
  • Xotelo totals derive from nightly averages with unknown tax treatment (taxConfidence: "unknown") — verify final totals on the booking page.

Responsible usage

Only publicly accessible or explicitly authorized APIs; conservative concurrency, bounded retries with backoff, request pacing, and caching. No CAPTCHA circumvention, no credential use, no access-control bypasses — providers that would need them are not included. You are responsible for complying with the terms of any API keys you supply.