Skip to content

Stays

The Stay resource is the heart of the API. Every other route returns the same canonical shape.

Endpoints

GET /v1/stays/{id}

Get a stay by listing id.

Terminal window
curl https://api.stayingapi.com/v1/stays/1135700964697993602 \
-H "Authorization: Bearer sk_live_..."

GET /v1/stays/by-url

Get a stay by airbnb.com/rooms URL.

Terminal window
curl "https://api.stayingapi.com/v1/stays/by-url?url=https://airbnb.com/rooms/1135700964697993602" \
-H "Authorization: Bearer sk_live_..."

GET /v1/stays/by-address

Look up a stay by free-text street address. Coming soon — the endpoint currently returns 501 not_implemented. Use GET /v1/stays/by-url with an airbnb.com/rooms/{id} URL, or POST /v1/search with a location query.

POST /v1/stays/batch

Look up multiple stays in one synchronous request. The worker fans out N parallel detail fetches and returns the full Stay array inline.

Terminal window
curl -X POST https://api.stayingapi.com/v1/stays/batch \
-H "Authorization: Bearer sk_live_..." \
-H "content-type: application/json" \
-d '{
"entries": [
{ "url": "https://airbnb.com/rooms/19278160" },
{ "id": "595401" }
]
}'
  • Up to 50 entries per request.
  • Each entry must carry exactly one of url or id. (address is not yet supported on this endpoint.)
  • One credit per returned row.

Response:

{
"data": [ /* Array<Stay> */ ],
"meta": {
"count": 2,
"requested": 2,
"missing": 0
},
"request_id": "req_..."
}

meta.missing tells you how many entries the upstream couldn’t resolve (usually deleted or private listings). Failed rows aren’t billed.

Sub-resources

Slice the cached row without re-fetching. All return the same { data, request_id } envelope, with data narrowed.

PathReturns
/v1/stays/{id}/photos{ id, photos[] }
/v1/stays/{id}/reviews{ id, reviews_count, rating_breakdown, reviews[] }
/v1/stays/{id}/host{ id, host }
/v1/stays/{id}/amenities{ id, amenities[] }
/v1/stays/{id}/availability{ id, availability[] }
/v1/stays/{id}/pricing{ id, pricing }
/v1/stays/{id}/location{ id, location }
/v1/stays/{id}/rating{ id, star_rating, reviews_count, rating_breakdown }

Field availability

Every field below is valid in the schema, but some depend on what the upstream source currently exposes and are commonly null/empty today:

  • pricing.price (and currency / rate_type / breakdown) is date-dependent. It is populated on the dated /v1/search path (with checkIn/checkOut). Single-listing detail lookups (/v1/stays/{id}, /v1/stays/by-url, and the /pricing sub-resource) return pricing as all-null — the single-listing source is not price-aware.
  • reviews[] bodies are not currently provided; the array is usually empty even when reviews_count > 0. Use reviews_count for the total.
  • rating_breakdown components (accuracy, cleanliness, …) are not currently provided; all are null. Use the overall star_rating.
  • room_type / property_type are not currently classified; typically null on both search and detail.
  • location.city / location.country are derived from the search query on /v1/search; on detail lookups they may be null (latitude/longitude are still returned).

Everything else — title, description, star_rating, reviews_count, person_capacity, host, photos, amenities, location.latitude/longitude — is populated whenever the listing exposes it. amenities is returned as a single "General" group (the source provides a flat amenity list, not categories).

Canonical Stay schema

interface Stay {
id: string;
url: string;
title: string;
description: string | null;
property_type: string | null;
room_type: string | null;
person_capacity: number | null;
star_rating: number | null;
location: {
latitude: number | null;
longitude: number | null;
address: string | null;
city: string | null;
country: string | null;
};
host: {
id: string | null;
name: string | null;
is_superhost: boolean;
profile_image_url: string | null;
profile_url: string | null;
rating: number | null;
};
pricing: {
price: number | null;
currency: string | null;
rate_type: string | null;
breakdown: { label: string; amount: number }[] | null;
};
reviews_count: number;
rating_breakdown: {
accuracy: number | null;
cleanliness: number | null;
communication: number | null;
location: number | null;
value: number | null;
check_in: number | null;
guest_satisfaction: number | null;
};
photos: { url: string; caption: string | null }[];
reviews: { id: string; author_name: string; rating: number; text: string; created_at: string }[];
amenities: { category: string; items: string[] }[];
availability: { date: string; available: boolean; min_nights: number | null; price: number | null }[];
}

Example response

A single-listing detail lookup. Note the upstream-limited fields (pricing, room_type, property_type, reviews[], rating_breakdown, location.city) returning null/empty — see Field availability. For nightly pricing, call /v1/search with checkIn/checkOut.

{
"data": {
"id": "1135700964697993602",
"title": "Beachfront flat in Estoril",
"property_type": null,
"room_type": null,
"person_capacity": 4,
"star_rating": 4.92,
"reviews_count": 117,
"location": { "latitude": 38.71, "longitude": -9.40, "address": null, "city": null, "country": null },
"host": { "name": "Maria", "is_superhost": true },
"pricing": { "price": null, "currency": null, "rate_type": null, "breakdown": null },
"amenities": [{ "category": "General", "items": ["Wifi", "Kitchen", "Washer", "Air conditioning"] }],
"reviews": []
}
}

Next