Search listings by location
Search Airbnb listings for a place. `location` is the only required field — a place name like "Lisbon, Portugal" or "Austin, TX" — and every result comes back with its price, rating, badges, coordinates and photos. **Dates are optional, and the two routes that take them behave differently on purpose.** `/search-listings` **always prices**: with no dates it prices every result for the source's own default stay window and reports that window back on `checkIn`/`checkOut` plus a note. `/listing-detail` **does not**: with no dates `listing.price` is **`null`** and a note says to pass `checkIn` and `checkOut` to price a stay. A search has to price to be a search; a detail read will not invent a stay you did not ask about. Read one route's behaviour onto the other and a `null` price looks like a broken listing when it is the documented answer. `price` is a structured object, not a number: `{total, perNight, nights, taxesAndFees, originalTotal, qualifier, note}`, where `total`, `perNight`, `taxesAndFees` and `originalTotal` are each `{amount, currency, formatted}`. `originalTotal` above `total` means a discount is applied — a measured example is `originalTotal: {amount: 1083.09}` against `total: {amount: 940.47}`. `taxesAndFees` is broken out rather than folded into the total, and `nights` is the stay length the figures cover. Any of the money fields can be `null` when the source did not publish it. **Dates here price a stay; they are not a calendar.** A stay that cannot be priced returns `price: null` with a note that it may be unavailable for those dates — which tells you about those dates and nothing else. For which nights are open, use [`/listing-availability`](/documentation/airbnb/endpoints/listing-availability), which returns the calendar night by night. Billing: 1 credit per page fetched, reported as `pagesFetched`. A page is up to 18 listings and costs the same whether it comes back full or half empty. Measured on 17 September 2026: `{"location":"Lisbon, Portugal"}` returned 200 in 1.6-1.9s across three runs, with 18 listings each time.
/search-listings Listings https://api.fetchlayer.dev/airbnb/search-listings Headers
Authorization string required Bearer token — your FetchLayer API key.
Parameters
location string required A place name, e.g. "Austin, TX" or "Lisbon, Portugal". The only required field.
checkIn string optional Stay start date, YYYY-MM-DD. Optional — without it, results are priced for the source's own default stay window, which comes back on `checkIn` in the response. Must be given together with `checkOut`: one without the other is a 400 saying "checkIn and checkOut must be given together".
checkOut string optional Stay end date, YYYY-MM-DD. Required if `checkIn` is given, and vice versa.
adults integer optional Adult guests, up to 50. Omitted means the source's own default, and the response echoes null rather than pretending to a number.
children integer optional Children, up to 50.
infants integer optional Infants, up to 50.
pets integer optional Pets, up to 50.
pages integer optional How many pages of results to walk in one request, up to 15. Each page is up to 18 listings and 1 credit. Pass -1 for the maximum. (default: 1)
cursor string optional Continue from a previous response's `nextCursor`.
format string optional Envelope format: json or markdown. (default: json)
Response Fields
search-listings
Search listings by location
transport string The source. "airbnb".
notes string[] Caveats and completeness statements you can act on, in plain words. On /listing-reviews this is where the "10 of the 52" line lives; on the priced routes it is where the stay window used for pricing is stated; on /listing-availability it is where the booking-window warning lives — read it before reading a run of closed nights as a closure.
pagesFetched number Pages read, and what the request is billed at: 1 credit per page. A page costs the same whether it comes back full or half empty. /resolve-url reports 0 and is free.
query string The location that was searched, echoed back.
listingCount number How many listings came back in this response.
hasMore boolean Whether the source has further results beyond this page.
nextCursor string Pass back as `cursor` to continue. Null when there is nothing more.
checkIn string **The stay window the prices are actually for.** Your dates when you gave them; the source's own default window when you did not — so a price is never silently for dates you did not ask about. Read this before comparing prices across requests.
checkOut string The other end of that window, on the same terms.
adults number The guest count the prices are for, or null when you passed none and the source used its own default.
children number As `adults`.
infants number As `adults`.
pets number As `adults`.
listings[].id string The listing's numeric id. Hand it straight to /listing-detail or /listing-reviews as `listing`.
listings[].url string The listing's airbnb.com/rooms/… address.
listings[].name string The row's headline as published, e.g. "Apartment in Santa Maria Maior" or a hotel name.
listings[].roomName string The specific room on a listing that has one, e.g. "Casa Teva Lisboa Hotel, Deluxe double room". Null on an ordinary whole-home listing.
listings[].coordinates object `{latitude, longitude}` — approximate on search, as the source publishes them.
listings[].rating object `{average, count}` — the aggregate score and how many reviews it rests on. The per-category breakdown is on /listing-detail.
listings[].badges string[] The source's own labels on the row. Measured values include "Guest favorite", "Superhost" and "Featured hotel".
listings[].photos string[] Photo URLs for the row — six per listing in the searches measured.
listings[].price object `price` is a structured object, not a number: `{total, perNight, nights, taxesAndFees, originalTotal, qualifier, note}`, where `total`, `perNight`, `taxesAndFees` and `originalTotal` are each `{amount, currency, formatted}`. `originalTotal` above `total` means a discount is applied — a measured example is `originalTotal: {amount: 1083.09}` against `total: {amount: 940.47}`. `taxesAndFees` is broken out rather than folded into the total, and `nights` is the stay length the figures cover. Any of the money fields can be `null` when the source did not publish it.
listings[].price.total object `{amount, currency, formatted}` — the whole stay, e.g. `{amount: 1245, currency: "USD", formatted: "$1,245"}`.
listings[].price.perNight object `{amount, currency, formatted}` — the per-night figure, e.g. `{amount: 301.93, currency: "USD", formatted: "$301.93"}`.
listings[].price.nights number How many nights the figures cover.
listings[].price.taxesAndFees object `{amount, currency, formatted}`, broken out rather than folded into `total`. Null when the source published no separate figure.
listings[].price.originalTotal object The pre-discount total when one is published, in the same money shape. Above `total` means a discount is applied; null means there is none to report. Measured: `{amount: 1083.09}` against a `total` of `{amount: 940.47}`.
listings[].price.qualifier string What the figures are qualified as, in the source's own words — "total" or "for 4 nights".
listings[].price.note string Whatever the source printed alongside the price, verbatim, e.g. "Pay $0 today with no extra fees." or the room name on a hotel row. Null when there was none.
Request
curl -X POST "https://api.fetchlayer.dev/airbnb/search-listings" \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"location":"Lisbon, Portugal"}'Response
{
"transport": "airbnb",
"notes": [
"More results are available. Continue with nextCursor.",
"No check-in/check-out was given, so each listing's price reflects the source's own default stay (2026-10-16 to 2026-10-21), not necessarily the dates you want. Pass checkIn and checkOut to price a specific stay."
],
"pagesFetched": 1,
"query": "Lisbon, Portugal",
"listingCount": 18,
"hasMore": true,
"nextCursor": "eyJzZWN0aW9uX29mZnNldCI6MCwiaXRlbXNfb2Zmc2V0IjoxOCwidmVyc2lvbiI6MX0=",
"checkIn": "2026-10-16",
"checkOut": "2026-10-21",
"adults": null,
"children": null,
"infants": null,
"pets": null,
"listings": [
{
"id": "33579922",
"url": "https://www.airbnb.com/rooms/33579922",
"name": "Apartment in Santa Maria Maior",
"roomName": null,
"coordinates": {
"latitude": 38.7132,
"longitude": -9.14376
},
"rating": {
"average": 4.95,
"count": 465
},
"badges": [
"Guest favorite"
],
"photos": [
"https://a0.muscache.com/im/pictures/6ae6f001-a512-474b-96ce-bd7852242a3e.jpg"
],
"price": {
"total": {
"amount": 1245,
"currency": "USD",
"formatted": "$1,245"
},
"originalTotal": null,
"perNight": {
"amount": 301.93,
"currency": "USD",
"formatted": "$301.93"
},
"nights": 4,
"taxesAndFees": {
"amount": 36.7,
"currency": "USD",
"formatted": "$36.70"
},
"qualifier": "total",
"note": "Pay $0 today with no extra fees."
}
}
]
}