浏览器

Scavio Airbnb

试用

Search Airbnb stays with the full discount ledger, pull one listing with its complete amenity list and rating breakdown, and page through real review bodies. 3 endpoints, 1 credit each, structured JSON.

它能做什么

Search Airbnb stays with the full discount ledger, pull one listing with its complete amenity list and rating breakdown, and page through real review bodies. 3 endpoints, 1 credit each, structured JSON.

技能文档

Airbnb via Scavio

Search Airbnb stays for a location and date window, read one listing in full, and page through its review bodies. All endpoints return structured JSON.

When to trigger

Use this skill when the user asks to:

  • Find Airbnb stays in a place for specific dates, with price, rating and capacity filters
  • Compare nightly and stay-total prices across listings, including the discount ledger
  • Pull one listing in full - description, capacity, the complete grouped amenity list, host profile, house rules, cancellation policy, photo tour
  • Read the rating breakdown - six category ratings and the five-bucket star distribution
  • Read actual guest review bodies with per-review ratings and dates
  • Build short-term-rental market research, comp sets or host analytics

Setup

Get a free API key at scavio.dev (50 free credits to get started, no card required):

export SCAVIO_API_KEY=sk_live_your_key

Every request is a POST with a JSON body and:

Authorization: Bearer $SCAVIO_API_KEY

Endpoints

Base URL: https://api.scavio.dev. Every Airbnb endpoint costs 1 credit.

EndpointCreditsWhat it returns
POST /api/v1/airbnb/search1Stays: stay-total and per-night price with the full discount ledger, rating and review count, bedrooms/beds/baths, coordinates, badges, images, dates_are_defaulted
POST /api/v1/airbnb/listing1One listing in full: description, property and room type, capacity and room counts, the complete grouped amenity list (including what the place does not have), host profile and stats, house rules with parsed check-in/out times, cancellation policy, sleeping arrangements, photo tour, every image, and the rating breakdown. No nightly price
POST /api/v1/airbnb/reviews1Review bodies with per-review rating, date, and reviewer name/photo/location

Two facts that decide how you call this

Prices are search-only. The room page carries no nightly rate under any parameters - with or without dates, and even under a rendered fetch. If the user wants a price for a specific listing, you must find it in a /search response. /listing will never have one.

The rating breakdown is listing-only. The six category ratings, the five-bucket star distribution and the synthesised review tags are server-rendered on /listing - they are not on /reviews. /reviews gives you the review text.

Workflow

  1. Search: call /airbnb/search with location and, ideally, check_in + check_out. Read listings[].listing_id and listings[].price.
  2. One listing: call /airbnb/listing with that listing_id or a full /rooms/ URL. Query parameters on a pasted URL are discarded - they carry somebody else's dates.
  3. Reviews: call /airbnb/reviews with the same listing_id, sending an explicit limit and stepping offset.

Dates and currency

check_in and check_out must be sent together. A dateless search defaults to roughly +30 days for 5 nights - and Airbnb A/B tests both the window and the prices on that shape: the same URL has come back split across two different windows with first-row prices of $680, $802 and $2,238. The response flags this as dates_are_defaulted. If it is true, do not quote the price as an answer to a dated question.

currency defaults to USD in the transport. Send one explicitly; without it Airbnb prices off the proxy exit and two identical requests disagree.

Pagination

  • /search is 18 listings per page and offers two mutually exclusive controls: a 1-based page, or the opaque next_cursor from a previous response passed back as cursor. cursor wins over page, so sending both is rejected. Pick one. page_count is on the response.
  • /reviews pages with limit (1-50, default 30) and offset (default 0). count is the listing's total review count; returned is how many this page holds.
  • /listing takes no paging parameter.

The limit / offset names are load-bearing. The underscored _limit / _offset used elsewhere in Airbnb's API are silently ignored here and pin the response at a fixed 7 rows for every offset - which reads as a paging loop that never advances.

Parameters

ParameterTypeDefaultDescription
locationstringrequiredCity, region, ZIP, or a pasted airbnb.com/s/ URL (1-200 chars). Unresolvable is a 404
check_in / check_outstring+30d / +5 nightsYYYY-MM-DD, sent together and in order
adultsinteger--Adult guests
childreninteger--Ages 2-12
infantsinteger--Infants
petsinteger--Pets
min_price / max_pricenumber--Whole-stay total, not per night
room_typestring--entire_home, private_room, shared_room, hotel_room
min_bedrooms / min_beds / min_bathroomsinteger--Minimum counts
superhostboolean--Superhost listings only
instant_bookboolean--Instant Book only
guest_favoriteboolean--Guest Favourite only
free_cancellationboolean--Free cancellation only
amenitiesstring--Comma-separated: wifi, air_conditioning, pool, kitchen, free_parking, washer, self_check_in, tv - or raw numeric Airbnb amenity ids
currencystringUSDISO 4217
pageinteger--1-based, 18 listings per page. Cannot be combined with cursor
cursorstring--next_cursor from a previous response. Wins over page

room_type and the named amenities are validated before the scrape, on purpose: an unrecognised value makes Airbnb return the unfiltered set under a 200, so the user would pay for a filter that never ran.

Listing (/listing)

ParameterTypeDefaultDescription
listing_idstringrequiredListing id or full /rooms/ URL; query params discarded
check_in / check_outstring--YYYY-MM-DD, sent together and in order
adults / children / infants / petsinteger--Party composition
currencystringUSDISO 4217

Reviews (/reviews)

ParameterTypeDefaultDescription
listing_idstringrequiredListing id or full /rooms/ URL
limitinteger301-50. Send it explicitly - see the paging note
offsetinteger0Row offset
currencystringUSDISO 4217

Examples

import requests

BASE = "https://api.scavio.dev"
# Your key from https://scavio.dev. Load it from your environment or secret
# store in real code - keep it out of source control.
API_KEY = "sk_your_key_here"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Search a real date window - min_price/max_price are the WHOLE-STAY total
found = requests.post(f"{BASE}/api/v1/airbnb/search", headers=HEADERS,
    json={"location": "Austin, TX", "check_in": "2026-09-08", "check_out": "2026-09-13",
          "adults": 2, "max_price": 1500, "room_type": "entire_home",
          "amenities": "wifi,pool", "currency": "USD"}).json()

assert found["data"]["dates_are_defaulted"] is False   # you sent dates, so this is False

row = found["data"]["listings"][0]
listing_id, stay_price = row["listing_id"], row["price"]

# 2. Listing detail: amenities, host, house rules, rating breakdown - NO price
listing = requests.post(f"{BASE}/api/v1/airbnb/listing", headers=HEADERS,
    json={"listing_id": listing_id}).json()

print(listing["data"]["category_ratings"])   # cleanliness, accuracy, check-in, ...

# 3. Review bodies - always send limit explicitly, then step offset
reviews = requests.post(f"{BASE}/api/v1/airbnb/reviews", headers=HEADERS,
    json={"listing_id": listing_id, "limit": 30, "offset": 0}).json()

print(reviews["data"]["count"], reviews["data"]["returned"])   # total vs this page

Paging: cursor or page, never both.

def search_pages(location, max_pages=3, **body):
    """18 listings per page, 1 credit per page."""
    out, cursor = [], None
    for _ in range(max_pages):
        payload = {"location": location, **body}
        if cursor:
            payload["cursor"] = cursor          # never alongside "page"
        data = requests.post(f"{BASE}/api/v1/airbnb/search",
                             headers=HEADERS, json=payload).json()["data"]
        out += data["listings"]
        cursor = data["next_cursor"]
        if not cursor:
            break
    return out


def all_reviews(listing_id, max_pages=4, limit=50):
    out = []
    for i in range(max_pages):
        data = requests.post(f"{BASE}/api/v1/airbnb/reviews", headers=HEADERS,
                             json={"listing_id": listing_id,
                                   "limit": limit, "offset": i * limit}).json()["data"]
        out += data["reviews"]
        if data["returned"] < limit or len(out) >= data["count"]:
            break
    return out

Response shapes

Every response uses the envelope { data, response_time, credits_used, credits_remaining }. Key data fields:

  • searchurl, location, resolved_location, city, state, country, place_precision, coordinates, map_bounds, check_in, check_out, nights, dates_are_defaulted, currency, guests, page, page_count, next_cursor, count, listings[] (pos, listing_id, listing_node_id, url, name, title, subtitle, rating, review_count, rating_label, bedrooms, beds, baths, price, badges, is_guest_favorite, is_superhost, coordinates, images).
  • listinglisting_id, url, name, headline, description, description_html, summary, property_type, room_type, space_type, person_capacity, overview, bedrooms, beds, baths, rating, review_count, is_guest_favorite, is_new_listing, coordinates, address, neighborhood, breadcrumbs, host, amenities, amenity_groups, highlights, sleeping_arrangements, photo_tour, images, thumbnail, house_rules, safety_and_property, cancellation_policy, additional_house_rules, check_in_time, check_in_end_time, check_out_time, category_ratings[] (category, label, rating). No price field of any kind.
  • reviewslisting_id, url, count (the listing's total), rating, returned (this page), reviews[] (id, text, rating, language, created_at, date, reviewer_id, reviewer_name, reviewer_photo).
{
  "data": {
    "location": "Austin, TX",
    "check_in": "2026-09-08",
    "check_out": "2026-09-13",
    "nights": 5,
    "dates_are_defaulted": false,
    "currency": "USD",
    "page": 1,
    "page_count": 15,
    "next_cursor": "eyJzZWN0aW9uX29mZnNldCI6...",
    "count": 18,
    "listings": [
      {
        "pos": 1,
        "listing_id": "1234567890",
        "name": "Sunny East Austin bungalow",
        "rating": 4.92,
        "review_count": 318,
        "bedrooms": 2,
        "beds": 3,
        "baths": 1,
        "is_guest_favorite": true,
        "url": "https://www.airbnb.com/rooms/1234567890"
      }
    ]
  },
  "credits_used": 1,
  "credits_remaining": 999
}

Guardrails

  • Every call is 1 credit, including one that comes back empty.
  • Never quote a nightly rate from /listing - there is none. Prices come from /search only.
  • Always check dates_are_defaulted. If it is true, Airbnb chose the window and A/B tested the prices; say so instead of presenting the figure as the user's dates.
  • min_price / max_price are the whole-stay total. If the user thinks in nightly terms, convert and tell them which one you filtered on.
  • Send currency on every call. Two identical requests without it can disagree.
  • Send page or cursor, never both - the request is rejected.
  • On /reviews, always send an explicit limit, and use exactly limit / offset. The underscored variants silently return the same 7 rows forever.
  • Never invent a room_type or amenity name. Unrecognised values are rejected before the scrape precisely so the user is not billed for a filter Airbnb would have ignored.
  • Never fabricate listing names, prices, ratings, host details or review text. Only return what the API returned.
  • Review text and host profiles are personal data about real people. Summarise; do not build profiles of individuals.

Failure handling

  • 400 means an invalid or missing parameter - an unpaired or out-of-order date, min_price above max_price, page sent together with cursor, or an unrecognised room_type / amenity name. Fix and retry.
  • 401 means the API key is invalid or missing. Check SCAVIO_API_KEY.
  • 404 means Airbnb could not resolve the location, or the listing id does not exist.
  • 429 means rate or usage limit exceeded. Wait before retrying. See rate limits.
  • 502 / 503 mean upstream is temporarily unavailable - wait a few seconds and retry, up to a few times. Airbnb occasionally serves a geo domain-switch interstitial; the transport already retries that internally, so a 502 that survives to you is real.
  • An empty result set is usually the filters - widen max_price (remember it is the stay total), drop superhost / guest_favorite, or shorten the stay.
  • If SCAVIO_API_KEY is not set, prompt the user to export it before continuing.

SDKs

pip install scavio==0.15.0
from scavio import ScavioClient

client = ScavioClient()  # reads SCAVIO_API_KEY

found = client.airbnb.search("Austin, TX", check_in="2026-09-08", check_out="2026-09-13",
                             adults=2, max_price=1500, currency="USD")
listing_id = found["data"]["listings"][0]["listing_id"]

listing = client.airbnb.listing(listing_id)          # amenities + rating breakdown, no price
reviews = client.airbnb.reviews(listing_id, limit=50, offset=0)
npm install scavio@0.15.0
import { Scavio } from "scavio";

const client = new Scavio(); // reads SCAVIO_API_KEY
const found = await client.airbnb.search({
  location: "Austin, TX", check_in: "2026-09-08", check_out: "2026-09-13", currency: "USD",
});
const reviews = await client.airbnb.reviews({ listing_id: "1234567890", limit: 50, offset: 0 });

相关技能

Extracts Airbnb accommodation search results from a destination query via SSR-embedded data, returning listing ID, URL, name, coordinates, rating, price, photos, and badge info for each result, plus pagination cursors for multi-page retrieval. Use when user mentions Airbnb search results, Airbnb lis

1 星标

Complete Airbnb toolkit — search, availability, listing detail, price, cross-OTA price comparison and reviews, all in one unified schema. Install this when an agent needs broad Airbnb coverage. Powered by StayingAPI.

Read normalized Airbnb reviews for a listing, with native rating scales preserved. Use when a user wants ratings or guest feedback for a listing on Airbnb. Powered by StayingAPI.

2 次安装

Fetches complete Airbnb listing details for a given numeric listing ID via the internal GraphQL API, returning title, room type, description, amenities, photos, coordinates, city, house rules, highlights, ratings, review count, bedroom configuration, and property overview. Use when user mentions Air

This skill helps users run the Airbnb Listing Details Scraper BrowserAct template and extract structured public data. Use this skill when users ask to collect airbnb listing details scraper data, scrape airbnb listing details scraper results, monitor public records from this source, export structure

1 次安装