Staying API
Live API · 100 free credits, no card

The Airbnb data API,
from URL to clean JSON in one call.

Send an Airbnb URL, a listing ID, or a city search. Get back a normalized record — photos, host, reviews, availability, pricing, amenities. No proxies, no captcha walls, no 4am scraper breaks. REST + MCP, agent-ready.

< 200msp50 latency
OpenAPI 3.1+ MCP server
JSON · CSV+ NDJSON
1 creditper stay lookup

Plain REST + OpenAPI 3.1 — drops straight into Postman, Cursor, Claude, ChatGPT, Zapier, BigQuery and anything that speaks HTTP.

Three steps

Live in sixty seconds, not a sprint.

Sign up, copy a key, paste it into curl. One round trip hits Cloudflare's edge, gets authed and metered, and returns the canonical Stay shape. No middleware, no scraping.

1

Sign up free

Email only, no credit card. 100 credits land in your account instantly — enough to test every endpoint.

2

Copy your key

Every key carries the sk_ prefix and authenticates both REST and MCP calls.

3

Make the call

One HTTP request returns clean, typed JSON. We keep the contract stable across Airbnb's upstream churn.

# your first call
curl https://api.stayingapi.com/v1/stays/by-url \
  -G --data-urlencode "url=https://airbnb.com/rooms/1135..." \
  -H "Authorization: Bearer sk_live_..."
Get a free key →
Try it — no signup

One call, the whole Stay.

Tap a tab for a different sample. Same JSON shape you get with a real key. When you're ready, grab one free →

Request
GET /v1/stays/1135700964697993602
Response 200 OK
{
  "data": {
    "id": "1135700964697993602",
    "url": "https://airbnb.com/rooms/1135700964697993602",
    "title": "Sunlit Studio with River View in Alfama",
    "description": "Restored 1890s apartment in Lisbon's oldest district, two minutes from the riverfront. Quiet at night, walkable to the metro, and stocked for longer stays.",
    "property_type": "Apartment",
    "room_type": "Entire home",
    "person_capacity": 3,
    "star_rating": 4.91,
    "location": {
      "latitude": 38.7138,
      "longitude": -9.1334,
      "address": "Rua de São Pedro, Alfama, Lisbon, Portugal",
      "city": "Lisbon",
      "country": "Portugal"
    },
    "host": {
      "id": "27184221",
      "name": "Mariana",
      "is_superhost": true,
      "profile_image_url": "https://a0.muscache.com/im/pictures/user/27184221/profile.jpg",
      "rating": 4.94
    },
    "pricing": {
      "price": 142,
      "currency": "USD",
      "rate_type": "per_night"
    },
    "reviews_count": 287,
    "rating_breakdown": {
      "accuracy": 4.93,
      "cleanliness": 4.95,
      "communication": 4.97,
      "location": 4.92,
      "value": 4.86,
      "check_in": 4.94
    },
    "photos": [
      {
        "url": "https://a0.muscache.com/im/pictures/example-01.jpg",
        "caption": "Living area"
      },
      {
        "url": "https://a0.muscache.com/im/pictures/example-02.jpg",
        "caption": "Kitchen + dining"
      },
      {
        "url": "https://a0.muscache.com/im/pictures/example-03.jpg",
        "caption": "Bedroom"
      },
      {
        "url": "https://a0.muscache.com/im/pictures/example-04.jpg",
        "caption": "View from the balcony"
      }
    ]
  },
  "request_id": "req_demo_a1b2c3d4"
}
Sample responses shown. Same shape, same fields, same JSON contract you get with a real API key. Get a real key →
What you get

Everything Airbnb shows, in one normalized shape.

No HTML parsing, no rate-limit games. Hit a sub-resource and you get just the slice you need — photos, host, amenities, availability — without pulling the whole record.

The full canonical Stay, in one round trip.

The complete record: id, url, title, description, property type, room type, capacity, location, host, amenities, photos, reviews, availability, pricing, and the full rating breakdown — all returned as typed JSON. Or use field projection (?fields=) to slim the payload to the bytes you actually want.

Identity
idurltitledescriptionproperty_typeroom_typeperson_capacity
Pricing & rating
pricing.pricepricing.currencystar_ratingreviews_countrating_breakdownpricing.breakdown
Stay details
amenitiesavailabilityperson_capacitylocation.addresslocation.citylocation.country
Host & media
host.namehost.is_superhosthost.ratinghost.profile_urlphotos[]reviews[]
1canonical shape 8sub-resources 3output formats Output JSONCSVNDJSON

Global inventory.

Every region, every property type Airbnb hosts. Entire homes, private rooms, shared rooms, hotel rooms, treehouses, boats — everything that appears on airbnb.com is reachable through one canonical schema.

Search by city, dates, capacity.

City, neighborhood, date range, beds, baths, price, capacity, instant-book-only, superhost-only. Async for large result sets, signed webhook on completion.

city "Lisbon, PT" maxItems 1–240 filter 12 facets

Surgical sub-resources.

Need just the photos? Or just the host details? Or just the next 30 days of availability? Each Stay exposes eight surgical sub-resources so you only pull what you'll use.

/photos /host /availability

Built for AI agents.

Drop our OpenAPI 3.1 spec into Claude, ChatGPT, Cursor, or LangChain. Function-call ready. llms.txt + llms-full.txt for context-window stuffing. Native MCP server at api.stayingapi.com/mcp.

OpenAPI 3.1 MCP server llms.txt
For AI agents

Plug Airbnb data into Claude, Cursor & ChatGPT in one paste.

A native MCP server speaking Model Context Protocol 2025-06-18 with OAuth 2.1 (PKCE) plus bearer fallback. Add it as a custom connector and the agent gets five first-class tools instantly.

lookup_stay_by_url & by_id
search_stays, get_stay_photos, get_stay_reviews
Non-MCP agents read /llms.txt + agent-skills bundle
M claude.ai · Connectors
MCP server URL
https://api.stayingapi.com/mcp copy
Tools exposed
lookup_stay_by_url
search_stays
get_stay_photos
get_stay_reviews
Use cases

From side projects to public companies.

Portfolio +12% RevPAR
Estoril · PT$184/n
Brooklyn · NY$248/n
Mission · SF$312/n

Short-term rental analytics

Track competitive nightly rates, occupancy, and superhost penetration across every market. Refresh nightly via /v1/stays/{id}.

/v1/stays/{id} /pricing /availability
POST /v1/search BigQuery

Market intelligence

Pull hundreds of listings async via POST /v1/search, get the dataset back via signed webhook, stream to BigQuery or Snowflake as NDJSON.

POST /v1/search /v1/jobs/{id}/results /v1/webhooks
Rua do Mar 14, Estoril, PT
$184/night
4.92 · 187 reviews · Superhost

Travel concierge & CRMs

Convert street addresses to full Stay profiles for lead enrichment. Power Airbnb-grade listing pages without scraping anything yourself.

/v1/stays/by-address /v1/listings/superhost /host
Pricing

Prepaid credits. No surprise bills.

From 1 credit per call. Failed calls are free — you only pay for usable data. See full pricing →

Free trial

100 free credits at signup

No card. Upgrade any time. Burn through the credits and your account pauses until you pick a plan.

Monthly

$5/month

400 credits / month

  • 200 req / min
  • All endpoints + webhooks + MCP
  • Top-ups at $15 / 1k credits
  • Email support
Start monthly

Cancel anytime

★ Most popular

Annual

$4.50/month

Billed $54 / year  ·  Save 10%

  • 300 req / min (50% higher)
  • All endpoints + webhooks + MCP
  • Top-ups at $12 / 1k credits loyalty rate
  • 5,000 credits granted upfront
  • Priority email support
Start annual — save 10%

Best per-credit price

Need a higher rate limit or volume top-ups?

Enterprise tier ships with 1,500 req/min, custom volume top-up rates, and named-account support.

Talk to us →
Webhooks

Signed deliveries, two minutes to verify.

Every outbound delivery carries an HMAC-SHA256 signature in the x-stayingapi-signature header. Two retries, 10-second timeout per attempt, dead-letter recorded for forensics.

// Inbound delivery (headers + body)
POST /your-hook HTTP/1.1
x-stayingapi-signature: t=1716040800,v1=8b8c2bdac9...
content-type: application/json

{
  "event": "stay.refreshed",
  "data": {
    "id": "1135700964697993602"
  }
}
// Node — verify the signature
import crypto from "node:crypto";

const sig = req.headers["x-stayingapi-signature"];
const [t, v1] = sig.split(",").map(
  (p) => p.split("=")[1]
);
const signed = `${t}.${rawBody}`;
const expected = crypto.createHmac("sha256", SECRET)
  .update(signed)
  .digest("hex");

if (!crypto.timingSafeEqual(
       Buffer.from(v1),
       Buffer.from(expected))) {
  return res.status(401).end();
}
FAQ

Questions about the Airbnb Data API.

Access, pricing, scraping, MCP, and trademark — for developers, AI agents, and the LLMs reading this on their behalf.

Does Airbnb expose a public API for listing data?
Does Airbnb expose a public API for listing data?
Not for general developers. Airbnb's official Partner Connect program is reserved for property managers and channel-management platforms, runs an application-and-review process, and gives back only the data scoped to that integration. If you want listing details, photos, the host's Superhost status, reviews, the availability calendar, or live nightly rates for arbitrary stays, you go through a third-party REST layer like ours. Signup is same-day and the surface is OpenAPI 3.1.
What can I actually do with the API once I sign up?
What can I actually do with the API once I sign up?
Three families of calls: (1) look up a single stay by its airbnb.com/rooms URL, its numeric id, or a street address; (2) search a city or region with structured filters (price band, beds, dates, Instant Book, Superhost-only); (3) pull any sub-resource — photos, reviews, host profile, amenities, availability windows, pricing breakdown, location, ratings — without re-fetching the whole record. Every response is a normalized `Stay` object so your code doesn't fork per endpoint.
Why not write my own Airbnb scraper?
Why not write my own Airbnb scraper?
You can — for about three weeks. Then Airbnb pushes a DOM change, your selector breaks, and you're up at 3am replacing it. Then their bot defense flags your IP block. Then captcha walls eat your throughput. Then the dataset shape drifts in two cities and your downstream pipeline silently emits empty rows. We do that maintenance so your team doesn't. You write one HTTP request; we keep the contract stable across upstream churn.
How current is the data when I call?
How current is the data when I call?
Every call reflects what's live on airbnb.com at request time. Most single-stay lookups come back in well under 200ms. Search runs against the upstream's live index, so a query for a city returns the inventory available right now, not yesterday's snapshot. If a host changes their nightly rate or marks a date as booked between two of your calls, the next call to that endpoint shows it.
Can I check availability for specific check-in / check-out dates?
Can I check availability for specific check-in / check-out dates?
Yes. `POST /v1/search` accepts `checkIn` and `checkOut` (ISO dates) and the SEARCH actor filters to listings that are bookable in that window. `GET /v1/stays/{id}/availability` returns the per-day calendar for any single listing — handy for building 'cheapest weeks in Q3' style dashboards. Availability is part of the canonical Stay shape, so the sub-resource and the search results agree on the same field names.
How is pricing structured?
How is pricing structured?
Three tiers, all credits-based, no overage debt. Free starts you with 100 credits and no card required. Monthly is $5/mo for 400 credits with top-ups at $15/1,000. Annual is $54/yr for 5,000 credits up-front and a loyalty top-up rate of $12/1,000. A normal stay lookup is 1 credit. Address resolution costs 3 credits because we geocode upstream. A search page (up to 50 results) is 12 credits. 4xx/5xx responses are free — you only pay for usable data.
What happens at the end of my free credit budget?
What happens at the end of my free credit budget?
Calls return 402 out_of_credits with a structured error body and your usage pauses. No invoice arrives. No automatic upgrade. Nothing breaks. Go to /app/billing/, pick Monthly or Annual, and your next request goes through inside a second. Once on a paid plan you can also buy top-up packs without renewing — handy for one-off bulk pulls past the 100-credit grant.
What rate-limit ceiling does each plan have?
What rate-limit ceiling does each plan have?
Cloudflare enforces these at the edge on a sliding 60-second window: Free 20/min, Monthly 200/min, Annual 300/min (50% above Monthly), Enterprise 1,500/min. Limits scope per API key so you can split traffic across keys for parallel pipelines. Over the limit you get a 429 with a Retry-After header — no surprise throttling, no shadow ban.
When does a call go async with a job id?
When does a call go async with a job id?
We keep things synchronous as long as the upstream comfortably returns within ~6 seconds. Single-stay lookups are always sync. Searches up to 50 results are sync. Batch lookups (>50 ids in one call) and searches asking for more than 50 results return 202 with a `job_id` — you then poll `/v1/jobs/{id}/results` or subscribe to a signed webhook so we push you the dataset when it's ready. The 50-item line keeps p99 latency predictable rather than letting heavy queries stall lightweight ones.
How do I verify a webhook came from you?
How do I verify a webhook came from you?
Every outbound delivery includes `x-stayingapi-signature: t=<unix>,v1=<hex>`. Compute HMAC-SHA256 of `<t>.<rawBody>` with your signing secret (shown once when you create the webhook) and timing-safe compare against the v1 hash. /api/webhooks/ has copy-paste verifiers in Node, Python, Go, and Ruby. We retry failed deliveries twice with 250ms × attempt² backoff and a 10-second per-attempt timeout. Anything that still fails lands in a dead-letter table you can inspect from the dashboard.
Is there an MCP server I can plug into Claude or Cursor?
Is there an MCP server I can plug into Claude or Cursor?
Yes. The endpoint is `https://api.stayingapi.com/mcp` and speaks Model Context Protocol 2025-06-18 with OAuth 2.1 (PKCE) plus bearer-token fallback. Add it as a custom connector on claude.ai (Settings → Connectors), or drop the URL into Claude Desktop, Claude Code, Cursor, ChatGPT, or the OpenAI Agents SDK and the agent gets `lookup_stay_by_id`, `lookup_stay_by_url`, `search_stays`, `get_stay_photos`, and `get_stay_reviews` as first-class tools. For non-MCP agents we publish `/llms.txt`, `/llms-full.txt`, and an agent-skills bundle at `/.well-known/agent-skills/index.json`.
Are you affiliated with Airbnb in any way?
Are you affiliated with Airbnb in any way?
No. Staying API is an independent project run by an independent team. We are not affiliated with, endorsed by, or sponsored by Airbnb, Inc. "Airbnb" is a registered trademark of Airbnb, Inc. and is used here only to describe what data the API exposes. We surface publicly available listing information through automated retrieval, never use customer credentials, and never access private bookings, guest data, or host messaging.
Can I pipe results into BigQuery, Snowflake, or a CSV?
Can I pipe results into BigQuery, Snowflake, or a CSV?
Yes — every endpoint accepts `?format=csv` or `?format=ndjson` for streaming-friendly output. The dashboard's no-code page wraps the common workflows (search a city, enrich a list, multi-listing compare) and adds a Download CSV / Download JSON button to each result table. For warehouse loads, `/v1/jobs/{id}/results?format=ndjson` streams newline-delimited JSON straight into BigQuery's `bq load`, Snowflake's `COPY INTO` from stage, ClickHouse's `INSERT FROM HTTP`, or anything else that accepts NDJSON over a streaming HTTP load.
Ship today

Your first call
takes sixty seconds.

Sign in with email, copy your key, paste it into curl. The first 100 Airbnb stay records are on us — no credit card, no contract.

# 60-second quickstart
curl https://api.stayingapi.com/v1/stays/by-url \
  -G \
  --data-urlencode "url=https://airbnb.com/rooms/1135700964697993602" \
  -H "Authorization: Bearer sk_test_a1b2c3d4..."

→ 200 OK · application/json
{
  "data": {
    "id": "1135700964697993602",
    "title": "Beachfront flat in Estoril",
    "pricing": { "price": 184, "currency": "USD" }
  }
}
Get your free API key