Skip to main content
New

The YouTube API is live.

Try it
Python tutorial

Compare Your Airbnb Price to Nearby Listings with Python

Find out how nearby listings in your area compare to yours on price for a given date range.

By the Tapline teamLast updated 7 min read

Find out how your nightly rates compare against nearby listings without spending hours clicking through Airbnb. By the end of this tutorial, you will be able to compare your nightly price against the similar listings in your area.

Short version

  • Pick a date range and pull nearby listings with the same bedroom count on the same dates.
  • In Nashville, the median price came to $240.
  • Save as CSV with room ID, title, bedrooms, rating, total price, per night price and URL.
  • Rerun with different dates to get an idea of how your price compares to others.

The Results

We picked this listing to represent your apartment, a two-bedroom condo in Nashville's Gulch priced for 4 adults. Change the link with your own listing to see how it compares.

City Retreat: Modern Gulch Pad, Downtown Views!

Your listing

City Retreat: Modern Gulch Pad, Downtown Views!

2 bedrooms · 4 beds · 2 baths · ★ 4.85

Nov 8 to Nov 11, 2026 · 3 nights · 4 adults

USD 264/ night

USD 790.89 for 3 nights, fees included

Prices collected November 3, 2026

Listings49 with 2 bedrooms within 1.5 km
Median priceUSD 240 per night (middle half USD 198 to USD 293)
Cheaper than you32 of 49 (65%)

What you need

  • Python 3.11.
  • A Tapline account and an API key.
  • The Tapline Python client, version 0.2.18: pip install "tapline==0.2.18".
  • The listing ID from your Airbnb URL.

Lets run a test request

The code below fetches one page of nearby listings and reads each result's room_id, bedrooms, price.formatted, and name. From this you can get the stay total and extract the average price.

terminal
pip install "tapline==0.2.18"
export TAPLINE_API_KEY="your-api-key"
first_request.py
import os
from datetime import date, timedelta
from tapline import SyncTaplineClient
check_in = date.today()
check_out = check_in + timedelta(days=3)
with SyncTaplineClient(api_key=os.environ["TAPLINE_API_KEY"]) as tapline:
page = tapline.airbnb.search(
lat=36.1580,
lon=-86.7766,
radius_km=1.5,
check_in=check_in.isoformat(),
check_out=check_out.isoformat(),
adults=4,
min_bedrooms=2,
)
for listing in page.listings[:3]:
print(listing.room_id, listing.bedrooms, listing.price.formatted, listing.name)

Run the complete comparison script

This fetches the listing and then finds 2 pages of search results around its location. It drops listings with a different bedroom count and reports how your rate compares to others. Every listing gets saved to a CSV.

compare_airbnb_prices.py
"""Compare an Airbnb listing's price with nearby listings for the same dates."""
from __future__ import annotations
import argparse
import csv
import os
import statistics
import sys
from dataclasses import asdict, dataclass
from datetime import date, datetime, timedelta, timezone
from pathlib import Path
from tapline import SyncTaplineClient, TaplineError
SEARCH_RADIUS_KM = 1.5
NUM_SEARCH_PAGES = 2
OUTPUT_PREFIX = "airbnb-listings"
@dataclass(frozen=True)
class Subject:
room_id: str
title: str
bedrooms: int
lat: float
lng: float
per_night: float
currency: str
@dataclass(frozen=True)
class NearbyListing:
room_id: str
title: str
bedrooms: int
rating: float | None
stay_total: float
per_night: float
url: str
def find_next_stay(tapline: SyncTaplineClient, room_id: str, nights: int) -> date:
today = date.today()
calendar = tapline.airbnb.get_calendar(
room_id=room_id, month=today.month, year=today.year, count=3
)
days = {day.date: day for month in calendar.months for day in month.days}
for offset in range(92):
check_in = today + timedelta(days=offset)
stay = [days.get((check_in + timedelta(days=night)).isoformat()) for night in range(nights + 1)]
if None in stay:
continue
first_night, checkout_day = stay[0], stay[-1]
if (
first_night.available_for_checkin
and (first_night.min_nights or 1) <= nights
and all(day.available for day in stay[:-1])
and checkout_day.available_for_checkout
):
return check_in
raise SystemExit(f"Listing {room_id} has no bookable {nights}-night stay in the next 3 months.")
def fetch_subject(
tapline: SyncTaplineClient, room_id: str, check_in: date, check_out: date, adults: int
) -> Subject:
details = tapline.airbnb.get_details(room_id=room_id)
quote = tapline.airbnb.get_price(
room_id=room_id,
check_in=check_in.isoformat(),
check_out=check_out.isoformat(),
adults=adults,
)
if not quote.available or quote.requested_stay_total is None:
raise SystemExit(f"Listing {room_id} is not bookable for {check_in} to {check_out}.")
return Subject(
room_id=room_id,
title=details.title or "",
bedrooms=details.bedrooms or 0,
lat=details.location.lat,
lng=details.location.lng,
per_night=quote.requested_stay_total.amount / (check_out - check_in).days,
currency=quote.currency,
)
def fetch_nearby_listings(
tapline: SyncTaplineClient, subject: Subject, check_in: date, check_out: date, adults: int
) -> list[NearbyListing]:
nights = (check_out - check_in).days
nearby: dict[str, NearbyListing] = {}
cursor = ""
for _ in range(NUM_SEARCH_PAGES):
page = tapline.airbnb.search(
lat=subject.lat,
lon=subject.lng,
radius_km=SEARCH_RADIUS_KM,
check_in=check_in.isoformat(),
check_out=check_out.isoformat(),
adults=adults,
min_bedrooms=subject.bedrooms,
cursor=cursor,
)
for search_listing in page.listings:
if (
search_listing.room_id in (None, subject.room_id)
or search_listing.bedrooms != subject.bedrooms
or search_listing.price.amount is None
):
continue
nearby[search_listing.room_id] = NearbyListing(
room_id=search_listing.room_id,
title=search_listing.name or search_listing.title or "",
bedrooms=search_listing.bedrooms,
rating=search_listing.rating,
stay_total=search_listing.price.amount,
per_night=round(search_listing.price.amount / nights, 2),
url=search_listing.url or "",
)
if not page.pagination.next_cursor:
break
cursor = page.pagination.next_cursor
return sorted(nearby.values(), key=lambda listing: listing.per_night)
def find_price_neighbours(subject: Subject, nearby: list[NearbyListing]) -> list[NearbyListing]:
cheaper = [listing for listing in nearby if listing.per_night < subject.per_night]
pricier = [listing for listing in nearby if listing.per_night >= subject.per_night]
return cheaper[-5:] + pricier[:5]
def write_csv(nearby: list[NearbyListing], output_dir: Path) -> Path:
output_dir.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
output_path = output_dir / f"{OUTPUT_PREFIX}-{timestamp}.csv"
with output_path.open("w", newline="", encoding="utf-8") as output:
writer = csv.DictWriter(output, fieldnames=list(NearbyListing.__dataclass_fields__))
writer.writeheader()
for listing in nearby:
writer.writerow(asdict(listing))
return output_path
def print_report(
subject: Subject, nearby: list[NearbyListing], check_in: date, check_out: date
) -> None:
per_night = [listing.per_night for listing in nearby]
lower, median, upper = statistics.quantiles(per_night, n=4)
cheaper = sum(1 for price in per_night if price < subject.per_night)
money = subject.currency + " {:,.0f}"
print(f"Your listing: {subject.title} ({subject.bedrooms} bedrooms)")
print(f"Dates: {check_in} to {check_out}")
print(f"Your price: {money.format(subject.per_night)} per night, fees included")
print(f"Listings: {len(nearby)} with {subject.bedrooms} bedrooms within {SEARCH_RADIUS_KM} km")
print(
f"Median price: {money.format(median)} per night "
f"(middle half {money.format(lower)} to {money.format(upper)})"
)
print(f"Cheaper than you: {cheaper} of {len(nearby)} ({cheaper / len(nearby):.0%})")
print()
print("Closest listings by price:")
for listing in find_price_neighbours(subject, nearby):
rating = f"{listing.rating:.2f}" if listing.rating else "n/a"
print(f" {money.format(listing.per_night):>10} {rating:>4} {listing.title[:48]} {listing.url}")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("room_id", help="Your Airbnb listing ID, from its URL")
parser.add_argument(
"--check-in",
type=date.fromisoformat,
help="Check-in date, YYYY-MM-DD (default: your listing's next bookable stay)",
)
parser.add_argument("--nights", type=int, default=3, help="Nights to price (default: 3)")
parser.add_argument("--adults", type=int, default=2, help="Guests to price for (default: 2)")
parser.add_argument(
"--output-dir",
type=Path,
default=Path("."),
help="Directory for the timestamped CSV (default: current directory)",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
try:
with SyncTaplineClient(api_key=os.environ["TAPLINE_API_KEY"]) as tapline:
check_in = args.check_in or find_next_stay(tapline, args.room_id, args.nights)
check_out = check_in + timedelta(days=args.nights)
subject = fetch_subject(tapline, args.room_id, check_in, check_out, args.adults)
nearby = fetch_nearby_listings(tapline, subject, check_in, check_out, args.adults)
except TaplineError as error:
print(f"Tapline request failed: {error}", file=sys.stderr)
return 1
if len(nearby) < 4:
print(f"Only {len(nearby)} listings found; widen SEARCH_RADIUS_KM.", file=sys.stderr)
return 1
print_report(subject, nearby, check_in, check_out)
print()
print(f"Saved {len(nearby)} listings to {write_csv(nearby, args.output_dir)}")
return 0
if __name__ == "__main__":
sys.exit(main())

Download compare_airbnb_prices.py

Going further

The script uses 2 constants: SEARCH_RADIUS_KM: the size of the radius we search through and NUM_SEARCH_PAGES: the number of result pages we consider in our comparison. Increase these parameters to compare your apartment to a broader range of other listings.

Run it on your listing

Run the script with your listing ID and guest count. It prices your listing's next open 3-night stay, or pass --check-in and --nights to pick the dates. It prints the report and writes the CSV to the output directory.

terminal
python compare_airbnb_prices.py 41687118 --adults 4
output
Your listing: City Retreat: Modern Gulch Pad, Downtown Views! (2 bedrooms)
Dates: 2026-11-08 to 2026-11-11
Your price: USD 264 per night, fees included
Listings: 49 with 2 bedrooms within 1.5 km
Median price: USD 240 per night (middle half USD 198 to USD 293)
Cheaper than you: 32 of 49 (65%)
Closest listings by price:
USD 252 4.90 Walk To Broadway!Charming Modern Historic Townho https://www.airbnb.com/rooms/43800126
USD 253 4.87 Step out to Broadway /Cozy Loft with Street Acce https://www.airbnb.com/rooms/560117787898033346
USD 258 4.94 1st Floor, No Steps - Walk to Vanderbilt, Belmon https://www.airbnb.com/rooms/547106685230630704
USD 261 4.88 HUGE Corner💍GEM-walk to BROADWAY w/pool SLEEPS 8 https://www.airbnb.com/rooms/554429675255632025
USD 263 4.86 Walk to Honky Tonks & Broadway https://www.airbnb.com/rooms/770320003270085942
USD 268 4.99 The Midnight Cowboy | 0.9 Miles to Broadway! https://www.airbnb.com/rooms/1255204474452570833
USD 269 4.76 The Pink Cowgirl - King Suite https://www.airbnb.com/rooms/1378552204561557864
USD 269 4.84 Wild Flowers, Wild Horses- Sleeps 8 https://www.airbnb.com/rooms/1346475628817668473
USD 270 4.85 Luxury Rental with Pool and Hot tub in Music row https://www.airbnb.com/rooms/33223288
USD 292 4.92 SoBro 2BR Skyline Views | Pool + Gym https://www.airbnb.com/rooms/1581455832059843218
Saved 49 listings to airbnb-listings-20261103T194817Z.csv

Wrapping Up

And there you have it, save hours of time by leveraging Airbnb data directly instead of manually comparing prices on the website. Want to save even more time? Copy this prompt and have an agent set it up for you!

02Try it live

Run a live request.
No account needed.

Pick an example and send a real request. The response is exactly what your code receives in production.

Listing Details

Current listing data

Listing Details

Use Run to fetch a live, normalized response from the Tapline API.

Run a request to fetch a live response.
03Pricing

Start free.
Scale when you need to.

Use one credit pool across every live Tapline API. Upgrade only when you need more requests or a higher rate limit.

 

Free

$0
No card required
100 API credits
All endpointsNo charge for failed requests1 req/s
 

Pay As You Go

$9
one-time payment
From 5,000 credits
All endpointsCredits never expire5 req/s
 

Starter

$39
/ month
billed $468/yrSave $120/yr
100,000 credits/mo
All endpointsEmail support5 req/s
 

Enterprise

Custom
Priced to your workload
More than 4,000,000 credits/mo
Higher rate limitsCustom endpointsAnnual contracts
Get started

Put Airbnb data to work

Search, prices, availability and reviews as structured JSON. Sign up for 100 free API credits, no card needed.

Try Airbnb data on a real listing.
Run live