Compsets¶
GET /api/v1/compsets/— list the comp sets you can see (paginated summary).GET /api/v1/compsets/<id>/— get one comp set, fully enriched.- Scope:
compsets:read
Try it out
Explore schemas and make live requests in the Swagger UI.
What is a compset?¶
A compset (Competitive Set) is a group of comparable nearby listings used to benchmark a property's pricing and performance. Beyond surfaces the competitive set for a listing — its members are comparable nearby properties drawn from the channels Beyond tracks — together with the headline KPIs (posted rate, occupancy, minimum stay) operators use to position their property in the local market.
Compset kinds¶
Every comp set carries a kind discriminator so you can tell the types apart —
some fields are only populated for some kinds:
kind |
Description |
|---|---|
connected |
Anchored to a Beyond listing (whether that listing's comp set was user-curated or system-generated). |
custom |
Built against a typed-in custom listing, with no Beyond listing. Beta. |
Beta
The custom kind is a beta feature. Its response shape and behavior may
change without notice, and it is not yet covered by backward-compatibility
guarantees.
For a custom comp set (no Beyond listing) the source.min-stay,
source.base-price, source.health-score, and source.market fields are
null, the whole performance.main-listing-metrics block is null, and
source.currency falls back to the user's billing currency.
List comp sets¶
GET /api/v1/compsets/
Returns a paginated list of summary entries — cheap fields only (no metric
or member enrichment) — enough to choose which comp set to fetch in detail. Each
entry has its kind, title, listing-id, total member-count, and
timestamps.
- Pagination:
page[number]andpage[size](max 100). - Filtering:
filter[owner]=<user_id>(owning user),filter[listing]=<id>(Beyond listing id),filter[kind]=custom|connected. - Sorting:
sort=created-at(default-created-at, newest first) orsort=title; prefix with-for descending.
filter[owner]
filter[owner] narrows the list to a single user. It is only meaningful for
full-access partner tokens; a user-scoped token already sees just its own
user, so the filter has no additional effect.
Compound Documents (Sideloading)¶
Include related resources in a single request using the ?include= parameter:
owner-- the user who owns the comp setlisting-- the Beyond listing the comp set is anchored to (nullforcustomcomp sets)
This avoids separate API calls to fetch the owner or listing. See the JSON:API guide for details on how compound documents work.
Get a comp set¶
GET /api/v1/compsets/<id>/
Returns one comp set by its id, with the base listing anchor (source), its
headline metrics over the next 30 and 90 days, the curated members[] enriched
with per-member attributes and metrics, and a performance comparison against
the aggregated compset benchmark — enough to render a full side-by-side
comparison in a single round trip.
Returns 404 when no comp set with that id is visible to your application.
Stricter rate limit
This is a heavy endpoint, so it carries a stricter limit of 30 requests/minute per user/application. Exceeding it returns 429; cache responses and avoid tight polling loops.
Performance comparison — start_date / end_date¶
The response always includes a performance block: the listing's metrics
compared to the aggregated compset benchmark for the requested date range
(posted rate, occupancy, minimum stay, booked rate, adjusted occupancy).
Control the window with the start_date and end_date query parameters
(defaults: today → today + 90 days, max 180-day range). This is the heaviest
part of the query — clients backing real-time UIs should cache results.
Notable Fields¶
kind—customorconnected(see Compset kinds).listing-id— the Beyond listing the comp set is anchored to (nullforcustomcomp sets).title— the comp set's name.matched-airbnb-id— external id Beyond matched to the base listing, when available.source— the base listing's attributes (bedrooms, bathrooms, location,base-price,min-stay,health-score) and its headlinemetrics.source.metrics— base-listing KPIs over the next 30 and 90 days:thirty-day-price/ninety-day-price(posted rate),*-adr(booked rate),*-booked(occupancy),*-availability,*-min-stays, plusratingandreviews-count.members[]— the curated comparables, each with attributes (channel,channel-listing-id,title,url,image,bedrooms,bathrooms,room-type,distance-km,rating,reviews-count,health-score) and ametricsblock.members[].channel-listing-id— the comparable's channel-native listing id (the id inmembers[].url), not a Beyond listing id.members[].distance-km— distance from the base listing, in kilometers.members[].metrics— per-member KPIs over the next 30 and 90 days:*-adrand*-booked-rate(rates),*-booked(occupancy),*-availability,*-adj-occupancy,*-min-stays, plusbase-price.performance.main-listing-metrics— the base listing over the requested range:average-posted-rate,occupancy,average-min-stay,average-booked-rate,adj-occupancy.nullforcustomcomp sets.performance.aggregated-metrics— the same figures aggregated across the comp set, plusnumber-of-nearby-listings(members contributing to the aggregate).
Metrics a channel does not provide are returned as null.
Use cases¶
- Browse and pick. List comp sets with
GET /compsets/, optionallyfilter[kind]orfilter[listing], then fetch the chosen one in detail. - Side-by-side comparison table. Combine
sourceandmembers[]to render a comparison grid — bedrooms, bathrooms,room-type,rating,reviews-count,distance-km,health-score, and a thumbnail (image) linking out (url) — and highlight where the base listing trails the cluster. - Pricing pacing. Compare the base listing's
source.metricsthirty-day-price/ninety-day-priceagainst members'thirty-day-adr/ninety-day-adrto spot where the operator is materially above or below the local market. - Occupancy & availability benchmarking. Track
thirty-day-booked/ninety-day-booked(occupancy) and the*-availabilitymetrics acrosssourceandmembers[]to tell apart soft pricing from soft demand. - Minimum-stay strategy. Compare the base listing's
min-stayand*-min-staysagainst members to validate length-of-stay rules for the market. - Reputation & review competitiveness. Compare the base listing's
ratingandreviews-count(source.metrics) against members'rating/reviews-countto spot where weak social proof — not price — is suppressing conversion, and prioritize review generation where the listing trails the cluster. - Listing-quality benchmarking. Rank the base listing's
source.health-scoreagainst members'health-scoreto surface quality headroom (content, photos, listing completeness) to address before adjusting price. - Performance scorecard. Use the
performanceblock to benchmark the listing against the aggregated compset over a chosen date range (average-posted-rate,occupancy,average-booked-rate,adj-occupancy,average-min-stay) and roll the result up to a portfolio scorecard. - Seasonality & demand pacing. Sweep
start_date/end_dateacross consecutive windows (e.g. month by month) and chartperformance.aggregated-metricsover time to map the local demand curve and see where the listing's pacing diverges from the market by season. Cache results — this is the heaviest part of the query.
Errors¶
| Status | Cause |
|---|---|
400 |
Malformed start_date/end_date, or range > 180 days. |
401 |
Missing or invalid bearer token. |
403 |
Token does not have the compsets:read scope, or the credential lacks privileges on the comp set's listing. |
404 |
No comp set with that id is visible to the application. |
429 |
Rate limit exceeded — the detail endpoint is capped at 30 requests/minute per application. |