1
Send a GET request with the target property's coordinates and specs. The API returns up to 25 comparable listings ranked by relevance, each with full property details, host info, ratings, and performance metrics.
Python
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.airroi.com"
# Pull up to 25 comparable listings near a target property
response = requests.get(
f"{BASE_URL}/listings/comparables",
headers={"X-API-KEY": API_KEY},
params={
"latitude": 36.1627,
"longitude": -86.7816,
"bedrooms": 3,
"baths": 2,
"guests": 6,
"currency": "usd"
}
)
data = response.json()
comps = data["comparable_listings"]
print(f"Found {len(comps)} comparable listings")2
Each comparable listing contains four main sections: listing_info (name, type, photos), property_details (bedrooms, amenities), ratings (overall + subcategories), and performance_metrics (TTM and L90D revenue, ADR, occupancy).
json
{
"comparable_listings": [
{
"listing_info": {
"name": "Charming Nashville Cottage near Broadway",
"type": "Entire home",
"photos_count": 32
},
"location_info": {
"city": "Nashville",
"state": "Tennessee",
"lat": 36.1580,
"lng": -86.7740
},
"property_details": {
"bedrooms": 3,
"baths": 2,
"guests": 6,
"amenities": ["wifi", "pool", "hot_tub", "parking", "kitchen"]
},
"ratings": {
"overall": 4.92,
"cleanliness": 4.95,
"communication": 4.98,
"checkin": 4.97,
"accuracy": 4.94,
"location": 4.89,
"value": 4.85
},
"performance_metrics": {
"ttm_revenue": 67800,
"ttm_avg_rate": 245,
"ttm_occupancy": 0.76,
"l90d_revenue": 18200,
"l90d_avg_rate": 258,
"l90d_occupancy": 0.78
},
"host_info": {
"is_superhost": true,
"instant_book": true,
"professional_management": false,
"review_count": 142
}
}
// ... up to 25 comparable listings
]
}listing_info — Name, property type, and photo count.
property_details — Bedrooms, baths, guest capacity, and amenities array.
ratings — Overall rating plus subcategory scores (cleanliness, communication, etc.).
performance_metrics — TTM (trailing twelve months) and L90D (last 90 days) for revenue, ADR, and occupancy.
host_info — Superhost status, instant book, professional management, and review count.
3
Calculate average, median, min, and max for key metrics across all comps. This gives you a quick snapshot of the competitive landscape and helps identify outliers.
Python
import statistics
# Extract key metrics from all comps
revenues = [c["performance_metrics"]["ttm_revenue"] for c in comps]
adrs = [c["performance_metrics"]["ttm_avg_rate"] for c in comps]
occupancies = [c["performance_metrics"]["ttm_occupancy"] for c in comps]
reviews = [c["host_info"]["review_count"] for c in comps]
ratings = [c["ratings"]["overall"] for c in comps]
# Build summary table
metrics = {
"TTM Revenue": revenues,
"TTM ADR": adrs,
"TTM Occupancy": occupancies,
"Review Count": reviews,
"Overall Rating": ratings,
}
print(f"\n{'Metric':<18} {'Avg':>10} {'Median':>10} {'Min':>10} {'Max':>10}")
print("-" * 62)
for name, values in metrics.items():
avg = sum(values) / len(values)
med = statistics.median(values)
fmt = ",.0f" if name != "Overall Rating" and name != "TTM Occupancy" else ".2f"
if name == "TTM Occupancy":
print(f" {name:<18} {avg:>9.0%} {med:>9.0%} {min(values):>9.0%} {max(values):>9.0%}")
elif name == "Overall Rating":
print(f" {name:<18} {avg:>10.2f} {med:>10.2f} {min(values):>10.2f} {max(values):>10.2f}")
else:
print(f" {name:<18} ${avg:>9,.0f} ${med:>9,.0f} ${min(values):>9,.0f} ${max(values):>9,.0f}")4
Narrow the comp set by filtering on superhost status, instant book, specific amenities (pool, hot tub, WiFi), review count, and more. Compare the filtered group's performance against the full set to quantify the impact of each attribute.
Python
# Filter comps by specific criteria
superhosts = [c for c in comps if c["host_info"]["is_superhost"]]
instant_book = [c for c in comps if c["host_info"]["instant_book"]]
has_pool = [c for c in comps
if "pool" in c["property_details"]["amenities"]]
has_hot_tub = [c for c in comps
if "hot_tub" in c["property_details"]["amenities"]]
high_reviews = [c for c in comps if c["host_info"]["review_count"] > 10]
print(f"Filter Results (out of {len(comps)} comps):")
print(f" Superhosts: {len(superhosts)}")
print(f" Instant Book: {len(instant_book)}")
print(f" Has Pool: {len(has_pool)}")
print(f" Has Hot Tub: {len(has_hot_tub)}")
print(f" 10+ Reviews: {len(high_reviews)}")
# Compare filtered vs unfiltered performance
all_rev = sum(c["performance_metrics"]["ttm_revenue"] for c in comps) / len(comps)
sh_rev = sum(c["performance_metrics"]["ttm_revenue"] for c in superhosts) / len(superhosts) if superhosts else 0
pool_rev = sum(c["performance_metrics"]["ttm_revenue"] for c in has_pool) / len(has_pool) if has_pool else 0
print(f"\nAvg TTM Revenue Comparison:")
print(f" All comps: ${all_rev:,.0f}")
print(f" Superhosts: ${sh_rev:,.0f} ({(sh_rev/all_rev - 1):+.0%})")
print(f" With pool: ${pool_rev:,.0f} ({(pool_rev/all_rev - 1):+.0%})")5
Determine where your property sits relative to comps. Calculate a percentile rank for each metric: count how many comps your property outperforms, divided by total comps. This tells you exactly how competitive you are.
Python
# Calculate your competitive position among comps
# Assume your property's metrics:
my_revenue = 72000
my_adr = 260
my_occupancy = 0.80
def percentile_rank(my_value, comp_values):
"""What percentage of comps does your property beat?"""
below = sum(1 for v in comp_values if v < my_value)
return below / len(comp_values)
rev_rank = percentile_rank(my_revenue, revenues)
adr_rank = percentile_rank(my_adr, adrs)
occ_rank = percentile_rank(my_occupancy, occupancies)
print("Competitive Position:")
print(f" Revenue: {rev_rank:.0%} percentile (${my_revenue:,} vs avg ${sum(revenues)/len(revenues):,.0f})")
print(f" ADR: {adr_rank:.0%} percentile (${my_adr} vs avg ${sum(adrs)/len(adrs):,.0f})")
print(f" Occupancy: {occ_rank:.0%} percentile ({my_occupancy:.0%} vs avg {sum(occupancies)/len(occupancies):.0%})")
# Overall assessment
avg_rank = (rev_rank + adr_rank + occ_rank) / 3
if avg_rank >= 0.75:
assessment = "Top performer - outperforming most comps"
elif avg_rank >= 0.50:
assessment = "Above average - room for optimization"
elif avg_rank >= 0.25:
assessment = "Below average - significant upside potential"
else:
assessment = "Underperforming - review pricing and listing quality"
print(f"\nOverall: {assessment} (avg rank: {avg_rank:.0%})")6
What do the top 5 revenue-earning comps have in common that the bottom 5 do not? Analyze superhost status, instant book, professional management, photo count, review count, and amenity patterns to uncover what drives higher revenue.
Python
# Identify what top-performing comps have in common
comps_sorted = sorted(comps, key=lambda c: c["performance_metrics"]["ttm_revenue"], reverse=True)
top5 = comps_sorted[:5]
bottom5 = comps_sorted[-5:]
def analyze_group(group, label):
print(f"\n{label}:")
print(f" Avg Revenue: ${sum(c['performance_metrics']['ttm_revenue'] for c in group) / len(group):,.0f}")
print(f" Avg ADR: ${sum(c['performance_metrics']['ttm_avg_rate'] for c in group) / len(group):,.0f}")
print(f" Avg Occupancy: {sum(c['performance_metrics']['ttm_occupancy'] for c in group) / len(group):.0%}")
print(f" Superhosts: {sum(1 for c in group if c['host_info']['is_superhost'])} / {len(group)}")
print(f" Instant Book: {sum(1 for c in group if c['host_info']['instant_book'])} / {len(group)}")
print(f" Pro Managed: {sum(1 for c in group if c['host_info']['professional_management'])} / {len(group)}")
print(f" Avg Photos: {sum(c['listing_info']['photos_count'] for c in group) / len(group):.0f}")
print(f" Avg Reviews: {sum(c['host_info']['review_count'] for c in group) / len(group):.0f}")
# Most common amenities in top performers
all_amenities = {}
for c in group:
for a in c["property_details"]["amenities"]:
all_amenities[a] = all_amenities.get(a, 0) + 1
common = sorted(all_amenities.items(), key=lambda x: x[1], reverse=True)[:5]
print(f" Top amenities: {', '.join(a for a, _ in common)}")
analyze_group(top5, "Top 5 Revenue Performers")
analyze_group(bottom5, "Bottom 5 Revenue Performers")Keep exploring the AirROI API with these related tutorials.
The API returns up to 25 comparable listings, ranked by relevance to your target property. The number of results depends on listing density in the area. Urban markets typically return the full 25, while rural areas may return fewer.
Comparables are selected based on geographic proximity, bedroom count, bathroom count, guest capacity, and property type. The algorithm weights these factors to find the most similar active listings in the area.
The API returns all comparable listings with their full details. You can then filter client-side by any attribute: superhost status, instant book, specific amenities (pool, hot tub, WiFi), review count, rating, and more. This tutorial shows you exactly how to implement those filters.
Each comparable listing includes trailing twelve month (TTM) metrics: revenue, average daily rate, and occupancy. It also includes last-90-day (L90D) versions of these same metrics for more recent performance, plus review count, overall rating, and subcategory ratings.
The percentile rank is calculated as: (number of comps with a lower value) / (total number of comps). For example, if your property revenue is higher than 18 out of 25 comps, your percentile rank is 72%, meaning you outperform 72% of comparable listings.
Comparable listing data is refreshed continuously. TTM (trailing twelve months) metrics aggregate the last 12 months of actual booking data. L90D metrics cover the most recent 90 days. This means the data reflects current market conditions, not stale historical snapshots.
Stay ahead of the curve
Join our newsletter for exclusive insights and updates. No spam ever.