Datasets API endpoint
Returns aggregate Airbnb short-term-rental market rollups from the dataset id enum value `airbnb-markets`. Aggregate-only: each row is a market cell, never an individual listing. Thin cells are suppressed. group_by enum: `country`, `market`, `admin1` (top subdivision), `locality` (settlement), `room_type` (`entire_place`/`private_room`/`hotel`/`shared_room`), `property_type` (Airbnb's canonical listing type from the detail page). Enrichment-derived groupings include a `coverage` object with the number and share of filtered listings carrying that dimension; the 20% minimum gate is not a completeness guarantee, and counts still describe classified rows only. Each cell also carries `median_price_usd`, the median nightly price converted to USD via an approximate dated FX snapshot, for cross-country comparison (combine with `group_by=room_type` for median price by room type); `guest_favorite_pct`, the share of listings carrying the Guest Favorite badge (an observed lower bound, like `superhost_pct`); and `avg_person_capacity`, the average guests a listing sleeps over the detail-page-enriched sample. Sort enum: `listings_desc`, `superhost_pct_desc`, `rating_desc`, `key_asc`. Billing: this search costs 1 credit per record returned, with a minimum of 2 (an empty result costs 2, a full page of 100 costs 100).
/datasets/airbnb-markets/searchReturns aggregate Airbnb short-term-rental market statistics rolled up from a large public-listing supply census. Each result row is a market cell — a country (default) or a metro — with listing supply, Superhost share, ratings and review counts. It is aggregate-only: it never returns individual listings, hosts, photos or review text, and cells below the small-cell suppression floor are omitted entirely.
Dataset id enum:
airbnb-marketsQuery parameters:
group_by: optional aggregate cell dimension. Allowed values: country, market, admin1, locality, room_type, property_type. Defaults to country. admin1 is the top subdivision (state/province/region) and locality is the settlement (city/town/village), both derived from reverse geocoding. room_type buckets each market by listing type — entire_place, private_room, hotel, shared_room — so you can compare supply and price across accommodation types. property_type is Airbnb's finer canonical listing type (e.g. Entire guest suite, Private room in rental unit), read authoritatively from the listing detail page.country: optional exact ISO-3166-1 alpha-2 country filter, e.g. FR.market: optional exact metro-market filter, e.g. Paris, max 128 characters.superhost: optional filter to count only Superhost listings.guest_favorite: optional filter to count only Guest Favorite listings (an observed lower bound; the badge under-counts).min_rating: optional minimum listing rating, from 0 through 5.min_review_count: optional minimum listing review count, 0 or greater.active_since: optional freshness filter, an ISO-8601 date (YYYY-MM-DD); only listings last seen on or after it are counted.min_listings: optional minimum listings per cell; raises the small-cell suppression floor. It can only raise the floor, never lower it below the built-in minimum.sort: optional sort order. Allowed values: listings_desc, superhost_pct_desc, rating_desc, key_asc. Defaults to listings_desc.page: optional page number, defaults to 1.page_size: optional page size, defaults to 20 and maxes at 100.Response behavior:
admin1, locality, room_type or property_type returns enrichment-derived market cells. When the filtered universe has at least 50 listings, the response includes a coverage object with the number of filtered listings carrying the dimension, the filtered-universe denominator, coverage_pct, the 20% minimum visibility threshold, and meets_threshold. Below the 20% threshold, items is empty and coverage reports the gap. Below the 50-listing suppression floor, both items and coverage are omitted so small-cell totals are not disclosed. Above the threshold, bucket counts still describe only rows carrying the dimension; the threshold is not a completeness guarantee. country and market groupings do not include this object.avg_person_capacity is the average number of guests a listing sleeps, computed over the cell's detail-page-enriched sample; like the *_enriched fields it is reported only once that sample is large enough to be reliable. Combine it with median_price_usd for a rough price-per-guest read.group_by=room_type with median_price_usd gives the median nightly USD price per accommodation type (e.g. entire homes vs private rooms), optionally filtered to one country or market.median_price_usd is the cell's median nightly price converted to USD via an approximate, dated FX snapshot, so markets are price-comparable across countries despite Airbnb localizing the display currency. It is reported only for cells with enough USD-normalized priced listings and is a market-level approximation, not an exact conversion.avg_rating is reported only for cells with enough rated listings, so a handful of reviews never swings a published market average; it is omitted otherwise.superhost_pct is the Superhost share of the cell, from 0 through 100. It is an observed lower bound: it counts listings seen carrying the Superhost badge on the search card, which renders inconsistently, so it under-counts.guest_favorite_pct is the share of the cell's listings carrying the Guest Favorite badge, from 0 through 100, with guest_favorite_listings the underlying count. Like superhost_pct it is an observed lower bound — the badge renders inconsistently on the search card, so it under-counts.superhost_pct_enriched is the reliable Superhost share, computed over a random sample of the cell's listings enriched from the listing detail page (enrichment draws a representative sample, so the rate is unbiased even at partial coverage). It, along with enriched_listings (the size of that enriched sample), distinct_hosts (the number of distinct operators among the enriched listings) and listings_per_host (enriched_listings / distinct_hosts, an operator-concentration signal), is reported only once the enriched sample is large enough to be reliable; all four are omitted until then. Detail-page enrichment covers a growing subset of the census, so these fields appear for more markets over time. distinct_hosts is an aggregate count only — no host identity is ever returned.guest_favorite_pct_enriched is the reliable Guest Favorite share over that same detail-page-enriched sample (the listing detail page carries an authoritative Guest Favorite flag, unlike the inconsistent search-card badge behind guest_favorite_pct). It is reported under the same gate as superhost_pct_enriched and omitted until the enriched sample is large enough.min_listings field in the response echoes the effective suppression floor that was applied.10000; page * page_size must not exceed 10000.items array (not an error) when no cell clears the suppression floor.1 credit per record returned, minimum 2. A search that returns 20 records costs 20 credits, a full page of 100 costs 100, and an empty or one-record result costs 2. You are charged for what comes back, not for the page_size you ask for, but your balance must cover the requested page_size for the call to be accepted. The response header x-credit-cost shows what a call was charged.
| Field | Filled in, of 1 checked | Values in the sample |
|---|---|---|
| key | 1 | |
| listings | 1 | 1,348,902 |
| superhost_listings | 1 | 438,199 |
| superhost_pct | 1 | 32.5 |
| guest_favorite_listings | 1 | 573,945 |
| guest_favorite_pct | 1 | 42.5 |
| rated_listings | 1 | 1,139,658 |
| avg_rating | 1 | 4.67 |
| avg_review_count | 1 | 66.7 |
| median_price_usd | 1 | 245.1 |
| enriched_listings | 1 | 357,275 |
| superhost_pct_enriched | 1 | 58.2 |
| guest_favorite_pct_enriched | 1 | 48.9 |
| avg_person_capacity | 1 | 5.99 |
| distinct_hosts | 1 | 217,056 |
| listings_per_host | 1 | 1.65 |
| last_seen | 1 | 2026-07-29 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| group_by | string | No | country | Aggregate cell dimension enum: country, market, admin1, locality, room_type, property_type. Defaults to country Allowed values: country, market, admin1, locality, room_type, property_type. | |
| country | string | No | Exact ISO-3166-1 alpha-2 country filter, e.g. FR | ||
| market | string | No | Exact metro-market filter, e.g. Paris, max 128 characters | ||
| superhost | boolean | No | Count only Superhost listings | ||
| guest_favorite | boolean | No | Count only Guest Favorite listings (an observed lower bound; the badge under-counts) | ||
| min_rating | number | No | Minimum listing rating, from 0 through 5 | ||
| min_review_count | integer | No | Minimum listing review count, 0 or greater | ||
| active_since | string | No | Freshness filter, an ISO-8601 date (YYYY-MM-DD); only listings last seen on or after it are counted | ||
| min_listings | integer | No | Minimum listings per cell; raises the small-cell suppression floor (never lowered below the built-in minimum) | ||
| sort | string | No | Sort enum: listings_desc, superhost_pct_desc, rating_desc, key_asc Allowed values: listings_desc, superhost_pct_desc, rating_desc, key_asc. | ||
| page | integer | No | 1 | Page number, defaults to 1 | |
| page_size | integer | No | 20 and maxes at 100 | Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/datasets/airbnb-markets/search?group_by=country&country=us&superhost=true&guest_favorite=true&sort=listings_desc&page=1" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"dataset": "airbnb-markets",
"group_by": "room_type",
"coverage": {
"dimension": "room_type",
"covered_listings": 300,
"total_listings": 1000,
"coverage_pct": 30,
"minimum_coverage_pct": 20,
"meets_threshold": true
},
"items": [
{
"key": "entire_place",
"listings": 244,
"superhost_pct": 26.4
},
{
"key": "private_room",
"listings": 56,
"superhost_pct": 18.2
}
],
"page": 1,
"page_size": 20,
"total": 2,
"sort": "listings_desc",
"min_listings": 50
}
}Request schema
No body schema
Response schema
#/definitions/datasets.airbnbMarketsSearchResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | datasets.AirbnbMarketSearchResponse | No | ||||
| data.coverage | object | No | Coverage over the filtered listing universe for enrichment-derived groupings. Omitted for country/market groupings that do not depend on a partial field. | |||
| data.coverage.coverage_pct | number | No | Share of the filtered universe with the dimension, from 0 through 100. | |||
| data.coverage.covered_listings | integer | No | Number of filtered listings with the dimension field populated. | |||
| data.coverage.dimension | string | No | Dimension whose field coverage was measured (for example room_type). | |||
| data.coverage.meets_threshold | boolean | No | Whether the existing presentation gate permits buckets for this result. | |||
| data.coverage.minimum_coverage_pct | number | No | Minimum coverage share required before buckets are returned. | |||
| data.coverage.total_listings | integer | No | Number of listings in the filtered universe, including those without the dimension. | |||
| data.dataset | string | No | Identifier of the dataset queried (`airbnb-markets`). | |||
| data.group_by | string | No | Dimension the cells are grouped by: `country`, `market`, `admin1`, `locality`, `room_type` or `property_type`. | |||
| data.items | array | No | Aggregate market cells on this page, one per group. | |||
| data.items[].avg_person_capacity | number | No | Average number of guests a listing sleeps, over the sampled listings. Omitted until the sample is large enough. | |||
| data.items[].avg_rating | number | No | Average listing rating across rated listings. Omitted when the market has too few rated listings. | |||
| data.items[].avg_review_count | number | No | Average number of reviews per listing. | |||
| data.items[].distinct_hosts | integer | No | Number of distinct hosts among the sampled listings. Omitted until the sample is large enough. | |||
| data.items[].enriched_listings | integer | No | Number of listings in the detail-page sample behind the reliable rates. Omitted when no listing has been sampled. | |||
| data.items[].guest_favorite_listings | integer | No | Number of listings seen with the Guest Favorite badge. | |||
| data.items[].guest_favorite_pct | number | No | Share of listings seen with the Guest Favorite badge, from 0 to 100. A lower bound, because the badge does not always show. | |||
| data.items[].guest_favorite_pct_enriched | number | No | Share of sampled listings that are Guest Favorites, from 0 to 100, taken from listing detail pages. Omitted until the sample is large enough. | |||
| data.items[].key | string | No | Market this row covers: a country code, metro name or other value of the chosen `group_by` dimension. | |||
| data.items[].last_seen | string | No | Most recent time a listing in this market was seen, in UTC (RFC 3339). | |||
| data.items[].listings | integer | No | Number of listings in the market. | |||
| data.items[].listings_per_host | number | No | Sampled listings divided by distinct hosts, a sign of how concentrated hosting is. Omitted until the sample is large enough. | |||
| data.items[].median_price_usd | number | No | Median nightly price in US dollars, converted with an approximate dated exchange rate. Omitted when too few listings have a price. | |||
| data.items[].rated_listings | integer | No | Number of listings that have a rating. | |||
| data.items[].superhost_listings | integer | No | Number of listings seen with the Superhost badge on the search card. | |||
| data.items[].superhost_pct | number | No | Share of listings seen with the Superhost badge, from 0 to 100. A lower bound, because the badge does not always show. | |||
| data.items[].superhost_pct_enriched | number | No | Share of sampled listings that are Superhosts, from 0 to 100, taken from listing detail pages. Omitted until the sample is large enough. | |||
| data.min_listings | integer | No | Minimum number of listings a cell needs to be included. | |||
| data.page | integer | No | Page number returned. | |||
| data.page_size | integer | No | Number of items per page. | |||
| data.sort | string | No | Sort order applied. | |||
| data.total | integer | No | Total number of cells. | |||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 500 | Internal Server Error | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/datasets/airbnb-markets/search?group_by=country&country=us&superhost=true&guest_favorite=true&sort=listings_desc&page=1" \
-H "x-api-key: $CRAWLORA_API_KEY"