Skip to content

Projections

POST /api/v1/projections/

  • Scope: projections:write
  • Description: estimate a property's annual occupancy, nightly rate and revenue from similar Airbnb listings, given its Airbnb URL or address.

Try it out

Explore parameters, schemas, and live requests in the Swagger UI.

What you get

The same projection the Owner Hub projection flow builds in the Beyond app, in one call: Beyond resolves the property, picks the similar Airbnb listings the app would suggest, and returns the 25th, 50th and 75th percentiles of their occupancy, average daily rate (ADR), booked nights and revenue over the trailing year.

The property does not have to be connected to Beyond. Each projection is saved to the Owner Hub History of the user it is charged to, with the same downloadable report as a projection made in the app, and the response id is the saved projection's id.

Cost

Each successful projection spends 4 Owner Hub tokens, the same as a projection in the app, charged to the token's user (for an application token, the application's owner). Requests that fail are not charged.

Request

POST /api/v1/projections/
Content-Type: application/vnd.api+json

{
  "data": {
    "type": "projections",
    "attributes": {
      "airbnb-url": "https://www.airbnb.com/rooms/53906452",
      "bathrooms": 2.5,
      "compset-filters": {"radius-km": 15, "bedrooms": ["3", "4"]},
      "exclude-airbnb-ids": ["41290385"]
    }
  }
}
Attribute Description
airbnb-url The property's Airbnb listing URL. Send exactly one of airbnb-url or address.
address The property's street address. Send exactly one of airbnb-url or address.
bedrooms Bedroom count. Required with address.
bathrooms Bathroom count; half baths as .5.
property-type Airbnb room type: entire-home, private-room, shared-room or hotel-room.
market-percentile Where the property sits in its market: p25 (budget), p50, p75, p90 or p95 (luxury).
currency ISO 4217 code for adr and revenue. Defaults to the user's display currency, then their billing currency, then USD.
compset-filters Narrow the similar listings with the Comp Sets filters, see below.
exclude-airbnb-ids Up to 100 Airbnb listing ids, as strings, to drop from the similar listings.
include-airbnb-ids Up to 20 Airbnb listing ids, as strings, to add to the similar listings.

Airbnb URL or address

The two ways in behave differently, because Beyond knows more about an Airbnb listing than about an address:

  • Airbnb URL. The listing's bedrooms, bathrooms, room type and market percentile fill in any of those you leave out. Send them only to override.
  • Address. Nothing is known about the property itself, so bedrooms is required, and bathrooms and property-type are worth sending: anything you leave out is not matched on. The market percentile defaults to the most common one in the area.

subject.sources in the response says where each value came from.

Comp filters

compset-filters takes the same filters as Comp Sets. Every one is optional:

Filter Description
radius-km Only listings within this distance, 1 to 100.
bedrooms Bedroom counts as strings; the last one may be open-ended, e.g. ["2", "3+"].
beds Bed counts, in the same format as bedrooms.
bathrooms Bathroom counts, in the same format as bedrooms.
rating Minimum rating, above 0 and up to 5.
amenities Amenities every listing must have: air-conditioning, heating, washer, dryer, kitchen, parking, hot-tub, internet, tv, pool, waterfront, beachfront, allows-pets.
listing-types Keep only listings of these types: entire-home, private-room, shared-room, hotel-room.
title Text the listing title must contain, up to 100 characters.

Adjusting the comps

The comps are the similar listings the app suggests by default, returned as compset.airbnb-ids. To change them, call again with exclude-airbnb-ids (e.g. ids from the previous response) or include-airbnb-ids. An id in both lists is excluded.

At least 5 of the final comps need priced nights in the window. Fewer is a 422 with code insufficient_compset: loosen the filters, exclude fewer listings or include more.

Stricter rate limit

Each call can fetch the Airbnb listing or geocode the address, run the similar-listings model and several analytics queries. It carries a stricter limit of 10 requests/minute, on top of the application-level limit. See Rate Limiting.

Response

201 Created

{
  "data": {
    "type": "projections",
    "id": "4821",
    "attributes": {
      "currency": "USD",
      "window": {"start-date": "2025-11-02", "end-date": "2026-11-02"},
      "subject": {
        "airbnb-id": "53906452",
        "full-address": "Seagrove Beach, Florida, United States",
        "latitude": 30.3191,
        "longitude": -86.1197,
        "bedrooms": 3,
        "bathrooms": 2.5,
        "property-type": "entire-home",
        "market-percentile": "p75",
        "sources": {
          "bedrooms": "airbnb-listing",
          "bathrooms": "request",
          "property-type": "airbnb-listing",
          "market-percentile": "airbnb-listing"
        }
      },
      "compset": {
        "airbnb-ids": ["18546233", "22931870", "30871442", "37725519", "44108236", "49920817", "51137264", "52088913"],
        "priced-listing-count": 8
      },
      "projection": {
        "p25": {"occupancy": 48.0, "adr": 150, "nights": 176, "revenue": 26280},
        "p50": {"occupancy": 62.0, "adr": 180, "nights": 227, "revenue": 40734},
        "p75": {"occupancy": 74.0, "adr": 225, "nights": 271, "revenue": 60772}
      }
    }
  }
}
Field Description
currency ISO code of adr and revenue.
window The trailing year of stays the comps were measured over.
subject The property as resolved: its Airbnb id (null for an address), address, coordinates and the details the comps were matched on.
subject.sources Per detail: request (you sent it), airbnb-listing (from the Airbnb listing), market (the most common tier in the area) or null (unknown, not matched on).
compset.airbnb-ids The comps used, after your exclusions and inclusions.
compset.priced-listing-count How many of them had priced nights in the window and so count towards the percentiles.
projection.p25 / p50 / p75 The 25th, 50th and 75th percentile scenarios.

Each scenario:

Field Description
occupancy Booked nights over all nights, as a percentage.
adr Average daily rate in currency, in whole major units.
nights Booked nights per year.
revenue Gross annual revenue in currency: ADR × occupancy × 365, before fees. It is computed before adr and nights are rounded, so it can differ slightly from adr × nights.

Percentiles are taken per metric

Occupancy and ADR are percentiles of the comps taken separately, and revenue multiplies them, matching the app's projection. p75.revenue is the revenue at p75 ADR and p75 occupancy, not the 75th percentile of the comps' revenue, so the p25-p75 revenue range is wider than the comps' actual revenue spread.

Use cases

  1. Owner acquisition. Show a prospective owner what their property could earn from its Airbnb URL or address, before it is connected to Beyond.
  2. Underwriting. Estimate revenue for a property you are considering buying or managing, with p25 as the conservative case.
  3. Scenario modelling. Use occupancy and adr separately to apply your own assumptions, e.g. your management's typical occupancy uplift.
  4. Comp review. Drop comps that are not comparable with exclude-airbnb-ids and call again until the set matches your judgement.

Errors

Status Cause
400 Invalid attributes: neither or both of airbnb-url and address, an address without bedrooms, a URL that is not an Airbnb listing, an unsupported currency, or an invalid filter.
401 Missing or invalid bearer token.
403 Token does not have the projections:write scope or is not bound to a user, or the user's plan does not include Owner Hub projections.
422 The property could not be resolved, or has too few comps. See below.
429 Rate limit exceeded, or the user's Owner Hub tokens are used up until Retry-After.
503 A dependency failed or timed out. Nothing was saved or charged; retry with backoff.
Status code Meaning
422 property_not_resolved The Airbnb listing or the address could not be found.
422 no_similar_listings No similar Airbnb listings around the property.
422 insufficient_compset Fewer than 5 comps with priced nights. Loosen the filters or adjust the ids.
503 listing_unavailable The Airbnb listing could not be fetched right now.
503 geocoding_unavailable The address could not be geocoded right now.
503 similar_listings_unavailable The similar listings could not be computed in time.
503 projection_unavailable The percentile query failed.
{
  "errors": [
    {
      "status": "422",
      "detail": "Only 3 comparable listings with priced nights; at least 5 are needed. Loosen `compset-filters`, exclude fewer listings or include more.",
      "source": {"pointer": "/data"},
      "code": "insufficient_compset"
    }
  ]
}