Search then detail
Search results are intentionally thinner than detail rows — they don’t include full reviews, availability calendars, or full descriptions. This recipe shows the standard two-step flow for going from “find candidates” to “compare deeply”.
Step 1 — Search
import httpx
search = httpx.post( "https://api.stayingapi.com/v1/search", headers={"Authorization": "Bearer sk_live_..."}, json={"location": "Lisbon, Portugal", "filters": {"minBeds": 2, "priceMax": 250}}, timeout=60,).json()
candidates = search["data"]print(f"Found {len(candidates)} candidates")Step 2 — Detail lookup
import httpx
# Pick the top 5 by guest_satisfactiontop_5 = sorted( candidates, key=lambda s: s.get("rating_breakdown", {}).get("guest_satisfaction") or 0, reverse=True,)[:5]
details = []for c in top_5: r = httpx.get( f"https://api.stayingapi.com/v1/stays/{c['id']}", headers={"Authorization": "Bearer sk_live_..."}, timeout=30, ) if r.status_code == 200: details.append(r.json()["data"])
for d in details: print(f"{d['title']}: {d['reviews_count']} reviews, {len(d['amenities'])} amenity groups")Why the split
- Cost: a SEARCH page is ~12 credits for 50 results; a DETAIL is 1 credit each. If you do detail-on-all, you’d pay 50 extra credits for stays you’ll probably discard anyway.
- Latency: search is one upstream call. Detail-on-all is N parallel calls.
- Repeat-lookup speed: subsequent detail calls for the same listing return in tens of milliseconds.
Batching detail calls
If you have ≤25 ids you want to compare at once, the no-code dashboard’s
“multi-listing-comparison” template wraps the loop for you with a CSV download.
Programmatically, just parallelise with asyncio.gather or Promise.all.
const ids = ["1135...", "2245...", "3355..."];const details = await Promise.all( ids.map((id) => fetch(`https://api.stayingapi.com/v1/stays/${id}`, { headers: { Authorization: "Bearer sk_live_..." }, }).then((r) => r.json()) ));Next
- Full stay lookup
- Async jobs — for searches that need more than 240 rows
- Pagination