Skip to main content

How to Monitor Listing Performance (KPIs)

Learn how to retrieve KPI data for your Wheelhouse listings: rolling-window metrics and monthly, quarterly, and yearly stats.

Written by Ryo

Wheelhouse provides four KPI endpoints per listing — a rolling-window snapshot, monthly stats, quarterly stats, and yearly stats. All four require listing_id in the path and channel as a query parameter.


Rolling-window KPIs

Returns performance metrics across multiple time windows simultaneously — both forward-looking (next 7, 14, 21, 30, 60, 90, 180, 365 days) and backward-looking (past 7, 14, 21, 30, 60, 90, 180, 365 days). Not every metric has every window; the list below shows which do. Each metric is an object keyed by period strings like 0_7 (next 7 days), 30_0 (past 30 days), etc.

curl "https://api.usewheelhouse.com/ss_api/v1/listings/12345678/kpis?channel=airbnb" \
-H "X-Integration-Api-Key: your_api_key_here"

Response shape:

{
"currency": "USD",
"model_date": "2026-07-04",
"last_booked_days": {
"0_7": 3,
"0_30": 3,
"7_0": 3,
"30_0": 3,
"365_0": 3
},
"occupancy": {
"0_7": 0,
"0_30": 0,
"7_0": 0,
"30_0": 0,
"365_0": 0
},
"adr": { "0_7": 0, "0_30": 0, ... },
"revenue": { "0_7": 0, "0_30": 0, ... },
"bookings": { "0_7": 0, "0_30": 0, ... },
"revpar": { "0_7": 0, "0_30": 0, ... },
"nights_available": { "0_7": 0, "0_30": 0, ... },
"nights_blocked": { "0_7": 0, "0_30": 0, ... }
}

⚠️ Breaking change (2026-08-13): last_booked_at — a single timestamp of the most recent booking — no longer exists. It's replaced by last_booked_days, a full rolling-window metric (same period-keyed shape as adr): the number of days since the most recent booking whose stay dates overlap that period, per period. Read last_booked_days["7_0"] instead of diffing a timestamp yourself.

Available metrics:

  • Next and past windows: adr, adr_fees, asking_rate, asking_rate_fees, asking_rate_highest, asking_rate_lowest, bookings, last_booked_days, lead_time, length_of_stay, min_price_occurrence, nights_available, nights_blocked, nights_bookable, nights_booked, nights_calendar, nights_percent_open, occupancy, occupancy_adjusted, revenue, revenue_available, revenue_blocked, revenue_fees, revenue_fees_taxes, revpar, revpar_adjusted_occupancy, revpar_adjusted_occupancy_fees, revpar_fees.

  • Next windows only: occupancy_neighborhood, occupancy_neighborhood_pp, occupancy_neighborhood_ratio, occupancy_neighborhood_adjusted, occupancy_neighborhood_adjusted_pp, occupancy_neighborhood_adjusted_ratio, revenue_score.

  • Past windows only: pickup, pickup_bookings.

  • Comp set, next 7, 30 and 60 days only: comp_set_occupancy, comp_set_occupancy_adjusted, comp_set_revenue. comp_set_count is a single number, not a set of windows.

A metric is null when it has not been generated yet for the listing. A single window is null when the metric does not apply to it or it has no data.

All monetary values are in the listing's currency.


Rank your whole portfolio by one KPI

New as of 2026-08-13. Instead of pulling every listing's full KPI object and sorting client-side, GET /listings/kpis ranks every listing you can access by a single metric + window in one call.

curl "https://api.usewheelhouse.com/ss_api/v1/listings/kpis?metric=revenue&window=30_0&sort=desc" \
-H "X-Integration-Api-Key: your_api_key_here"

Response — one row per listing, already sorted:

[
{ "listing_id": 84521, "partner_listing_id": "12345678", "value": 4210.55, "currency": "USD", "updated_at": "2026-08-12T04:00:00Z" },
{ "listing_id": 84522, "partner_listing_id": "12345679", "value": 3980.10, "currency": "USD", "updated_at": "2026-08-12T04:00:00Z" }
]

metric and window are required — most metrics support both 0_N (forward) and N_0 (trailing) windows; a few are one-direction only (see the list above). Asking for a window a metric doesn't have returns a 400. Comp-set metrics are not available on this endpoint yet. Pass currency to convert monetary metrics before ranking if your portfolio spans currencies — without it, rows are ranked on unconverted numbers. A listing with no value for the window sorts last with value: null; listings with no stats at all are omitted entirely. include_managed_listings defaults to true (includes listings you manage for another account, not just ones you own).


Monthly stats

Returns monthly performance stats ordered oldest to newest. They cover up to 15 months back and run forward through the month that contains the maximum calendar horizon (1.5 years from today). That last month only includes nights up to the horizon, so its nights and revenue are partial. The current month and later months are forward-looking: they reflect the bookings on the books so far plus asking rates for nights that are still open, so they change as bookings come in. Compare each month value with today's date to see which side it falls on.

curl "https://api.usewheelhouse.com/ss_api/v1/listings/12345678/kpis/monthly?channel=airbnb" \
-H "X-Integration-Api-Key: your_api_key_here"

Response:

{
"currency": "USD",
"data": [
{ ... }
]
}


Quarterly stats

Returns quarterly performance stats ordered oldest to newest. They run from the quarter that contains the date 15 months ago through the quarter that contains the maximum calendar horizon (1.5 years from today). That last quarter only includes nights up to the horizon, so its nights and revenue are partial. The current quarter and later quarters are forward-looking and change as bookings come in. Compare each quarter value with today's date to see which side it falls on.

curl "https://api.usewheelhouse.com/ss_api/v1/listings/12345678/kpis/quarterly?channel=airbnb" \
-H "X-Integration-Api-Key: your_api_key_here"

Response follows the same shape: {"currency": "USD", "data": [...]}.


Yearly stats

Returns yearly performance stats ordered oldest to newest. They run from 5 calendar years ago through the year that contains the maximum calendar horizon (1.5 years from today). That last year only includes nights up to the horizon, so its nights and revenue are partial. The current year and later years are forward-looking and change as bookings come in. Compare each year value with today's date to see which side it falls on.

curl "https://api.usewheelhouse.com/ss_api/v1/listings/12345678/kpis/yearly?channel=airbnb" \
-H "X-Integration-Api-Key: your_api_key_here"

Response follows the same shape: {"currency": "USD", "data": [...]}.


Monitor your full portfolio

Loop through all active listings to pull rolling-window KPIs for each:

import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://api.usewheelhouse.com/ss_api/v1"
headers = {"X-Integration-Api-Key": API_KEY}

listings = requests.get(
f"{BASE_URL}/listings",
headers=headers,
params={"exclude_inactive": "true"}
).json()

for listing in listings:
kpis = requests.get(
f"{BASE_URL}/listings/{listing['id']}/kpis",
headers=headers,
params={"channel": listing["channel"]}
).json()
occ_30 = kpis.get("occupancy", {}).get("0_30")
rev_30 = kpis.get("revenue", {}).get("0_30")
print(f"{listing['id']}: next-30d occupancy={occ_30}, revenue={rev_30}")


Next steps
How to organize and filter listings (tags, segments, dynamic sets)

Did this answer your question?