Skip to content

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] and page[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) or sort=title; prefix with - for descending.
GET /api/v1/compsets/?filter[kind]=connected&sort=title&page[size]=50

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 set
  • listing -- the Beyond listing the comp set is anchored to (null for custom comp sets)
GET /api/v1/compsets/?include=owner,listing

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

  • kindcustom or connected (see Compset kinds).
  • listing-id — the Beyond listing the comp set is anchored to (null for custom comp 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 headline metrics.
  • 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, plus rating and reviews-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 a metrics block.
  • members[].channel-listing-id — the comparable's channel-native listing id (the id in members[].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: *-adr and *-booked-rate (rates), *-booked (occupancy), *-availability, *-adj-occupancy, *-min-stays, plus base-price.
  • performance.main-listing-metrics — the base listing over the requested range: average-posted-rate, occupancy, average-min-stay, average-booked-rate, adj-occupancy. null for custom comp sets.
  • performance.aggregated-metrics — the same figures aggregated across the comp set, plus number-of-nearby-listings (members contributing to the aggregate).

Metrics a channel does not provide are returned as null.

Use cases

  1. Browse and pick. List comp sets with GET /compsets/, optionally filter[kind] or filter[listing], then fetch the chosen one in detail.
  2. Side-by-side comparison table. Combine source and members[] 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.
  3. Pricing pacing. Compare the base listing's source.metrics thirty-day-price / ninety-day-price against members' thirty-day-adr / ninety-day-adr to spot where the operator is materially above or below the local market.
  4. Occupancy & availability benchmarking. Track thirty-day-booked / ninety-day-booked (occupancy) and the *-availability metrics across source and members[] to tell apart soft pricing from soft demand.
  5. Minimum-stay strategy. Compare the base listing's min-stay and *-min-stays against members to validate length-of-stay rules for the market.
  6. Reputation & review competitiveness. Compare the base listing's rating and reviews-count (source.metrics) against members' rating / reviews-count to spot where weak social proof — not price — is suppressing conversion, and prioritize review generation where the listing trails the cluster.
  7. Listing-quality benchmarking. Rank the base listing's source.health-score against members' health-score to surface quality headroom (content, photos, listing completeness) to address before adjusting price.
  8. Performance scorecard. Use the performance block 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.
  9. Seasonality & demand pacing. Sweep start_date / end_date across consecutive windows (e.g. month by month) and chart performance.aggregated-metrics over 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.