# ScraperCompany API reference > Hotel and travel data API: Google Hotels calendars and offers, OTA and official-site rates, guest reviews, Google Flights, vacation rentals and search engines as JSON. ## Conventions - Base URL: `https://api.scrapercompany.com` - Auth: send your key in the `x-api-key` header on every request. Keys start with `sk_`. Call the API from servers only. - Requests: JSON bodies for POST, query strings for GET. Unknown fields are rejected with 422. - Errors: non-2xx status with a JSON body carrying `detail`. Retry 429, 502 and 503 with backoff. - Billing: each operation costs a fixed number of credits per successful call. Failed requests (4xx/5xx) and empty results cost 0. Responses report `x-credits-charged` and `x-credits-remaining`. - Every response has an `x-request-id` header (`req_…`). - OpenAPI: https://scrapercompany.com/openapi.json ## Guides and concepts - [Documentation](https://scrapercompany.com/docs): Hotel, flight and vacation-rental rates as structured JSON, plus guest reviews and a growing set of vertical search engines (Google News, Google Search, Bing, Maps, Trends, Jobs, Shopping, Amazon, Walmart, Indeed) through one REST API or an MCP server. - [Quickstart](https://scrapercompany.com/docs/quickstart): Make your first call in 60 seconds: resolve a hotel to a token, then price its next 90 nights. - [Authentication](https://scrapercompany.com/docs/authentication): Authenticate every request with your API key in the x-api-key header. - [MCP server](https://scrapercompany.com/docs/mcp): Give AI agents hotel, flight and vacation-rental prices: connect Claude Code, Cursor or Claude Desktop to the ScraperCompany MCP server with your API key. - [Docs for AI tools](https://scrapercompany.com/docs/ai-tools): Feed these docs to an AI assistant or coding agent: llms.txt, the full-text llms-full.txt, copy any page as Markdown, or open it in ChatGPT or Claude. - [Core concepts](https://scrapercompany.com/docs/concepts): The ideas every endpoint shares: property identifiers, markets and currencies, how a price is broken down, provenance, batch jobs and request IDs. - [Credits & billing](https://scrapercompany.com/docs/credits): How requests are metered in credits, what each operation costs, the planned plans, and the billing endpoints. - [Errors](https://scrapercompany.com/docs/errors): Error bodies, every HTTP status the API returns, and which ones to retry. - [Rate limits](https://scrapercompany.com/docs/rate-limits): The per-key requests-per-minute limit, concurrency limits and how to back off. - [Guides](https://scrapercompany.com/docs/guides): Task-based walkthroughs for the most common jobs: price a hotel for 90 nights, compare OTA rates, search a destination, pull reviews and plan flights. - [Price a hotel's next 90 nights](https://scrapercompany.com/docs/guides/price-next-90-nights): Resolve a hotel once, then fetch a whole forward rate calendar in a single 5-credit call. - [Search a destination, then price a hotel](https://scrapercompany.com/docs/guides/search-a-destination): List a destination's hotels with Google Hotels prices and filters, page through them, then price the one you pick. - [Compare OTA rates for one night](https://scrapercompany.com/docs/guides/compare-ota-rates): Get Booking.com, Hotels.com, Agoda and Expedia prices for the same stay in one call, or every seller Google shows. - [Get Expedia and Vrbo rates](https://scrapercompany.com/docs/guides/expedia-vrbo): Find a hotel's Expedia id and price its rooms, and search and quote Vrbo vacation rentals. - [Get an Airbnb listing's priced calendar](https://scrapercompany.com/docs/guides/airbnb-priced-calendar): Day-by-day availability and stay rules for a listing, with Airbnb's own quoted prices for the nights you choose. - [Price a round trip: outbound, return and booking options](https://scrapercompany.com/docs/guides/round-trip-flights): Search Google Flights, pick an outbound, get its return flights, then see who sells the itinerary and for how much. - [Monitor a comp set with jobs and webhooks](https://scrapercompany.com/docs/guides/monitor-comp-set): Queue calendar collection for up to 50 properties, poll or receive a signed webhook, and schedule it daily. - [Find a property token](https://scrapercompany.com/docs/guides/find-property-token): Turn a hotel name into the Google property token, and into Booking.com, Hotels.com, Agoda and Expedia ids. - [Get a hotel's official-site rates](https://scrapercompany.com/docs/guides/official-site-rates): Read rooms and rate plans straight from the hotel's own booking engine. - [Migrate from another SERP API](https://scrapercompany.com/docs/guides/serp-api-migration): The /v1/serp and /api/v1/search endpoints accept the standard SERP API parameters and return the standard shapes: switch the base URL and key. - [Scrape guest reviews](https://scrapercompany.com/docs/guides/hotel-reviews): Guest reviews from Tripadvisor, Booking.com, Expedia, Hotels.com and Google Hotels as structured JSON, page by page. - [Identify a property by name and address](https://scrapercompany.com/docs/guides/identify-a-property): Look up a hotel by name and place, confirm the exact property by its mailing address, then reuse the token. - [Beyond travel: search, maps, jobs, shopping, social data](https://scrapercompany.com/docs/guides/vertical-engines): Google News, Google Search (organic + People Also Ask + AI Overview), Bing, Trends, Maps, Jobs, Shopping, Amazon, Walmart and Indeed through the same API and key. - [Changelog](https://scrapercompany.com/docs/resources/changelog): Notable changes to the ScraperCompany API and these docs: new endpoints, new sources, response fields and fixes, newest first. - [Status](https://scrapercompany.com/docs/resources/status): How to check whether the API is up, and how incidents are communicated. - [Support](https://scrapercompany.com/docs/resources/support): How to reach the ScraperCompany team and what to include. - [FAQ](https://scrapercompany.com/docs/faq): Answers to common questions about access, credits, data and limits. - [Data sources](https://scrapercompany.com/docs/data-sources): Every source the API covers, what it is best for, and what it costs. - [OpenAPI explorer](https://scrapercompany.com/docs/api): Browse the full OpenAPI 3.1 document, or download it for code generation. ## Discovery Turn a hotel name into the property token the Google endpoints use. ### List markets: `GET /v1/markets` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/markets The markets this deployment is configured for. Each entry carries the currency its rates are quoted in and whether that market's published rates include tax, so a caller can pick a market without hard-coding either fact. Free. Response fields: - `markets` (array of object; required) - `markets[].code` (string; required) - `markets[].currency` (string; required) - `markets[].label` (string; required) - `markets[].rates_include_tax` (boolean; required): Default tax basis for the market. ### Search properties: `POST /v1/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/search Resolve a hotel name to candidate property tokens. Verification is on by default: each candidate is checked with a calendar lookup (slower, but no extra credits; a search costs 1 credit). That is the right default for onboarding: a wrong token yields rates that are entirely plausible and belong to a different hotel. Turn it off only when a human is going to confirm the choice anyway. Not a hot path — tokens are stable, so resolve once and store the result. Google rate-limits search more aggressively than the calendar. Request body (JSON): - `name` (string; required): Property name as a guest would type it. Fuzzy — exact punctuation does not matter. - `city` (string; optional; default ): Strongly recommended. Without it a common brand name matches the wrong city. - `market` (string | null; optional; one of AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UK, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW): ISO country/Google market to try first, e.g. `US`, `MX`, `GD`. Search accepts markets beyond the pricing markets listed by `GET /v1/markets` because property tokens are global; the response reports where it matched. - `fallback_markets` (array of string; optional; default ["US"]; max items 5): Markets tried in order only when the requested market returns zero candidates. Defaults to `US`, which often indexes Caribbean properties absent from their local Google market. Pass `[]` to disable fallback. The response always reports `attempted_markets`, `matched_market`, and `market_fallback_used`. - `currency` (string | null; optional; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `limit` (integer; optional; default 5; min 1, max 10): Candidates to return, best match first. - `verify` (boolean; optional; default true): Fetch each candidate to confirm the token resolves and read back its real name. Slower, far fewer wrong matches. Response fields: - `query` (string; required): `name` and `city` as searched. - `gl` (string; required): Google country (`gl`) of the market that matched, or of the first market tried. - `requested_market` (string; required) - `attempted_markets` (array of string; required): Markets tried, in order, up to and including the one that matched. - `matched_market` (string | null; required) - `market_fallback_used` (boolean; required) - `search_status` (string; required; one of matched, not_found) - `external_fallback_recommended` (boolean; required): True when nothing matched. - `matches` (array of object; required): Best match first when `verify` is on (verified, then name score, then Google rank). - `matches[].token` (string; required): Google property token; pass it as `token` / `property_token`. - `matches[].rank` (integer; required): Google's own ordering, 0 = first. - `matches[].verified` (boolean | null; required): Whether the token prices. `null` when `verify` was false. - `matches[].name` (string | null; required): Property name read back from Google. `null` when unchecked, empty string when checked but unreadable. - `matches[].name_score` (number | null; required): 0-1 word-overlap between the requested and real name. `null` when unchecked. ## Google Hotels Destination search, nightly calendars, stay prices, per-seller offers and room types. ### Calendar: `POST /v1/calendar` Cost: from 5 credits (5, plus 3 per night with `basis: mainstream` and 3 per `verify_sources` spot-check (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/calendar Forward horizon of nightly rates — the cheap bulk path. Request body (JSON): - `token` (string; required; min length 8): Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`. - `market` (string | null; optional; one of AG, AT, AU, BE, BZ, CA, CH, DE, ES, FR, GB, IE, IT, MX, NL, NZ, PT, US): Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`. - `country` (string | null; optional; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter `gl` override. Normally set by `market`. - `currency` (string | null; optional; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO currency for the returned prices. - `days` (integer; optional; default 90; min 1, max 330): Nights to price, starting at `start`. Max 330. - `start` (string (date) | null; optional): First stay date. Defaults to tomorrow. - `adults` (integer; optional; default 2; min 1, max 8): Occupancy: number of adults, 1-8. Children are not supported by the Google calendar. - `los` (integer; optional; default 1; min 1, max 30): Length of stay per quote. Nightly price genuinely moves with LOS. - `rates_include_tax` (boolean | null; optional): Overrides the market default; pass the property's own setting - `is_hostel` (boolean; optional; default false): Hostels are priced per bed rather than per room, so occupancy changes the rate differently. Set this and the per-person maths is applied. - `probe_min_stay` (boolean; optional; default true): Re-ask for any night that will not price as a single night. Google returns a two-night-minimum night identically to a sold-out one — empty, with no reason and no min-stay field — so without this, weekends silently vanish. On a beach market in August that was every Friday and Saturday on half the comp set. Filled rows carry `min_length_of_stay` and a per-night rate derived from the longer stay. Costs one extra call per probe level, not per date. - `basis` (string; optional; default cheapest; one of cheapest, mainstream; pattern ^(cheapest|mainstream)$): What the nightly figure should mean. **`cheapest` (default)** is the fast calendar path: one small request for the whole horizon. It returns Google's lowest bookable rate, including aggregators. The base/fees/taxes/total split and SERP-compatible `rate_before_taxes_with_fees` remain populated. **`mainstream`** also returns `rate_mainstream_total` / `rate_mainstream_base` / `mainstream_source` / `aggregator_discount` — the cheapest rate on Booking, Expedia, Hotels.com, Priceline, Tripadvisor or Agoda, which is what a comp-set audit means by 'the OTA rate'. `rate_total` is left untouched, so both bases are available. This is intentionally expensive: it samples multi-megabyte offers pages and, when an aggregator sets the floor, re-prices each date. Measured on a 14-day request it took about 8s versus 0.4s for `cheapest`; use it selectively. `basis_applied` reports which path ran. - `verify_sources` (integer; optional; default 0; min 0, max 5): Spot-check this many nights against the per-OTA offers page and return a `source_check` block. The Google calendar gives one price per night and never says which source it came from — usually a mainstream OTA, but where a discounter undercuts them it reports the discounter. Measured on four properties: three matched the cheapest mainstream OTA to the cent, the fourth's figure was Super.com's at 15% under. Costs one ~3 MB offers fetch per sampled night, so it is a sample, not every date. Response fields: - `token` (string; required) - `collection_id` (string; required): Shared by every row of this collection (`ratecol_...`). - `observed_at` (string; required): UTC observation time, ISO-8601. - `market` (string; required) - `requested_days` (integer; required): Nights requested (capped at 330). - `coverage` (number; required): Share of requested nights that returned a priced row, 0-1 rounded to 4 decimals (e.g. `0.9333` = 84 of 90). A number, not an `N/M` string. - `wire_bytes` (integer; required) - `elapsed_s` (number; required): End-to-end seconds for this request. - `calendar_elapsed_s` (number; required): Seconds spent on the upstream calendar fetch. - `egress_mode` (string; required; one of direct, proxy_fallback) - `tax_profile` (object | null; required): The property's effective tax profile, derived from the returned nights. - `tax_profile.rate` (number; required): Median tax / base ratio observed across nights. - `tax_profile.confidence` (string; required; one of high, low, none) - `tax_profile.itemised` (integer; required): Nights where the tax split was itemised. - `tax_profile.derived` (integer; required): Nights where only a total was given and the split was derived. - `unpriced_dates` (array of string (date); required): Requested nights with no bookable offer. - `validation` (object; required): Plausibility checks on the returned rows. - `validation.ok` (boolean; required): False when any error-level finding exists. - `validation.errors` (array of string; required) - `validation.warnings` (array of string; required) - `booking_window` (object; optional): How far out the property actually sells. Present on successful collections. - `booking_window.requested_days` (integer; required) - `booking_window.priced_days` (integer; required) - `booking_window.last_priced_day` (integer | null; required): 1-based day of the last priced night. - `booking_window.contiguous_days` (integer; optional): Priced nights from the start with no gap (absent when nothing priced). - `booking_window.dry_after_day` (integer; required) - `booking_window.note` (string; required) - `basis_applied` (string; optional; one of mainstream:annotated, mainstream:calendar-already-matched): Present only with `basis: mainstream`. - `source_check` (object; optional): Present only when `verify_sources` > 0 or `basis: mainstream` sampled nights against the offers page. - `source_check.sampled` (integer; required) - `source_check.mainstream_sources` (array of string; required) - `source_check.calendar_matches_mainstream` (boolean; required) - `source_check.note` (string; required) - `source_check.checks` (array of object; required) - `source_check.reprice` (object; optional): Present when mainstream re-pricing ran. - `rates` (array of object; required): One row per priced night. - `rates[].token` (string; required): Google property token. - `rates[].stay_date` (string (date); required): Stay (check-in) date. - `rates[].rate` (number; required): The market-correct figure to store: all-in (`rate_total`) when `rates_include_tax` is true, otherwise the pre-tax base. For `POST /v1/stay` it is the whole-stay figure. - `rates[].rate_base` (number | null; required): Room-only price before tax and mandatory fees. - `rates[].rate_before_taxes_with_fees` (number | null; required): `rate_base` + `fees` (The standard SERP API `extracted_price_before_taxes` basis). - `rates[].rate_total` (number | null; required): All-in price including tax and fees. - `rates[].tax` (number | null; required) - `rates[].fees` (number | null; required) - `rates[].currency` (string; required) - `rates[].market` (string; required) - `rates[].rates_include_tax` (boolean; required): Which basis `rate` uses. - `rates[].adults` (integer; required) - `rates[].los` (integer; required): Length of stay the price was quoted for. - `rates[].min_length_of_stay` (integer | null; required): Set when the night only prices at a longer stay; `rate` is then a per-night figure derived from that stay. - `rates[].rate_mainstream_base` (number | null; required): Cheapest mainstream-OTA base price (only populated with `basis: mainstream`). - `rates[].rate_mainstream_total` (number | null; required): Cheapest mainstream-OTA all-in price (only populated with `basis: mainstream`). - `rates[].mainstream_source` (string | null; required): OTA that produced the mainstream figure. - `rates[].aggregator_discount` (number | null; required): `rate_mainstream_total - rate_total` when both exist. - `rates[].implied_tax_rate` (number | null; required): `tax / rate_base`. - `rates[].provenance` (object; required): Provenance of one calendar row. ### Stay: `POST /v1/stay` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/stay One explicit stay window. `rate` is the WHOLE-STAY figure — length of stay moves the nightly price, so dividing it out would misrepresent it. Request body (JSON): - `token` (string; required; min length 8): Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date); required): Must be after `check_in`. The gap is the LOS, and the per-night price does change with it. - `market` (string | null; optional; one of AG, AT, AU, BE, BZ, CA, CH, DE, ES, FR, GB, IE, IT, MX, NL, NZ, PT, US): Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`. - `country` (string | null; optional; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): `gl` override. - `currency` (string | null; optional; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO currency for the returned prices. - `adults` (integer; optional; default 2; min 1, max 8): Occupancy: number of adults, 1-8. Children are not supported by the Google calendar. - `rates_include_tax` (boolean | null; optional): Which basis the summary price uses. Omit to take the market convention; pass the property's own setting to override. - `is_hostel` (boolean; optional; default false): Hostels are priced per bed rather than per room, so occupancy changes the rate differently. Set this and the per-person maths is applied. Response fields: - `nights` (integer; required): Nights between check_in and check_out. - `token` (string; required): Google property token. - `stay_date` (string (date); required): Stay (check-in) date. - `rate` (number; required): The market-correct figure to store: all-in (`rate_total`) when `rates_include_tax` is true, otherwise the pre-tax base. For `POST /v1/stay` it is the whole-stay figure. - `rate_base` (number | null; required): Room-only price before tax and mandatory fees. - `rate_before_taxes_with_fees` (number | null; required): `rate_base` + `fees` (The standard SERP API `extracted_price_before_taxes` basis). - `rate_total` (number | null; required): All-in price including tax and fees. - `tax` (number | null; required) - `fees` (number | null; required) - `currency` (string; required) - `market` (string; required) - `rates_include_tax` (boolean; required): Which basis `rate` uses. - `adults` (integer; required) - `los` (integer; required): Length of stay the price was quoted for. - `min_length_of_stay` (integer | null; required): Set when the night only prices at a longer stay; `rate` is then a per-night figure derived from that stay. - `rate_mainstream_base` (number | null; required): Cheapest mainstream-OTA base price (only populated with `basis: mainstream`). - `rate_mainstream_total` (number | null; required): Cheapest mainstream-OTA all-in price (only populated with `basis: mainstream`). - `mainstream_source` (string | null; required): OTA that produced the mainstream figure. - `aggregator_discount` (number | null; required): `rate_mainstream_total - rate_total` when both exist. - `implied_tax_rate` (number | null; required): `tax / rate_base`. - `provenance` (object; required): Provenance of one calendar row. - `provenance.schema_version` (integer; required): Provenance schema version (currently 1). - `provenance.observation_id` (string; required): Deterministic id of this price observation (`rateobs_...`). - `provenance.collection_id` (string; required): Id shared by every price from one upstream fetch (`ratecol_...`). - `provenance.observed_at` (string; required): UTC observation time, ISO-8601. - `provenance.source` (string; required): Upstream source, e.g. `google_hotels_calendar`. - `provenance.source_kind` (string; required): Kind of source, e.g. `calendar`, `offer`, `ota_calendar`, `official`. - `provenance.collector` (string; required): Identifier of the collector that produced the price. - `provenance.source_property_id` (string; required): Property identifier at the source. - `provenance.requested_market` (string | null; required) - `provenance.requested_currency` (string | null; required) - `provenance.returned_currency` (string | null; required) - `provenance.egress_mode` (string; required): How the request reached the source, e.g. `direct`. - `provenance.price_basis` (string; required): What the price represents, e.g. `room_base_before_taxes_and_fees`. - `provenance.derivation` (string; required): How the figure was derived, e.g. `normalized_upstream`. - `provenance.upstream_rate_id` (string | null; required): Source-native rate/room id when available. - `provenance.derived_fields` (array of string; required): Fields computed by ScraperCompany rather than read from the source. - `provenance.mainstream` (object; optional): Present only when mainstream figures were added (`basis: mainstream`). ### Offers: `POST /v1/offers` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/offers Per-OTA breakdown for one night. Heavier than /v1/calendar (~365 KB on the wire vs ~30 KB), so use it for the dates that matter, not all of them. Request body (JSON): - `token` (string; required; min length 8): Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Alternative to `nights`; wins if both are given. - `nights` (integer; optional; default 1; min 1, max 30): Ignored when `check_out` is given. - `market` (string | null; optional; one of AG, AT, AU, BE, BZ, CA, CH, DE, ES, FR, GB, IE, IT, MX, NL, NZ, PT, US): Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`. - `currency` (string | null; optional; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO currency for the returned prices. - `adults` (integer; optional; default 2; min 1, max 8): Occupancy: number of adults, 1-8. Children are not supported by the Google calendar. - `rates_include_tax` (boolean | null; optional): Which basis the summary price uses. Defaults to the market convention. - `property_name` (string; optional; default ): Improves official-site detection - `include_metasearch` (boolean; optional; default false): Include metasearch aggregators (Trivago, Vio, Kayak, Goseek) alongside real OTAs. Off by default: they resell other sources, so they inflate the offer count without adding inventory. - `free_cancellation_only` (boolean; optional; default false): Only offers with a stated free-cancellation deadline - `device` (string; optional; default iphone; one of android, desktop, iphone): Render profile. Google returns a different offer list per device and desktop is the thinnest — iphone found 17 offers where desktop found 12 on the same property. - `coverage` (integer; optional; default 1; min 1, max 3): Fetch this many device profiles and merge. Costs one ~3 MB page each; 2 is the sensible maximum. - `require_sources` (array of string | null; optional): Sources to insist on; retries a thin render. Defaults to official + Booking + Hotels.com + Expedia + Agoda. Pass [] to disable. Response fields: - `token` (string; required) - `check_in` (string (date); required) - `check_out` (string (date); required) - `nights` (integer; required) - `adults` (integer; required) - `device` (string; required) - `coverage` (integer; required): Device profiles fetched (echo of the request). - `currency` (string | null; required): Currency the page actually priced in. - `currency_matches_request` (boolean; required) - `requested_market` (string; required) - `egress_market` (string | null; required): Market the seller list is verified for, or null when unverified. - `egress_geo_locked_ok` (boolean; required) - `price_insights_market_verified` (boolean; required) - `rates_include_tax` (boolean; required): Basis used for `lowest_price_per_night`. - `lowest_price_per_night` (number | null; required) - `rooms_total` (integer; required) - `name` (string; required) - `hotel_class` (string; required) - `hotel_class_stars` (integer | null; required) - `rating` (number | null; required) - `reviews` (integer | null; required) - `deal` (string | null; required) - `deal_description` (string | null; required) - `has_deal` (boolean; required) - `price_insights` (object; required) - `price_insights.lowest_price` (string | null; required): As Google displays it, e.g. `$304`. - `price_insights.price_level` (string | null; required) - `price_insights.price_level_code` (integer | null; required) - `price_insights.typical_price_range` (object | null; required) - `sources` (array of string; required): Distinct sellers in `offers`. - `missing_sources` (array of string; required): Required sources not offered after retry. - `refundable_offers` (integer; required) - `wire_bytes` (integer; required) - `elapsed_s` (number; required) - `warnings` (array of string; required) - `offers` (array of object; required) - `offers[].source` (string; required): Normalized seller name, e.g. `Booking.com`, `Official site`. - `offers[].raw_source` (string; required): Seller name exactly as Google rendered it. - `offers[].is_official` (boolean; required) - `offers[].currency` (string | null; required) - `offers[].nights` (integer; required) - `offers[].room_id` (string | null; required): Seller-native room / rate-plan id. - `offers[].price_per_night` (number | null; required): All-in price per night. - `offers[].price_per_night_before_taxes` (number | null; required) - `offers[].total` (number | null; required): All-in price for the stay window. - `offers[].tax` (number | null; required) - `offers[].fees` (number | null; required) - `offers[].has_free_cancellation` (boolean; required) - `offers[].free_cancellation_until` (string | null; required) - `offers[].free_cancellation_time` (string | null; required) - `offers[].discount_remarks` (array of string; required): Member/loyalty remarks shown beside the offer. - `offers[].has_member_rate` (boolean; required) - `offers[].rooms` (array of object; required) - `offers[].headline_price_total` (number | null; required) - `offers[].headline_price_before_taxes` (number | null; required) - `offers[].price_derived_from_room` (boolean; required) - `offers[].provenance` (object; required): Where, when and how one normalized price was observed. ### Room matrix: `POST /v1/rooms` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/rooms Room types by OTA, aligned onto a comparable signature. Each OTA names the same room its own way — on one property the official site and Expedia shared **zero** names verbatim — so a pivot on the raw name shows every row filled by one source. Rows here are keyed on a normalised signature and every cell keeps the source's own wording. Room detail rides on Google's featured-offer blocks, which the thin variant of the page omits entirely. A source with `rooms: 0` means this render carried none for it, NOT that the OTA has no inventory. Request body (JSON): - `token` (string; required; min length 8): Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `market` (string | null; optional; one of AG, AT, AU, BE, BZ, CA, CH, DE, ES, FR, GB, IE, IT, MX, NL, NZ, PT, US): Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`. - `currency` (string | null; optional; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO currency for the returned prices. - `adults` (integer; optional; default 2; min 1, max 8): Occupancy: number of adults, 1-8. Children are not supported by the Google calendar. - `sources` (array of string | null; optional): Defaults to ['Official site', 'Booking.com', 'Hotels.com', 'Expedia'] Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of google_hotels_rooms) - `search_parameters.token` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.currency` (string; required) - `search_parameters.sources` (array of string; required) - `property` (object; required) - `property.name` (string; required) - `property.currency` (string; required) - `property.currency_matches_request` (boolean; required) - `property.requested_market` (string; required) - `property.egress_market` (string | null; required) - `property.egress_geo_locked_ok` (boolean; required) - `render` (object; required) - `render.wire_bytes` (integer; required) - `render.carried_room_detail` (boolean; required) - `sources` (array of object; required) - `sources[].source` (string; required) - `sources[].rooms` (integer; required): Distinct rooms this render carried for the source; 0 does NOT mean no inventory. - `sources[].cheapest` (number | null; required) - `sources[].dearest` (number | null; required) - `sources[].currency` (string; required) - `sources[].is_official` (boolean; required) - `sources[].duplicate_of` (string | null; required) - `sources[].provenance` (object | null; required): Where, when and how one normalized price was observed. - `rows` (array of object; required) - `rows[].signature` (string; required): Normalized room signature, e.g. `1 king`. - `rows[].cells` (object; required): Keyed by source name. - `totals` (object; required) - `totals.sources_present` (integer; required) - `totals.sources_with_rooms` (integer; required) - `totals.distinct_signatures` (integer; required) ### Destination search: `POST /v1/hotels/search` Cost: 3 credits (3 per page of results; an empty page and failed requests are free). Docs: https://scrapercompany.com/docs/reference/hotels-destination-search One page (~20) of the properties Google Hotels lists for a destination. Each property carries its `property_token` (feed it to `/v1/calendar` or `/v1/offers`), rating, class, amenities, images, coordinates, deal signal and the lowest price for the stay, itemised into base, taxes, fees and total with provenance. Vacation rentals add their seller rows. Page on with `pagination.next_page_token`, resending the same body. One upstream call per page. Prices follow the market Google sees the request from; `warnings` says when that market could not be verified. Request body (JSON): - `q` (string; required; min length 2, max length 200): Destination query exactly as a traveller would type it into Google Hotels, e.g. `hotels in Montreal`, `Paris`, `hotels near JFK`. Google resolves it to a place; the response reports which in `search_information.location`. - `adults` (integer; optional; default 2; min 1, max 10): Adults in the room. Encoded as one guest entry each, the way Google's own control sends them. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter Google country (market). Sets the market; the currency is requested separately. - `hl` (string; optional; default en; pattern ^[a-z]{2,3}(-[A-Za-z]{2,4})?$): Interface language. Display strings follow it; hotel amenity names are always English. - `sort_by` (string; optional; default relevance; one of highest_rating, lowest_price, most_reviewed, relevance): Result order, as Google's Sort by control. - `price_min` (integer | null; optional; min 0): Minimum nightly price in `currency`. - `price_max` (integer | null; optional; min 0): Maximum nightly price in `currency`. - `free_cancellation` (boolean; optional; default false): Only properties Google lists with free cancellation. - `special_offers` (boolean; optional; default false): Only properties with a special offer. - `eco_certified` (boolean; optional; default false): Only eco-certified properties. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date); required): Departure date, after `check_in`; at most 30 nights. - `children_ages` (array of integer; optional; default []; max items 8): One age (0-17) per child. Google prices on each age; the response is rejected if Google priced a different party. - `page_token` (string | null; optional; pattern ^[A-Za-z0-9_\-+/=]{1,200}$): Opaque cursor from `pagination.next_page_token` of the previous page. Resend the same query, stay, occupancy and filters with it, exactly as with SERP API. - `min_rating` (number | null; optional; one of 3.5, 4, 4.5): Minimum guest rating: 3.5, 4.0 or 4.5. - `hotel_class` (array of integer; optional; default []; max items 4): Star classes to include, 2-5. - `amenities` (array of integer; optional; default []; max items 19): Amenity filter ids: 1 Free parking, 3 Parking, 4 Indoor pool, 5 Outdoor pool, 6 Pool, 7 Fitness center, 8 Restaurant, 9 Free breakfast, 10 Spa, 11 Beach access, 12 Child-friendly, 15 Bar, 19 Pet-friendly, 22 Room service, 35 Free Wi-Fi, 40 Air-conditioned, 52 All-inclusive available, 53 Wheelchair accessible, 61 EV charger. - `property_types` (array of integer; optional; default []; max items 13): Property-type filter ids: 12 Beach hotels, 13 Boutique hotels, 14 Hostels, 15 Inns, 16 Motels, 17 Resorts, 18 Spa hotels, 19 Bed and breakfasts, 20 Other, 21 Apartment hotels, 22 Minshuku, 23 Japanese-style business hotels, 24 Ryokan. Response fields: - `search_parameters` (object; required): Echo of the effective request. Optional filters appear only when set. - `search_parameters.engine` (string; required; one of google_hotels_search) - `search_parameters.q` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.children_ages` (array of integer; required): One age per child; empty when none. - `search_parameters.currency` (string; required): Requested currency, upper-case. - `search_parameters.gl` (string; required): Market country code, lower-case. - `search_parameters.hl` (string; required) - `search_parameters.sort_by` (string; required; one of relevance, lowest_price, highest_rating, most_reviewed) - `search_parameters.price_min` (integer; optional): Present only when set in the request. - `search_parameters.price_max` (integer; optional): Present only when set in the request. - `search_parameters.min_rating` (number; optional): 3.5, 4.0 or 4.5. Present only when set in the request. - `search_parameters.hotel_class` (array of integer; optional): Present only when set in the request. - `search_parameters.amenities` (array of integer; optional): Present only when set in the request. - `search_parameters.property_types` (array of integer; optional): Present only when set in the request. - `search_parameters.free_cancellation` (boolean; optional): Present only when true. - `search_parameters.special_offers` (boolean; optional): Present only when true. - `search_parameters.eco_certified` (boolean; optional): Present only when true. - `search_parameters.next_page_token` (string; optional): Page token this page was fetched with. Present only when one was sent. - `search_information` (object; required) - `search_information.total_results` (integer | null; required): Total properties Google reports for the search. - `search_information.location` (string | null; required): Place Google resolved `q` to. - `search_information.location_data_id` (string | null; required): Google's place id for `location`. - `search_information.nights` (integer; required) - `search_information.returned` (integer; required): Properties on this page. - `search_information.priced` (integer; required): Properties on this page with a known stay total. - `search_information.requested_currency` (string; required) - `search_information.returned_currency` (string | null; required): Currency the prices came back in; `MIXED` when properties differ; null when no property carried a currency. - `search_information.currency_matches_request` (boolean; required): False when Google returned another currency (also reported in `warnings`). - `search_information.requested_market` (string; required): `gl`, upper-cased. - `search_information.available_property_types` (array of object; required): Property-type filters Google offers for this destination. - `properties` (array of object; required): About 20 per page. - `properties[].type` (string; required; one of hotel, vacation_rental): Google blends vacation rentals into the default list; this says which each result is. - `properties[].property_token` (string; required): Google property token; pass it to `/v1/calendar` or `/v1/offers`. - `properties[].name` (string; required) - `properties[].data_id` (string | null; required): Google Maps data id (`0x...:0x...`). - `properties[].description` (string | null; required) - `properties[].link` (string | null; required): The property's own website, when Google lists one. - `properties[].gps_coordinates` (object | null; required) - `properties[].country` (string | null; required): ISO 3166-1 alpha-2 country code. - `properties[].check_in_time` (string | null; required): As displayed, e.g. `3:00 PM`. - `properties[].check_out_time` (string | null; required): As displayed, e.g. `11:00 AM`. - `properties[].hotel_class` (string | null; required): As displayed, e.g. `4-star hotel`. - `properties[].extracted_hotel_class` (integer | null; required): Star class, 1-5. - `properties[].rating` (number | null; required): Guest rating out of 5. - `properties[].reviews` (integer | null; required): Number of reviews. - `properties[].reviews_histogram` (object | null; required): Review count per star rating, keyed `1`-`5` (only the stars Google reported). Null when Google gave none. - `properties[].location_rating` (number | null; required): Overall location score, out of 5. Null when Google has no score. - `properties[].proximity_to_things_to_do_rating` (number | null; required): Score for proximity to things to do, out of 5. Null when Google has no score. - `properties[].proximity_to_restaurants_rating` (number | null; required): Score for proximity to restaurants, out of 5. Null when Google has no score. - `properties[].proximity_to_transit_rating` (number | null; required): Score for proximity to public transit, out of 5. Null when Google has no score. - `properties[].airport_access_rating` (number | null; required): Score for airport access, out of 5. Null when Google has no score. - `properties[].reviews_breakdown` (array of object; required): Review topics with mention counts; empty when Google gave none. - `properties[].amenities` (array of string; required): Amenity names. Hotel amenity names are always English; rentals use Google's own labels. - `properties[].amenity_codes` (array of array of integer; required): Raw `[flag, code]` pairs from the card. Codes are not the `amenities` filter ids; codes without a known name appear only here. The flag does not mark an amenity as absent. - `properties[].excluded_amenities` (array of string; required): Amenities a rental states it lacks, e.g. `No balcony`; usually empty for hotels. - `properties[].essential_info` (array of string; required): Rental basics such as `Entire apartment` or `Sleeps 2`; usually empty for hotels. - `properties[].thumbnail` (string | null; required) - `properties[].images` (array of object; required) - `properties[].nearby_places` (array of object; required) - `properties[].deal` (string | null; required): Deal text, e.g. `27% less than usual` or `Great price for a 4-star hotel`. Null when there is no deal. - `properties[].deal_description` (string | null; required): Badge Google renders: `Deal`, `Great Deal`, `Great Price`, or another label. - `properties[].deal_kind` (string | null; required): `below_usual_price`, `great_price`, or `code_` for a deal type not yet mapped. Null when there is no deal. - `properties[].rate` (object | null; required): Lowest price for the stay. Null when the card carried no price, or Google priced other dates and the price was removed (see `warnings`). - `properties[].sources` (array of object; required): Seller rows Google attached to the card; mostly vacation rentals, usually empty for hotels. - `properties[].provenance` (object | null; required): Provenance of `rate`; null unless `rate.total` is known. - `brands` (array of object; required) - `brands[].id` (integer; required): Google brand id. - `brands[].title` (string; required): Brand name; empty string when Google did not name it. - `brands[].children` (array of object; required): Sub-brands. - `pagination` (object; required): Pages overlap by a few results (page 2 starts before page 1 ends); de-duplicate by `property_token`. - `pagination.records_from` (integer | null; required): 1-based position of the first result on this page. - `pagination.records_to` (integer | null; required): 1-based position of the last result on this page. - `pagination.next_page_token` (string | null; required): Send it back (as `page_token` on `/v1/hotels/search`, `next_page_token` on `/v1/serp/google_hotels`) with the same query, stay, party and filters for the next page. Null on the last page. - `warnings` (array of string; required): Notices about this page: prices removed because Google priced other dates, a currency other than the one requested, results outside a requested `hotel_class`, `min_rating` or `price_max`, or prices not verified for the requested market. - `meta` (object; required) - `meta.wire_bytes` (integer; required): Bytes received from Google. - `meta.elapsed_s` (number; required): Seconds spent fetching from Google. - `meta.egress` (object; required): How the request reached Google. - `meta.skipped_records` (integer; required): Result cards that could not be read and were left out. ## Booking.com Name search, calendar and rooms from Booking.com. ### Booking.com search: `POST /v1/ota/booking/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/booking-search Resolve a hotel name to Booking.com's country/slug identifier. Add `city` whenever possible. A slug is stable, so search once during onboarding and store `recommended_match` for calendar and room calls. It is null when only weak or ambiguous candidates were found; `matches` remains available for manual review. Request body (JSON): - `name` (string; required; min length 1): Hotel name as a guest would search for it. - `city` (string; optional; default ): Strongly recommended for common hotel names. It is sent to Booking.com with the name so results come from the intended city. - `limit` (integer; optional; default 5; min 1, max 10): Maximum candidates to return, best match first. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of booking_search) - `search_parameters.name` (string; required) - `search_parameters.city` (string; required) - `search_parameters.limit` (integer; required) - `search_status` (string; required; one of matched, ambiguous, not_found): `matched` only when the top candidate clears the identity threshold and margin. - `recommended_match` (object | null; required): Safe to store; null unless `search_status` is `matched`. - `recommended_match.pagename` (string; required): URL slug; pass as `pagename`. - `recommended_match.country` (string; required): Two-letter URL segment; pass as `country`. - `recommended_match.name` (string; required) - `recommended_match.url` (string; required) - `recommended_match.rank` (integer; required) - `recommended_match.name_score` (number; required) - `recommended_match.identity_score` (number; required) - `recommended_match.match_score` (number; required) - `recommended_match.confidence` (string; required; one of high, medium, low) - `warnings` (array of string; required) - `matches` (array of object; required): Candidates, best first, for manual review. - `matches[].pagename` (string; required): URL slug; pass as `pagename`. - `matches[].country` (string; required): Two-letter URL segment; pass as `country`. - `matches[].name` (string; required) - `matches[].url` (string; required) - `matches[].rank` (integer; required) - `matches[].name_score` (number; required) - `matches[].identity_score` (number; required) - `matches[].match_score` (number; required) - `matches[].confidence` (string; required; one of high, medium, low) - `meta` (object; required) - `meta.source` (string; required) - `meta.matches` (integer; required) - `meta.selection_method` (string; required) - `meta.match_threshold` (number; required) - `meta.match_margin` (number; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) ### Booking.com calendar: `POST /v1/ota/booking` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/booking-calendar Booking.com forward horizon — 61 dates per call. Request body (JSON): - `pagename` (string; required; min length 2): URL slug returned by `POST /v1/ota/booking/search`. For `booking.com/hotel/us/moxy-boston-downtown.html` the slug is `moxy-boston-downtown` and `country` is `us`. - `country` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw; min length 2, max length 2): The two-letter segment in the URL *before* the slug — part of the property's address on Booking, not your own location. - `start` (string (date) | null; optional): Defaults to today. - `days` (integer; optional; default 61; min 1, max 365): Booking truncates any single response to 61 days, so larger windows are paged automatically — a year is 6 calls, not 1. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `rooms` (integer; optional; default 1; min 1, max 8): Rooms requested. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of booking_calendar) - `search_parameters.pagename` (string; required) - `search_parameters.country` (string; required) - `search_parameters.start_date` (string (date); required) - `search_parameters.days` (integer; required) - `search_parameters.currency` (string; required) - `search_parameters.adults` (integer; required) - `search_parameters.rooms` (integer; required) - `property` (object; required) - `property.pagename` (string; required) - `property.hotel_id` (integer | null; required): Booking.com's numeric hotel id as returned upstream. - `calendar` (array of object; required) - `calendar[].stay_date` (string (date); required) - `calendar[].available` (boolean; required) - `calendar[].price` (number | null; required): Null for unsellable dates. - `calendar[].currency` (string; required) - `calendar[].min_length_of_stay` (integer | null; required) - `calendar[].provenance` (object; required): Where, when and how one normalized price was observed. - `unavailable_dates` (array of string (date); required) - `meta` (object; required) - `meta.source` (string; required; one of booking) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.calls` (integer; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) - `meta.dates` (integer; required) - `meta.priced` (integer; required) ### Booking.com rooms: `POST /v1/ota/booking/rooms` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/booking-rooms Booking.com room types and rate plans for one stay window. Fills the gap left by `/v1/rooms`: Google's entity page frequently carries no room detail for the Booking.com row, so this goes to Booking directly. Prices come from the property page's room grid, enriched with room size and occupancy when Booking.com provides them. Request body (JSON): - `pagename` (string; required; min length 2): URL slug returned by `POST /v1/ota/booking/search`, e.g. `moxy-boston-downtown` from `booking.com/hotel/us/moxy-boston-downtown.html`. - `country` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter segment before the slug in that URL. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `rooms` (integer; optional; default 1; min 1, max 8): Rooms requested. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. Response fields: - `pagename` (string; required) - `hotel_id` (string; required): Empty string when the room catalogue was unavailable. - `property_name` (string; required) - `check_in` (string (date); required) - `check_out` (string (date); required) - `nights` (integer; required) - `currency` (string; required) - `sold_out` (boolean | null; required) - `rendered` (boolean; required) - `catalogue_from_graphql` (boolean; required): Whether room size / occupancy enrichment was available. - `cheapest_rate` (number | null; required) - `wire_bytes` (integer; required) - `collection_id` (string; required) - `observed_at` (string; required) - `rooms` (array of object; required) - `rooms[].name` (string; required) - `rooms[].room_id` (string; required) - `rooms[].beds` (string; required) - `rooms[].room_size` (number | null; required) - `rooms[].max_persons` (integer | null; required) - `rooms[].cheapest_rate` (number | null; required) - `rooms[].rate_plans` (array of object; required) ## Hotels.com Name search, prices and rooms from Hotels.com. ### Hotels.com search: `POST /v1/ota/hotels/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hotels-search Resolve a hotel name to Hotels.com's numeric property identifier. This uses Hotels.com's lightweight typeahead response. Add `city` to disambiguate common brands, then store `recommended_match.property_id` for headline-price and room calls. It is null when only weak or ambiguous candidates were found. Request body (JSON): - `name` (string; required; min length 1): Hotel name as a guest would search for it. - `city` (string; optional; default ): Strongly recommended. Used both in Hotels.com's query and in local candidate ranking so same-brand hotels in other cities rank lower. - `market` (string; optional; default US; one of AU, CA, DE, EU, FR, GB, IE, IT, NL, NZ, US): Hotels.com point-of-sale used for search results. This also matches the market accepted by the rate and room endpoints. - `limit` (integer; optional; default 5; min 1, max 10): Maximum hotel candidates to return, best match first. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of hotels_search) - `search_parameters.name` (string; required) - `search_parameters.city` (string; required) - `search_parameters.market` (string; required) - `search_parameters.limit` (integer; required) - `search_status` (string; required; one of matched, ambiguous, not_found): `matched` only when the top candidate clears the identity threshold and margin. - `recommended_match` (object | null; required): Safe to store; null unless `search_status` is `matched`. - `recommended_match.property_id` (string; required): Numeric Hotels.com id (digits); pass as `property_id`. - `recommended_match.name` (string; required) - `recommended_match.city` (string; required) - `recommended_match.address` (string; required) - `recommended_match.country` (string; required) - `recommended_match.url` (string; required) - `recommended_match.rank` (integer; required) - `recommended_match.score` (number; required) - `recommended_match.name_score` (number; required) - `recommended_match.identity_score` (number; required) - `recommended_match.match_score` (number; required) - `recommended_match.confidence` (string; required; one of high, medium, low) - `recommended_match.winner_reason` (string; required) - `recommended_match.city_score` (number; optional): Present only when `city` was supplied. - `recommended_match.coordinates` (object; optional): Present only when the source returned coordinates. - `warnings` (array of string; required) - `matches` (array of object; required): Candidates, best first, for manual review. - `matches[].property_id` (string; required): Numeric Hotels.com id (digits); pass as `property_id`. - `matches[].name` (string; required) - `matches[].city` (string; required) - `matches[].address` (string; required) - `matches[].country` (string; required) - `matches[].url` (string; required) - `matches[].rank` (integer; required) - `matches[].score` (number; required) - `matches[].name_score` (number; required) - `matches[].identity_score` (number; required) - `matches[].match_score` (number; required) - `matches[].confidence` (string; required; one of high, medium, low) - `matches[].winner_reason` (string; required) - `matches[].city_score` (number; optional): Present only when `city` was supplied. - `matches[].coordinates` (object; optional): Present only when the source returned coordinates. - `meta` (object; required) - `meta.source` (string; required) - `meta.matches` (integer; required) - `meta.selection_method` (string; required) - `meta.match_threshold` (number; required) - `meta.match_margin` (number; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) ### Hotels.com price: `POST /v1/ota/hotels` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hotels-price Hotels.com headline price for one stay window. One small request. `price_per_night` is the sticky bar's lead price, as it always was; on the US and DE points-of-sale that is the stay total including taxes and fees, so `price_per_night_is` says which it is and `total`/`nightly` carry the labelled figures. An unbookable stay is `available: false` with Hotels.com's own `unavailable_reason`, billed like any other answer; only a reply with nothing in it is free. Request body (JSON): - `property_id` (string; required; min length 1): Numeric id returned by `POST /v1/ota/hotels/search`. For `hotels.com/h38766175.Hotel-Information` it is `38766175` — digits only, no leading `h`. The `ho…` number in a page URL is a legacy id the rate endpoints do not price. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `market` (string; optional; default US; one of AU, CA, DE, EU, FR, GB, IE, IT, NL, NZ, US): Point-of-sale, which is how currency is selected — there is no currency field. **Prices are not comparable across markets**: the display basis differs, so the same night reads 527 USD on `US` and 585 CAD on `CA`, an implied 1.11 against a real rate near 1.37. Pick one market per comparison. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of hotels_property) - `search_parameters.property_id` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.market` (string; required) - `search_parameters.currency` (string; required): The market's currency. - `property` (object; required) - `property.property_id` (string; required) - `property.price_per_night` (number | null; required) - `property.currency` (string; required): Currency the point-of-sale actually priced in. - `property.currency_verified` (boolean; required) - `property.available` (boolean; required) - `property.provenance` (object; required): Where, when and how one normalized price was observed. - `meta` (object; required) - `meta.source` (string; required; one of hotels) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.nights` (integer; required) - `meta.elapsed_s` (number; required) - `meta.comparable_across_markets` (boolean; required): Always false. ### Hotels.com rooms: `POST /v1/ota/hotels/rooms` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hotels-rooms Hotels.com room types and rate plans for one stay window. One request: the same document as `/v1/ota/hotels` with the room grid included. Each rate plan keeps its `price` (the card's lead price; on the US and DE points-of-sale the stay total including taxes and fees) and adds the labelled `total` and `nightly`, a derived `taxes_and_fees`, the payment model and the inventory source. ~100-200 KB against ~6 KB for the headline price, so use it on the dates that matter rather than sweeping a horizon. Request body (JSON): - `property_id` (string; required; min length 1): Numeric id returned by `POST /v1/ota/hotels/search`, or from `hotels.com/h38766175.Hotel-Information` (not the legacy `ho…` number). - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `market` (string; optional; default US; one of AU, CA, DE, EU, FR, GB, IE, IT, NL, NZ, US): Point-of-sale; also selects the currency. Response fields: - `property_id` (string; required) - `market` (string; required) - `check_in` (string (date); required) - `check_out` (string (date); required) - `nights` (integer; required) - `currency` (string; required) - `sold_out` (boolean; required) - `cheapest_rate` (number | null; required) - `wire_bytes` (integer; required) - `collection_id` (string; required) - `observed_at` (string; required) - `rooms` (array of object; required) - `rooms[].name` (string; required) - `rooms[].unit_id` (string; required) - `rooms[].cheapest_rate` (number | null; required) - `rooms[].rate_plans` (array of object; required) ## Expedia Name search, then rooms and rate plans for one stay from Expedia. ### Expedia search: `POST /v1/ota/expedia/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/expedia-search Resolve a hotel name to Expedia's numeric property identifier. Uses Expedia's own typeahead (one small request). Add `city` to disambiguate brands, then store `recommended_match.property_id` for `POST /v1/ota/expedia`. It is null when only weak or ambiguous candidates were found. Expedia ids match Hotels.com's for newer properties only. Request body (JSON): - `name` (string; required; min length 1): Hotel name as a guest would search for it. - `city` (string; optional; default ): Strongly recommended. Sent with the name to Expedia's typeahead and used to rank same-brand hotels in other cities lower. - `market` (string; optional; default US; one of CA, US): Expedia point-of-sale, which is how currency is selected - there is no currency field. `US` prices in USD on www.expedia.com, `CA` in CAD on www.expedia.ca. The display basis differs by market (the US room card leads with the stay total, CA with the nightly price), so compare within one market. - `limit` (integer; optional; default 5; min 1, max 10): Maximum hotel candidates to return, best match first. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of expedia_search) - `search_parameters.name` (string; required) - `search_parameters.city` (string; required) - `search_parameters.market` (string; required): Point-of-sale searched: `US` (www.expedia.com) or `CA` (www.expedia.ca). - `search_parameters.limit` (integer; required) - `search_status` (string; required; one of matched, ambiguous, not_found): `matched` only when the top candidate clears the identity threshold and margin. - `recommended_match` (object | null; required): Safe to store; null unless `search_status` is `matched`. - `recommended_match.property_id` (string; required): Numeric Expedia id (digits); pass as `property_id` to `POST /v1/ota/expedia` or as `expedia_property_id` to `POST /v1/ota/compare`. Matches the Hotels.com id only for newer properties. - `recommended_match.name` (string; required) - `recommended_match.city` (string; required) - `recommended_match.address` (string; required) - `recommended_match.country` (string; required) - `recommended_match.url` (string; required): Expedia property page, `https:///h.Hotel-Information`. - `recommended_match.rank` (integer; required) - `recommended_match.score` (number; required) - `recommended_match.name_score` (number; required) - `recommended_match.identity_score` (number; required) - `recommended_match.match_score` (number; required) - `recommended_match.confidence` (string; required; one of high, medium, low) - `recommended_match.winner_reason` (string; required) - `recommended_match.city_score` (number; optional): Present only when `city` was supplied. - `recommended_match.coordinates` (object; optional): Present only when the source returned coordinates. - `warnings` (array of string; required) - `matches` (array of object; required): Candidates, best first, for manual review. - `matches[].property_id` (string; required): Numeric Expedia id (digits); pass as `property_id` to `POST /v1/ota/expedia` or as `expedia_property_id` to `POST /v1/ota/compare`. Matches the Hotels.com id only for newer properties. - `matches[].name` (string; required) - `matches[].city` (string; required) - `matches[].address` (string; required) - `matches[].country` (string; required) - `matches[].url` (string; required): Expedia property page, `https:///h.Hotel-Information`. - `matches[].rank` (integer; required) - `matches[].score` (number; required) - `matches[].name_score` (number; required) - `matches[].identity_score` (number; required) - `matches[].match_score` (number; required) - `matches[].confidence` (string; required; one of high, medium, low) - `matches[].winner_reason` (string; required) - `matches[].city_score` (number; optional): Present only when `city` was supplied. - `matches[].coordinates` (object; optional): Present only when the source returned coordinates. - `meta` (object; required) - `meta.source` (string; required; one of expedia) - `meta.matches` (integer; required) - `meta.selection_method` (string; required) - `meta.match_threshold` (number; required) - `meta.match_margin` (number; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) - `meta.egress_mode` (string; required; one of direct, proxy): How the request was routed: `direct` or `proxy`. ### Expedia rates: `POST /v1/ota/expedia` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/expedia-rates Expedia's own rooms and rate plans. One request per stay. Each offer has the upstream stay `total` (Expedia labels it "Total with taxes and fees"), the upstream `nightly` price before taxes, `taxes_and_fees` derived from the two (see its provenance), cancellation terms read from the policy selector, and the payment model. `available` is false with Expedia's own `unavailable_reason` when the stay cannot be booked as asked - a minimum stay, for instance. That answer is billed like any other: only a reply with nothing in it is free. Request body (JSON): - `property_id` (string; required; min length 1, pattern ^\d+$): Numeric id returned by `POST /v1/ota/expedia/search`. For `expedia.com/Chicago-Hotels-Hilton-Chicago.h12570.Hotel-Information` it is `12570`. Not always the Hotels.com id: older properties differ between brands. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 28): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. - `market` (string; optional; default US; one of CA, US): Expedia point-of-sale, which is how currency is selected - there is no currency field. `US` prices in USD on www.expedia.com, `CA` in CAD on www.expedia.ca. The display basis differs by market (the US room card leads with the stay total, CA with the nightly price), so compare within one market. - `rooms` (boolean; optional; default true): Return every room type and rate plan (~50-250 KB upstream). False returns the headline price only (~6 KB). Same credit cost. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of expedia_property) - `search_parameters.property_id` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.market` (string; required): `US` or `CA`. - `search_parameters.currency` (string; required): The market's currency (`USD` for `US`, `CAD` for `CA`). - `search_parameters.rooms` (boolean; required): Whether room types and rate plans were requested. - `property` (object; required) - `property.property_id` (string; required) - `property.total` (number | null; required): Headline stay total for all nights; see `basis` and `taxes_and_fees_included`. Null when nothing priced. - `property.price_per_night` (number | null; required): Headline nightly price, before taxes and fees (Expedia rounds it to whole units). - `property.basis` (string | null; required; one of sticky_bar, cheapest_offer): Where the headline comes from: `sticky_bar` (the page's own headline price, read by its labels) or `cheapest_offer` (the cheapest priced offer). Null when nothing priced. - `property.total_text` (string; required): Headline total as displayed; empty when not shown. - `property.nightly_text` (string; required): Headline nightly price as displayed; empty when not shown. - `property.taxes_and_fees_included` (boolean | null; required): True when the headline total is labelled "with taxes and fees"; null when no such label was shown. - `property.fees_included` (boolean | null; required): True when the headline total is labelled "All fees included"; null when no such label was shown. - `property.currency` (string; required): Currency the point-of-sale actually priced in. - `property.currency_verified` (boolean; required): Whether `currency` equals the market's currency. - `property.available` (boolean; required): False when nothing is bookable for this stay as asked. - `property.unavailable_reason` (string | null; required): Expedia's own message when it says why the stay cannot be booked, e.g. `This property requires you to stay at least 4 nights`. Null otherwise; `available` can be false with a null reason when nothing priced. - `property.cheapest_total` (number | null; required): Lowest offer `total` across `rooms`; null when `rooms` was false or no offer priced. - `property.provenance` (object; required): Where, when and how one normalized price was observed. - `rooms` (array of object; required): Every room type with its offers. Empty when the request set `rooms: false`. - `rooms[].unit_id` (string; required): Room type id. A vacation rental listed on Expedia is one room with `unit_id` = `property_id` and name `entire unit`. - `rooms[].name` (string; required): Room name as displayed, e.g. `Room, 1 King Bed`. - `rooms[].cheapest_total` (number | null; required): Lowest `total` among this room's offers; null when none priced. - `rooms[].offers` (array of object; required) - `meta` (object; required) - `meta.source` (string; required; one of expedia) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.nights` (integer; required) - `meta.wire_bytes` (integer; required): Bytes received from the source. - `meta.elapsed_s` (number; required) - `meta.egress_mode` (string; required; one of direct, proxy): How the request was routed: `direct` or `proxy`. - `meta.room_types` (integer; required): 0 when `rooms` was false. - `meta.offers` (integer; required): Offers across all rooms; 0 when `rooms` was false. - `meta.comparable_across_markets` (boolean; required): Always false: the display basis differs by market. ## Agoda Name search and rooms from Agoda. ### Agoda search: `POST /v1/ota/agoda/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/agoda-search Resolve a hotel name to Agoda's numeric property identifier. This uses Agoda's lightweight guest-facing suggestion endpoint. Add `city` to disambiguate common brands, then store `recommended_match.property_id` for room and rate-plan calls. It is null when only weak or ambiguous candidates were found. Request body (JSON): - `name` (string; required; min length 1): Hotel name as a guest would search for it. - `city` (string; optional; default ): Strongly recommended. Included in Agoda's query and used to rank same-brand results in the intended city. - `origin` (string; optional; default US; one of AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UK, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW; min length 2, max length 2): Two-letter user-country context sent to Agoda. This is not the hotel's country; `city` identifies the location. - `limit` (integer; optional; default 5; min 1, max 10): Maximum hotel candidates to return, best match first. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of agoda_search) - `search_parameters.name` (string; required) - `search_parameters.city` (string; required) - `search_parameters.origin` (string; required) - `search_parameters.limit` (integer; required) - `search_status` (string; required; one of matched, ambiguous, not_found): `matched` only when the top candidate clears the identity threshold and margin. - `recommended_match` (object | null; required): Safe to store; null unless `search_status` is `matched`. - `recommended_match.property_id` (string; required): Numeric Agoda id; pass as `property_id`. - `recommended_match.name` (string; required) - `recommended_match.city` (string; required) - `recommended_match.country` (string; required) - `recommended_match.location` (string; required) - `recommended_match.rank` (integer; required) - `recommended_match.score` (number; required) - `recommended_match.name_score` (number; required) - `recommended_match.identity_score` (number; required) - `recommended_match.match_score` (number; required) - `recommended_match.confidence` (string; required; one of high, medium, low) - `recommended_match.city_score` (number; optional): Present only when `city` was supplied. - `warnings` (array of string; required) - `matches` (array of object; required): Candidates, best first, for manual review. - `matches[].property_id` (string; required): Numeric Agoda id; pass as `property_id`. - `matches[].name` (string; required) - `matches[].city` (string; required) - `matches[].country` (string; required) - `matches[].location` (string; required) - `matches[].rank` (integer; required) - `matches[].score` (number; required) - `matches[].name_score` (number; required) - `matches[].identity_score` (number; required) - `matches[].match_score` (number; required) - `matches[].confidence` (string; required; one of high, medium, low) - `matches[].city_score` (number; optional): Present only when `city` was supplied. - `meta` (object; required) - `meta.source` (string; required) - `meta.matches` (integer; required) - `meta.selection_method` (string; required) - `meta.match_threshold` (number; required) - `meta.match_margin` (number; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) ### Agoda rooms: `POST /v1/ota/agoda` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/agoda-rooms Agoda: every room type and rate plan for one stay window. Request body (JSON): - `property_id` (string; required; min length 1): Numeric id returned by `POST /v1/ota/agoda/search`, or from the Agoda URL — the digits in `agoda.com/…/hotel/…-h8795952.html`, or the `hotelId` query parameter. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `rooms` (integer; optional; default 1; min 1, max 8): Rooms requested. - `currency` (string; optional; default USD; one of AED, AUD, BRL, CAD, CHF, CZK, EUR, GBP, HKD, IDR, INR, JPY, KRW, MYR, NZD, PHP, PLN, SEK, SGD, THB, TWD, USD, ZAR): One of 23 supported. Unlike Hotels.com these ARE comparable — Agoda converts one underlying rate. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of agoda_property) - `search_parameters.property_id` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.rooms` (integer; required) - `search_parameters.currency` (string; required) - `property` (object; required) - `property.property_id` (string; required) - `property.name` (string; required) - `property.price_per_night` (number | null; required): Cheapest priced offer. - `property.currency` (string; required): ISO code of the cheapest offer (the requested currency when nothing priced). - `property.currency_display` (string | null; required) - `property.tax_inclusive` (boolean | null; required) - `property.sold_out` (boolean; required) - `property.provenance` (object | null; required): Provenance of the cheapest priced row; null when nothing priced. - `property.rooms` (array of object; required) - `meta` (object; required) - `meta.source` (string; required; one of agoda) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.nights` (integer; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) - `meta.room_types` (integer; required) - `meta.offers` (integer; required) - `meta.comparable_across_markets` (boolean; required): Always true. ## Tripadvisor Metasearch offers from Tripadvisor. ### Tripadvisor search: `POST /v1/ota/tripadvisor/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/tripadvisor-search **Not available yet.** Tripadvisor name search is not implemented in the current release: this operation always returns `502` with `{"detail": "TripadvisorError"}` (not charged). Take the `locationId` from the hotel's Tripadvisor URL instead — the digits after `-d` in `/Hotel_Review-g{geoId}-d{locationId}-...` — and pass it to `POST /v1/ota/tripadvisor`. The 200 example below shows the planned response shape. Resolve a hotel name to Tripadvisor's locationId. Uses Tripadvisor's own typeahead after a one-request session warmup - without a browser, ~1-10 KB. Add `city` to rank same-brand hotels elsewhere lower, then store `recommended_match.location_id` for `POST /v1/ota/tripadvisor` and `/v1/ota/tripadvisor/reviews`. It is null when only weak or ambiguous candidates were found. Request body (JSON): - `name` (string; required; min length 1): Hotel name as a guest would search for it (`query` is accepted as an alias). - `city` (string; optional; default ): Strongly recommended. Sent with the name to Tripadvisor's typeahead and used to rank same-brand hotels in other cities lower. - `limit` (integer; optional; default 5; min 1, max 10): Maximum hotel candidates to return, best match first. ### Tripadvisor prices: `POST /v1/ota/tripadvisor` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/tripadvisor-prices Tripadvisor metasearch: aggregated offers from multiple providers. Returns prices from Booking, Hotels.com, Expedia, and other providers as aggregated by Tripadvisor, for exactly the stay asked: the reply echoes the stay it priced and a different one is refused (503), never returned. Each offer's lead `price` means what its `pricing_mode` says - nightly or whole stay, before or after taxes, which Tripadvisor chooses per hotel - and `total` is the all-in stay total. `property.price_per_night` is the cheapest offer's nightly price before taxes. Request body (JSON): - `location_id` (string; required; min length 1, pattern ^\d+$): Numeric id returned by `POST /v1/ota/tripadvisor/search` (the digits after `-d` in a `/Hotel_Review-g…-d…` URL). - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `rooms` (integer; optional; default 1; min 1, max 8): Rooms requested. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, CZK, DKK, EUR, GBP, HKD, HUF, IDR, INR, JPY, KRW, MXN, MYR, NOK, NZD, PHP, PLN, SAR, SEK, SGD, THB, TWD, USD): One of 30 supported currencies. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of tripadvisor_property) - `search_parameters.location_id` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.nights` (integer; required) - `search_parameters.adults` (integer; required) - `search_parameters.rooms` (integer; required) - `search_parameters.currency` (string; required) - `property` (object; required) - `property.location_id` (string; required) - `property.hotel_id` (string; required) - `property.price_per_night` (number | null; required): Cheapest provider offer. - `property.currency` (string; required): The requested currency. - `property.provenance` (object | null; required): Provenance of the cheapest priced row; null when nothing priced. - `offers` (array of object; required) - `offers[].provider` (string; required) - `offers[].provider_name` (string; required): Same value as `provider`. - `offers[].location_id` (string; required) - `offers[].check_in` (string (date); required) - `offers[].check_out` (string (date); required) - `offers[].price` (number; required) - `offers[].price_value` (number; required): Same value as `price`. - `offers[].currency` (string; required) - `offers[].price_currency` (string; required): Same value as `currency`. - `offers[].room_plan` (string; required; one of , CP, EP, MAP, AP) - `offers[].offer_type` (string; required; one of chevron, hidden) - `offers[].provenance` (object; required): Where, when and how one normalized price was observed. - `meta` (object; required) - `meta.source` (string; required; one of tripadvisor) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.nights` (integer; required) - `meta.wire_bytes` (integer; required): Estimated. - `meta.elapsed_s` (number; required) - `meta.offers` (integer; required) ## Hostelworld Dorms and private rooms from Hostelworld. ### Hostelworld rooms: `POST /v1/ota/hostelworld` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hostelworld-rooms Hostelworld: every dorm bed and private room with rate plans. Currency is NOT selectable — Hostelworld returns the property's native currency (typically GBP for UK hostels). Per-bed pricing for dorms, per-room pricing for privates. Request body (JSON): - `property_id` (string; required; min length 1): Numeric property id from Hostelworld URL, e.g. `hostelworld.com/pwa/hosteldetails.php/88047/...` - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `guests` (integer; optional; default 1; min 1, max 8): Number of guests. For dorms, this is the number of beds needed. For private rooms, this is the occupancy. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of hostelworld_property) - `search_parameters.property_id` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.guests` (integer; required) - `property` (object; required) - `property.property_id` (string; required) - `property.price_per_night` (number | null; required) - `property.currency` (string; required): The property's native currency. - `property.sold_out` (boolean; required) - `property.deposit_percentage` (number | null; required) - `property.free_cancellation_available` (boolean; required) - `property.vat` (number; required) - `property.provenance` (object | null; required): Provenance of the cheapest priced row; null when nothing priced. - `property.rooms` (array of object; required) - `meta` (object; required) - `meta.source` (string; required; one of hostelworld) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.nights` (integer; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) - `meta.dorms_count` (integer; required) - `meta.privates_count` (integer; required) - `meta.total_rate_plans` (integer; required) - `meta.comparable_across_markets` (boolean; required): Always false. - `meta.notes` (string; required) ## Airbnb Vacation-rental search in the standard SERP API shape, and a day-by-day calendar with quoted prices. ### Airbnb search: `POST /v1/serp/airbnb` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/airbnb-search Search Airbnb with the standard SERP API request names and response hierarchy. Each call runs one live Airbnb search. Use `next_page_token` from the response for the next page. The same engine is also available at the standard SERP API GET-style `/api/v1/search?engine=airbnb`. Request body (JSON): - `q` (string | null; optional): Destination text. Required unless `bounding_box` is supplied; ignored for map bounds only when the two conflict. - `bounding_box` (string | null; optional): Map bounds as `[[ne_lat,ne_lng],[sw_lat,sw_lng]]`. Takes precedence over `q`. - `airbnb_domain` (string; optional; default airbnb.com; one of airbnb.ae, airbnb.am, airbnb.at, airbnb.az, airbnb.ba, airbnb.be, airbnb.ca, airbnb.cat, airbnb.ch, airbnb.cl, airbnb.cn, airbnb.co.cr, airbnb.co.id, airbnb.co.in, airbnb.co.kr, airbnb.co.nz, airbnb.co.uk, airbnb.co.ve, airbnb.com, airbnb.com.ar, airbnb.com.au, airbnb.com.bo, airbnb.com.br, airbnb.com.bz, airbnb.com.co, airbnb.com.ec, airbnb.com.ee, airbnb.com.gt, airbnb.com.hk, airbnb.com.hn, airbnb.com.my, airbnb.com.ni, airbnb.com.pa, airbnb.com.pe, airbnb.com.ph, airbnb.com.py, airbnb.com.ro, airbnb.com.sg, airbnb.com.sv, airbnb.com.tr, airbnb.com.tw, airbnb.com.ua, airbnb.com.vn, airbnb.cz, airbnb.de, airbnb.dk, airbnb.es, airbnb.fi, airbnb.fr, airbnb.gr, airbnb.gy, airbnb.hu, airbnb.ie, airbnb.is, airbnb.it, airbnb.jp, airbnb.lt, airbnb.lu, airbnb.lv, airbnb.me, airbnb.mx, airbnb.nl, airbnb.no, airbnb.pl, airbnb.pt, airbnb.rs, airbnb.ru, airbnb.se, airbnb.si, ar.airbnb.com, bg.airbnb.com, de.airbnb.lu, es.airbnb.com, fr.airbnb.be, fr.airbnb.ca, fr.airbnb.ch, ga.airbnb.ie, he.airbnb.com, hi.airbnb.co.in, hr.airbnb.com, it.airbnb.ch, ka.airbnb.com, kn.airbnb.co.in, mk.airbnb.com, mr.airbnb.co.in, mt.airbnb.com.mt, sk.airbnb.com, sq.airbnb.com, sw.airbnb.com, th.airbnb.com, xh.airbnb.co.za, zh-t.airbnb.com, zh.airbnb.com, zu.airbnb.co.za): Country/language Airbnb host, such as `airbnb.com`, `airbnb.ca` or `fr.airbnb.ca`. - `currency` (string | null; optional; one of AED, AUD, BAM, BGN, BRL, CAD, CHF, CLP, CNY, COP, CRC, CZK, DKK, EGP, EUR, GBP, GHS, GTQ, HKD, HNL, HUF, IDR, ILS, INR, JPY, KES, KRW, KZT, MAD, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, RUB, SAR, SEK, SGD, THB, TRY, TWD, UAH, UGX, USD, UYU, VND, ZAR): Airbnb-supported ISO 4217 display currency. Omit to use the selected domain's default. - `include_taxes` (boolean; optional; default false): Expose tax-inclusive totals when Airbnb includes a tax line in the search price breakdown. - `check_in_date` (string (date) | null; optional): Exact check-in date, `YYYY-MM-DD`. Cannot be mixed with `time_period`. - `check_out_date` (string (date) | null; optional): Exact departure date. Requires `check_in_date`; defaults to the next day when omitted. - `time_period` (string | null; optional; one of one_month, one_week, weekend_trip): Flexible date search: `weekend_trip`, `one_week` or `one_month`. Defaults to `one_week` when no exact dates are supplied. - `adults` (integer | null; optional; min 0, max 16): Adults aged 13+, from 0 through 16. Defaults to one when another guest count is set. - `children` (integer | null; optional; min 0, max 15): Children aged 2–12. Maximum 15. - `infants` (integer | null; optional; min 0, max 5): Infants under 2. Maximum 5. - `pets` (integer | null; optional; min 0, max 5): Pets. Maximum 5. - `price_min` (integer | null; optional; min 0): Minimum displayed trip price. - `price_max` (integer | null; optional; min 0): Maximum displayed trip price. - `type_of_place` (string; optional; default any; one of any, entire_home, room): `any`, `room`, or `entire_home`. - `property_types` (string | null; optional): Comma-separated `house`, `guesthouse`, `apartment` and/or `hotel`. - `bedrooms` (integer | null; optional; min 0, max 8): Minimum bedrooms, 0–8. - `beds` (integer | null; optional; min 0, max 8): Minimum beds, 0–8. - `bathrooms` (integer | null; optional; min 0, max 8): Minimum bathrooms, 0–8. - `amenities` (string | null; optional): Comma-separated SERP API amenity names, such as `guest_favorite,wifi,kitchen,instant_book`. - `next_page_token` (string | null; optional): Opaque cursor returned in `pagination.next_page_token`. - `zero_retention` (boolean; optional; default false): Accepted for SERP API request compatibility. This endpoint never stores raw HTML or search results, regardless of the value. Response fields: - `search_metadata` (object; required) - `search_metadata.id` (string; required) - `search_metadata.status` (string; required) - `search_metadata.created_at` (string; required) - `search_metadata.collection_id` (string; required) - `search_metadata.observed_at` (string; required) - `search_metadata.request_time_taken` (number; required) - `search_metadata.parsing_time_taken` (number; required) - `search_metadata.total_time_taken` (number; required) - `search_metadata.request_url` (string; required) - `search_metadata.wire_bytes` (integer; required) - `search_parameters` (object; required): Echo of the effective request. Every value is a string; parameters that were not set are omitted. - `search_parameters.engine` (string; required; one of airbnb) - `search_parameters.airbnb_domain` (string; required) - `search_information` (object; required) - `search_information.query_displayed` (string; required) - `search_information.results` (string; required) - `search_information.check_in_date` (string; optional) - `search_information.check_out_date` (string; optional) - `search_information.time_period` (string; optional) - `search_information.adults` (integer; optional) - `search_information.children` (integer; optional) - `search_information.infants` (integer; optional) - `search_information.pets` (integer; optional) - `search_information.guests` (string; required): e.g. `2 guests` or `Add guests`. - `properties` (array of object; required) - `properties[].position` (integer; required) - `properties[].id` (string; required) - `properties[].title` (string; optional) - `properties[].description` (string; optional) - `properties[].link` (string; required) - `properties[].booking_link` (string; required) - `properties[].booking_token` (string; required) - `properties[].rating` (number; optional) - `properties[].reviews` (integer; optional) - `properties[].price` (object; optional) - `properties[].check_in_date` (string; optional) - `properties[].check_out_date` (string; optional) - `properties[].time_period` (string; optional) - `properties[].accommodations` (array of string; optional) - `properties[].gps_coordinates` (object; optional) - `properties[].has_free_cancellation` (boolean; optional): Only present (as true) when advertised. - `properties[].badges` (array of string; optional) - `properties[].images` (array of string; optional) - `properties[].distance` (string; optional) - `properties[].extracted_distance` (number; optional) - `pagination` (object; optional): Present only when another page exists. - `pagination.next_page_token` (string; required) ### Airbnb priced calendar: `POST /v1/airbnb/calendar` Cost: from 8 credits (8, plus 1 per night actually priced (at most 92, so at most 100 a call); refused, failed and unsampled nights and failed requests are free). Docs: https://scrapercompany.com/docs/reference/airbnb-calendar Day-by-day availability for 1-12 months with Airbnb's own quoted prices. One upstream call returns availability, min/max nights and check-in / check-out rules. With `price_nights` = `sample` or `all`, each priced date is the check-in of a real quoted stay (`stay_nights`, default the date's minimum stay) from the query the listing page's booking sidebar runs: the nightly figure, taxes, discounts and total the guest would see. Request body (JSON): - `currency` (string | null; optional; one of AED, AUD, BAM, BGN, BRL, CAD, CHF, CLP, CNY, COP, CRC, CZK, DKK, EGP, EUR, GBP, GHS, GTQ, HKD, HNL, HUF, IDR, ILS, INR, JPY, KES, KRW, KZT, MAD, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, RUB, SAR, SEK, SGD, THB, TRY, TWD, UAH, UGX, USD, UYU, VND, ZAR): Airbnb-supported ISO 4217 currency for quoted prices. Omit for the domain's default; the currency Airbnb actually priced in is returned on every priced day. - `adults` (integer; optional; default 1; min 1, max 16): Adults aged 13+; quotes are priced for this party. - `children` (integer; optional; default 0; min 0, max 15): Children aged 2-12. - `infants` (integer; optional; default 0; min 0, max 5): Infants under 2. - `pets` (integer; optional; default 0; min 0, max 5): Pets. - `max_price_quotes` (integer | null; optional; min 1, max 92): Upper bound on price quotes, 1-92. The request holds 8 + this many credits and is charged 8 + the nights actually priced. - `stay_nights` (integer | null; optional; min 1, max 28): Length of the stay each priced date is quoted for. Omit to use each date's own minimum stay. Airbnb folds cleaning and service fees into its nightly rate, so the same night costs less per night on a longer stay. 1-28. - `listing_id` (string; required; pattern ^\d{1,25}$): Numeric Airbnb listing id: the number in `https://www.airbnb.com/rooms/`, or `properties[].id` from `/v1/serp/airbnb`. - `airbnb_domain` (string; optional; default airbnb.com; one of airbnb.ae, airbnb.am, airbnb.at, airbnb.az, airbnb.ba, airbnb.be, airbnb.ca, airbnb.cat, airbnb.ch, airbnb.cl, airbnb.cn, airbnb.co.cr, airbnb.co.id, airbnb.co.in, airbnb.co.kr, airbnb.co.nz, airbnb.co.uk, airbnb.co.ve, airbnb.com, airbnb.com.ar, airbnb.com.au, airbnb.com.bo, airbnb.com.br, airbnb.com.bz, airbnb.com.co, airbnb.com.ec, airbnb.com.ee, airbnb.com.gt, airbnb.com.hk, airbnb.com.hn, airbnb.com.my, airbnb.com.ni, airbnb.com.pa, airbnb.com.pe, airbnb.com.ph, airbnb.com.py, airbnb.com.ro, airbnb.com.sg, airbnb.com.sv, airbnb.com.tr, airbnb.com.tw, airbnb.com.ua, airbnb.com.vn, airbnb.cz, airbnb.de, airbnb.dk, airbnb.es, airbnb.fi, airbnb.fr, airbnb.gr, airbnb.gy, airbnb.hu, airbnb.ie, airbnb.is, airbnb.it, airbnb.jp, airbnb.lt, airbnb.lu, airbnb.lv, airbnb.me, airbnb.mx, airbnb.nl, airbnb.no, airbnb.pl, airbnb.pt, airbnb.rs, airbnb.ru, airbnb.se, airbnb.si, ar.airbnb.com, bg.airbnb.com, de.airbnb.lu, es.airbnb.com, fr.airbnb.be, fr.airbnb.ca, fr.airbnb.ch, ga.airbnb.ie, he.airbnb.com, hi.airbnb.co.in, hr.airbnb.com, it.airbnb.ch, ka.airbnb.com, kn.airbnb.co.in, mk.airbnb.com, mr.airbnb.co.in, mt.airbnb.com.mt, sk.airbnb.com, sq.airbnb.com, sw.airbnb.com, th.airbnb.com, xh.airbnb.co.za, zh-t.airbnb.com, zh.airbnb.com, zu.airbnb.co.za): Country/language Airbnb host. The host does not change prices; it picks the market and the default currency. - `months` (integer; optional; default 3; min 1, max 12): Calendar months to return, starting at `start_month` (default 3). - `start_month` (integer | null; optional; min 1, max 12): First month, 1-12. Defaults to the current month. - `start_year` (integer | null; optional; min 2020, max 2100): Year of `start_month`. Defaults to the current year. - `price_nights` (string; optional; default sample; one of none, sample, all): `none`: availability only (one upstream request). `sample`: quote `max_price_quotes` check-in dates spread evenly over the valid ones (default 12). `all`: quote every valid check-in date in order, up to `max_price_quotes` (default and maximum 92). Each quote is one ~0.9 KB upstream request and one credit. - `include_listing` (boolean; optional; default false): Add title, property type, rating, capacity and coordinates from one extra ~10 KB upstream request. No extra credits. Response fields: - `listing_id` (string; required): Airbnb listing id. - `link` (string; required): Listing URL on `airbnb_domain`. - `airbnb_domain` (string; required) - `currency` (string; optional): Currency of the quoted prices: the one Airbnb priced in, else the requested `currency`. Omitted when neither is known (no `currency` sent and no day priced). - `requested_currency` (string; optional): Present only when `currency` was sent. - `guests` (object; required): Party the quotes were priced for. - `guests.adults` (integer; required) - `guests.children` (integer; required) - `guests.infants` (integer; required) - `guests.pets` (integer; required) - `start_month` (integer; required): Effective first month (defaults to the current UTC month). - `start_year` (integer; required): Effective year of `start_month`. - `months` (integer; required) - `price_nights` (string; required; one of none, sample, all) - `stay_nights` (integer; optional): Present only when `stay_nights` was sent. - `max_price_quotes` (integer; required): Quote budget that applied: the requested `max_price_quotes` or the mode default (12 for `sample`, 92 for `all`), capped at 92 and at 31 x `months`; 0 with `price_nights: none`. - `listing` (object; optional): Present only when at least one listing fact is known. - `listing.constant_min_nights` (integer; optional): Minimum stay that applies to every date, when Airbnb reports one. - `listing.max_guests` (integer; optional): Guest capacity. - `listing.pets_allowed` (boolean; optional) - `listing.children_allowed` (boolean; optional) - `listing.infants_allowed` (boolean; optional) - `listing.guest_policy` (string; optional): Airbnb's guest-policy sentence, e.g. `This place has a maximum of 2 guests, not including infants.` - `listing.title` (string; optional): Listing title. Only with `include_listing`. - `listing.property_type` (string; optional): Airbnb property type, e.g. `PRIVATE_SUITE`. Only with `include_listing`. - `listing.room_type` (string; optional): Airbnb space type, e.g. `ENTIRE_HOME`. Only with `include_listing`. - `listing.location` (string; optional): Displayed location, e.g. `Toronto`. Only with `include_listing`. - `listing.overview` (array of string; optional): Summary items, e.g. `Entire guest suite`, `1 bed`, `1 bath`. Only with `include_listing`. - `listing.rating` (number; optional): Average rating. Only with `include_listing`. - `listing.reviews` (integer; optional): Review count. Only with `include_listing`. - `listing.is_guest_favorite` (boolean; optional): Only with `include_listing`. - `listing.is_luxe` (boolean; optional): Only with `include_listing`. - `listing.gps_coordinates` (object; optional): Only with `include_listing`. - `summary` (object; required): Counts over the returned days, and the spread of quoted nightly prices. - `summary.days` (integer; required): Days returned. - `summary.available` (integer; required): Days whose night is open. - `summary.available_for_checkin` (integer; required): Days Airbnb allows arriving on. - `summary.bookable` (integer; required): Days Airbnb marks bookable. - `summary.priced` (integer; required): Days with a quoted price (each is charged 1 credit). - `summary.min_price_per_night` (number; optional): Lowest `price_per_night` among priced days. Present only when at least one day was priced. - `summary.max_price_per_night` (number; optional): Highest `price_per_night` among priced days. Present only when at least one day was priced. - `summary.median_price_per_night` (number; optional): Median `price_per_night` among priced days, 2 decimals. Present only when at least one day was priced. - `summary.price_status` (object; required): Number of days per `price_status` value, keys sorted; only statuses that occur are present. - `days` (array of object; required): One row per date of the requested months, in date order. - `days[].date` (string (date); required): Calendar date; the night starts on this date. - `days[].available` (boolean; required): The night is open (not booked or blocked). - `days[].available_for_checkin` (boolean; required): Airbnb allows arriving on this date. - `days[].available_for_checkout` (boolean; required): Airbnb allows departing on this date. - `days[].bookable` (boolean; required): Airbnb's bookable flag for this date. - `days[].min_nights` (integer; optional): Minimum stay for a check-in on this date. Present only when Airbnb reports it. - `days[].max_nights` (integer; optional): Maximum stay for a check-in on this date. Present only when Airbnb reports it. - `days[].closed_to_arrival` (boolean; optional): Arrival restriction for this date. Present only when Airbnb returns arrival/departure rules for it. - `days[].closed_to_departure` (boolean; optional): Departure restriction for this date. Present only when Airbnb returns arrival/departure rules for it. - `days[].price_status` (object; optional; one of priced, not_sampled, quote_cap_reached, not_requested, unavailable, past, check_in_not_allowed, check_out_not_allowed, stay_blocked, stay_exceeds_max_nights, quote_refused, no_price, quote_failed, quote_skipped): Present unless `price_nights` is `none`. - `days[].price_error` (string; optional): Reason behind `quote_refused` (Airbnb's message), `no_price`, `quote_failed` or `quote_skipped` (`deadline_exceeded` or `stopped_after_failures`). Present only when there is one. - `days[].price` (object; optional): Present only when `price_status` is `priced`. - `metadata` (object; required) - `metadata.collection_id` (string; required): Shared by every price in this response (`ratecol_...`). - `metadata.observed_at` (string; required): UTC observation time, ISO-8601. - `metadata.calendar_operation` (string; required): Upstream operation used. - `metadata.upstream_requests` (integer; required): Upstream requests made, including retried attempts. - `metadata.price_quotes` (integer; required): Stays planned for quoting (skipped quotes included). - `metadata.wire_bytes` (integer; required): Bytes received from upstream, compressed. - `metadata.request_time_taken` (number; required): Seconds spent in upstream requests, summed. Quotes run in parallel, so this can exceed `total_time_taken`. - `metadata.parsing_time_taken` (number; required): Seconds spent parsing the calendar. - `metadata.total_time_taken` (number; required): End-to-end seconds for this request. - `metadata.egress` (array of string; required): How upstream requests were routed: `direct`, `proxy`, or both. - `warnings` (array of string; optional): Things worth checking: refused, failed or skipped quotes, a currency other than the one asked for, stays quoted longer than `stay_nights`, missing listing details. Present only when there is at least one. ### Airbnb availability calendar (SERP-compatible): `POST /v1/serp/airbnb_property_availability_calendar` Cost: from 8 credits (8 with the default `price_nights: none`; with `sample` or `all`, plus 1 per night actually priced (at most 92). Failed requests are free). Docs: https://scrapercompany.com/docs/reference/serp-airbnb-calendar The standard SERP API `airbnb_property_availability_calendar`, field for field. `property_id`, `start_month`, `start_year`, `months` and `airbnb_domain` keep the standard SERP API names and defaults, and every day keeps `date`, `is_available`, `is_available_for_checkin`, `is_available_for_checkout`, `is_bookable`, `min_nights` and `max_nights`. The standard shape has no prices; set `price_nights` to add a `price` object to priced days (The standard SERP API Airbnb search price vocabulary). The default `none` costs 8 credits. Request body (JSON): - `currency` (string | null; optional; one of AED, AUD, BAM, BGN, BRL, CAD, CHF, CLP, CNY, COP, CRC, CZK, DKK, EGP, EUR, GBP, GHS, GTQ, HKD, HNL, HUF, IDR, ILS, INR, JPY, KES, KRW, KZT, MAD, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, RUB, SAR, SEK, SGD, THB, TRY, TWD, UAH, UGX, USD, UYU, VND, ZAR): Airbnb-supported ISO 4217 currency for quoted prices. Omit for the domain's default; the currency Airbnb actually priced in is returned on every priced day. - `adults` (integer; optional; default 1; min 1, max 16): Adults aged 13+; quotes are priced for this party. - `children` (integer; optional; default 0; min 0, max 15): Children aged 2-12. - `infants` (integer; optional; default 0; min 0, max 5): Infants under 2. - `pets` (integer; optional; default 0; min 0, max 5): Pets. - `max_price_quotes` (integer | null; optional; min 1, max 92): Upper bound on price quotes, 1-92. The request holds 8 + this many credits and is charged 8 + the nights actually priced. - `stay_nights` (integer | null; optional; min 1, max 28): Length of the stay each priced date is quoted for. Omit to use each date's own minimum stay. Airbnb folds cleaning and service fees into its nightly rate, so the same night costs less per night on a longer stay. 1-28. - `engine` (string; optional; default airbnb_property_availability_calendar): Accepted for SERP API request compatibility; the path already selects the engine. - `property_id` (string; required; pattern ^\d{1,25}$): Numeric Airbnb listing id: the number in `https://www.airbnb.com/rooms/`, or `properties[].id` from `/v1/serp/airbnb`. - `start_month` (integer | null; optional; min 1, max 12): SERP API `start_month`: first month, 1-12. Defaults to the current month. - `start_year` (integer | null; optional; min 2020, max 2100): SERP API `start_year`. Defaults to the current year. - `months` (integer; optional; default 12; min 1, max 12): SERP API `months`: 1-12, default 12. - `airbnb_domain` (string; optional; default airbnb.com; one of airbnb.ae, airbnb.am, airbnb.at, airbnb.az, airbnb.ba, airbnb.be, airbnb.ca, airbnb.cat, airbnb.ch, airbnb.cl, airbnb.cn, airbnb.co.cr, airbnb.co.id, airbnb.co.in, airbnb.co.kr, airbnb.co.nz, airbnb.co.uk, airbnb.co.ve, airbnb.com, airbnb.com.ar, airbnb.com.au, airbnb.com.bo, airbnb.com.br, airbnb.com.bz, airbnb.com.co, airbnb.com.ec, airbnb.com.ee, airbnb.com.gt, airbnb.com.hk, airbnb.com.hn, airbnb.com.my, airbnb.com.ni, airbnb.com.pa, airbnb.com.pe, airbnb.com.ph, airbnb.com.py, airbnb.com.ro, airbnb.com.sg, airbnb.com.sv, airbnb.com.tr, airbnb.com.tw, airbnb.com.ua, airbnb.com.vn, airbnb.cz, airbnb.de, airbnb.dk, airbnb.es, airbnb.fi, airbnb.fr, airbnb.gr, airbnb.gy, airbnb.hu, airbnb.ie, airbnb.is, airbnb.it, airbnb.jp, airbnb.lt, airbnb.lu, airbnb.lv, airbnb.me, airbnb.mx, airbnb.nl, airbnb.no, airbnb.pl, airbnb.pt, airbnb.rs, airbnb.ru, airbnb.se, airbnb.si, ar.airbnb.com, bg.airbnb.com, de.airbnb.lu, es.airbnb.com, fr.airbnb.be, fr.airbnb.ca, fr.airbnb.ch, ga.airbnb.ie, he.airbnb.com, hi.airbnb.co.in, hr.airbnb.com, it.airbnb.ch, ka.airbnb.com, kn.airbnb.co.in, mk.airbnb.com, mr.airbnb.co.in, mt.airbnb.com.mt, sk.airbnb.com, sq.airbnb.com, sw.airbnb.com, th.airbnb.com, xh.airbnb.co.za, zh-t.airbnb.com, zh.airbnb.com, zu.airbnb.co.za): Country/language Airbnb host. The host does not change prices; it picks the market and the default currency. - `price_nights` (string; optional; default none; one of none, sample, all): ScraperCompany addition. Default `none` returns exactly the standard SERP API fields at the base cost. `none`: availability only (one upstream request). `sample`: quote `max_price_quotes` check-in dates spread evenly over the valid ones (default 12). `all`: quote every valid check-in date in order, up to `max_price_quotes` (default and maximum 92). Each quote is one ~0.9 KB upstream request and one credit. - `zero_retention` (boolean; optional; default false): Accepted for SERP API compatibility; calendars and quotes are never persisted. Response fields: - `search_metadata` (object; required) - `search_metadata.id` (string; required) - `search_metadata.status` (string; required; one of Success) - `search_metadata.created_at` (string; required): UTC, ISO-8601. - `search_metadata.request_time_taken` (number; required): Seconds spent in upstream requests, summed; can exceed `total_time_taken` because quotes run in parallel. - `search_metadata.parsing_time_taken` (number; required) - `search_metadata.total_time_taken` (number; required) - `search_metadata.request_url` (string; required): Listing URL. - `search_metadata.collection_id` (string; required): Shared by every price in this response (`ratecol_...`). - `search_metadata.observed_at` (string; required): UTC observation time, ISO-8601. - `search_metadata.wire_bytes` (integer; required): Bytes received from upstream, compressed. - `search_metadata.upstream_requests` (integer; required): Upstream requests made: 1 for the calendar plus one per quote attempt. - `search_parameters` (object; required): Echo of the effective request. - `search_parameters.engine` (string; required; one of airbnb_property_availability_calendar) - `search_parameters.airbnb_domain` (string; required) - `search_parameters.property_id` (string; required) - `search_parameters.start_month` (integer; required): Effective first month (defaults resolved). - `search_parameters.start_year` (integer; required) - `search_parameters.months` (integer; required) - `search_parameters.currency` (string; optional): Present only when sent. - `search_parameters.adults` (integer; optional): Present only when `price_nights` isn't `none`. - `search_parameters.children` (integer; optional): Present only when non-zero and `price_nights` isn't `none`. - `search_parameters.infants` (integer; optional): Present only when non-zero and `price_nights` isn't `none`. - `search_parameters.pets` (integer; optional): Present only when non-zero and `price_nights` isn't `none`. - `search_parameters.price_nights` (string; optional; one of sample, all): Present only when not `none`. - `search_parameters.max_price_quotes` (integer; optional): As sent. Present only when sent and `price_nights` isn't `none`. - `search_parameters.stay_nights` (integer; optional): Present only when sent and `price_nights` isn't `none`. - `months` (array of object; required): One entry per requested month, in order. - `months[].year` (integer; required) - `months[].month` (integer; required): 1-12. - `months[].days` (array of object; required): In date order. - `price_summary` (object; optional): Present only when `price_nights` isn't `none`. - `price_summary.days` (integer; required): Days returned. - `price_summary.available` (integer; required): Days whose night is open. - `price_summary.available_for_checkin` (integer; required): Days Airbnb allows arriving on. - `price_summary.bookable` (integer; required): Days Airbnb marks bookable. - `price_summary.priced` (integer; required): Days with a quoted price (each is charged 1 credit). - `price_summary.min_price_per_night` (number; optional): Lowest `price_per_night` among priced days. Present only when at least one day was priced. - `price_summary.max_price_per_night` (number; optional): Highest `price_per_night` among priced days. Present only when at least one day was priced. - `price_summary.median_price_per_night` (number; optional): Median `price_per_night` among priced days, 2 decimals. Present only when at least one day was priced. - `price_summary.price_status` (object; required): Number of days per `price_status` value, keys sorted; only statuses that occur are present. - `warnings` (array of string; optional): Things worth checking: refused, failed or skipped quotes, a currency other than the one asked for, stays quoted longer than `stay_nights`. Present only when there is at least one. ## Vrbo Vacation-rental search and stay quotes from Vrbo. ### Vrbo search: `POST /v1/ota/vrbo/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/vrbo-search Search Vrbo by destination and dates. Returns Vrbo's recommended listings with the numeric `property_id` that `POST /v1/ota/vrbo` quotes, the listing id and URL, and Vrbo's own nightly and stay prices. One request returns up to 50 listings. Request body (JSON): - `destination` (string; required; min length 2): Place as a guest would type it, e.g. `South Lake Tahoe, California`. Vrbo resolves it to a region. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 28): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 16): Guests (adults). - `limit` (integer; optional; default 20; min 1, max 50): Maximum listings to return, in Vrbo's recommended order. - `market` (string; optional; default US; one of US): Vrbo point-of-sale. Only `US` (www.vrbo.com, USD) is verified. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of vrbo_search) - `search_parameters.destination` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.market` (string; required): `US`. - `search_parameters.currency` (string; required): The market's currency (`USD`). - `search_parameters.limit` (integer; required) - `summary` (object; required) - `summary.matched_properties` (integer | null; required): Total listings Vrbo matched for the destination and dates. - `summary.results_heading` (string | null; required): Vrbo's heading, e.g. `Search results showing 359 properties in ...`. - `listings` (array of object; required): At most `limit` listings, in Vrbo's recommended order; sponsored placements are skipped. - `listings[].property_id` (string; required): Numeric Vrbo property id; pass as `property_id` to `POST /v1/ota/vrbo`. - `listings[].listing_id` (string; required): Id in the listing's Vrbo URL, e.g. `20218736ha`; empty when the card carried no listing link. - `listings[].name` (string; required) - `listings[].summary` (string; required): Card details joined with ` · `, e.g. `House · 4 bedrooms · 4 Queen Beds`. - `listings[].url` (string; required): `https://www.vrbo.com/`; empty when `listing_id` is empty. - `listings[].nightly` (number | null; required): Vrbo's nightly price, to the cent. Null when the card's price carried no recognised label. - `listings[].total` (number | null; required): Stay total for all nights; null when the card did not state one. - `listings[].currency` (string; required) - `listings[].nightly_text` (string; required): As displayed, e.g. `$462`. - `listings[].total_text` (string; required): As displayed, e.g. `$1,386 for 3 nights`. - `listings[].fees_included` (boolean | null; required): True when Vrbo labels the price "All fees included"; null when no such label was shown. - `listings[].taxes_and_fees_included` (boolean | null; required): True when labelled as including taxes and fees; null when no such label was shown. - `listings[].rank` (integer; required): 0-based position in Vrbo's recommended order. - `listings[].provenance` (object; required): Where, when and how one normalized price was observed. - `meta` (object; required) - `meta.source` (string; required; one of vrbo) - `meta.listings` (integer; required) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.wire_bytes` (integer; required): Bytes received from the source. - `meta.elapsed_s` (number; required) - `meta.egress_mode` (string; required; one of direct, proxy): How the request was routed: `direct` or `proxy`. ### Vrbo quote: `POST /v1/ota/vrbo` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/vrbo-quote A Vrbo stay quote: nightly and total price, fees and payment model. The total is Vrbo's own figure and `fees_included` repeats its "All fees included" label; cleaning and service fees and taxes are not itemised by Vrbo for this request, so they are not invented here. A stay Vrbo will not sell as asked (minimum stay, dates taken) returns `available: false` with Vrbo's reason, billed like any other answer. Request body (JSON): - `property_id` (string | null; optional; pattern ^\d+$): Numeric id returned by `POST /v1/ota/vrbo/search` (`property_id` on each listing). Not the id in the Vrbo URL. - `listing_id` (string | null; optional; pattern ^\d+(?:ha)?$): The listing id in a Vrbo URL, e.g. `20218736ha` for `vrbo.com/20218736ha`. Resolved to `property_id` with one page load. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 28): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 16): Guests (adults). - `market` (string; optional; default US; one of US): Vrbo point-of-sale. Only `US` (www.vrbo.com, USD) is verified. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of vrbo_property) - `search_parameters.property_id` (string; required): The property id quoted (resolved from `listing_id` when only that was sent). - `search_parameters.listing_id` (string; optional): Present only when `listing_id` was supplied. - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.market` (string; required): `US`. - `search_parameters.currency` (string; required): The market's currency (`USD`). - `property` (object; required) - `property.property_id` (string; required): Numeric Vrbo property id; store it to skip listing resolution next time. - `property.listing_id` (string | null; required): The `listing_id` you sent, echoed; null when you sent only `property_id`. When both are sent, `property_id` is used and the two are not cross-checked. - `property.total` (number | null; required): Headline stay total for all nights (Vrbo's own figure); see `basis`. Null when nothing priced. - `property.price_per_night` (number | null; required): Headline nightly price. - `property.basis` (string | null; required; one of sticky_bar, cheapest_offer): Where the headline comes from: `sticky_bar` (the page's own headline price, read by its labels) or `cheapest_offer` (the cheapest priced offer). Null when nothing priced. - `property.total_text` (string; required): Headline total as displayed; empty when not shown. - `property.nightly_text` (string; required): Headline nightly price as displayed; empty when not shown. - `property.taxes_and_fees_included` (boolean | null; required): True when the headline total is labelled "with taxes and fees"; null when no such label was shown. - `property.fees_included` (boolean | null; required): True when the headline total is labelled "All fees included"; null when no such label was shown. - `property.currency` (string; required): Currency the point-of-sale actually priced in. - `property.currency_verified` (boolean; required): Whether `currency` equals the market's currency. - `property.available` (boolean; required): False when Vrbo will not sell the stay as asked. - `property.unavailable_reason` (string | null; required): Vrbo's own message when the stay cannot be booked (minimum stay, dates taken). Null otherwise; `available` can be false with a null reason when nothing priced. - `property.payment_model` (string | null; required; one of PAY_NOW, PAY_LATER, PAY_LATER_WITH_DEPOSIT, ): `payment_model` of the cheapest offer; null when nothing priced. - `property.provenance` (object; required): Where, when and how one normalized price was observed. - `offers` (array of object; required): Every rate plan for the rental. - `offers[].plan_id` (string; required): Vrbo rate-plan id. - `offers[].room_type_id` (string; required) - `offers[].total` (number | null; required): Stay total for all nights, Vrbo's own figure; `fees_included` repeats its "All fees included" label. Cleaning and service fees and taxes are not itemised. - `offers[].nightly` (number | null; required): Vrbo's nightly price. - `offers[].taxes_and_fees` (number | null; required): Derived, not read from the source: `total - nightly × nights`, set only when `taxes_and_fees_included` is true. Accurate to within `nights` currency units because `nightly` is rounded; taxes and fees are not itemised. See `taxes_and_fees_provenance`. - `offers[].currency` (string; required): ISO 4217 code read back from the reply. - `offers[].total_text` (string; required): Total as displayed, e.g. `$635 total`. - `offers[].nightly_text` (string; required): Nightly price as displayed, e.g. `$509 nightly`. - `offers[].taxes_and_fees_included` (boolean | null; required): True when the source labels the total "Total with taxes and fees". Null means no such label was shown, not that taxes are excluded. - `offers[].fees_included` (boolean | null; required): True when the source labels the total "All fees included". Null means no such label was shown. - `offers[].payment_model` (string; required; one of PAY_NOW, PAY_LATER, PAY_LATER_WITH_DEPOSIT, ): `PAY_NOW`, `PAY_LATER` or `PAY_LATER_WITH_DEPOSIT`; empty when not stated. A plan sold both ways is two offers. - `offers[].hotel_collect` (boolean | null; required): True when the property collects payment; null when not stated. - `offers[].member_only` (boolean; required): True when booking the plan requires signing in as a member. - `offers[].refundable` (boolean | null; required): Always null on Vrbo: refundability is not read, rather than guessed. - `offers[].cancellation_text` (string; required): Always empty on Vrbo. - `offers[].extras` (string | null; required): Always null on Vrbo. - `offers[].extras_text` (string; required): Always empty on Vrbo. - `offers[].strikeout_text` (string; required): Struck-through comparison price as displayed; empty when none. - `offers[].inventory_type` (string; required): Source inventory type, e.g. `MERCHANT`, `TRIPCOM`, `DIRECT_AGENCY`, `VRBO`; empty when not stated. - `offers[].business_model` (string; required): `EXPEDIA_COLLECT` or `HOTEL_COLLECT`; empty when not stated. - `offers[].messages` (array of string; required): Vrbo's highlighted messages for the plan, e.g. `Reserve now, pay deposit`, `Your dates are available`. - `offers[].provenance` (object; required): Where, when and how one normalized price was observed. - `offers[].taxes_and_fees_provenance` (object | null; required): Provenance of `taxes_and_fees` (`price_basis: taxes_and_fees_combined`, `derivation: total_minus_nightly_times_nights`); null when `taxes_and_fees` is null. - `meta` (object; required) - `meta.source` (string; required; one of vrbo) - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.nights` (integer; required) - `meta.wire_bytes` (integer; required): Bytes received from the source, including the listing page when `listing_id` was resolved. - `meta.elapsed_s` (number; required) - `meta.egress_mode` (string; required; one of direct, proxy): How the request was routed: `direct` or `proxy`. - `meta.listing_resolved` (boolean; required): True when `listing_id` was resolved to `property_id` in this call. ## Google Flights Itineraries, return and multi-city legs, booking options, airport lookup and date-grid fares, in the standard SERP API shape. ### Google Flights search: `POST /v1/serp/google_flights` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-flights Every itinerary Google Flights offers, with per-segment detail. One shopping RPC (~0.3 s, ~185 KB for a typical one-way): Google's best and other flights, flight numbers, operating carrier, aircraft, legroom, amenities, layovers, emissions, bags included, price insights and a Google Flights link per itinerary. Round trips and multi-city return the first leg's options with a `departure_token` for `/v1/serp/google_flights_return`; complete itineraries carry a `booking_token` for `/v1/serp/google_flights_booking`. Request body (JSON): - `departure` (string; required; min length 3, max length 3): IATA airport code (`JFK`) or IATA city code (`NYC`, `LON`, `PAR`, `TYO`...: every airport of that city). For several airports or a Google city id use `departure_id`. - `arrival` (string; required; min length 3, max length 3): IATA airport code (`JFK`) or IATA city code (`NYC`, `LON`, `PAR`, `TYO`...: every airport of that city). For several airports or a Google city id use `arrival_id`. - `departure_date` (string (date); required): Outbound flight date, `YYYY-MM-DD`. - `return_date` (string (date) | null; optional): Return flight date for round-trip. Omit for one-way. - `departure_id` (string | null; optional; min length 3, max length 200): SerpApi's `departure_id`: overrides `departure` with comma-separated IATA airport/city codes and/or Google city ids (`/m/02_286`), up to 7. `departure` is then only the label echoed back. - `arrival_id` (string | null; optional; min length 3, max length 200): SerpApi's `arrival_id`: overrides `arrival` the same way, e.g. a city id from `/v1/serp/google_flights_location_search`. - `multi_city` (array of object | null; optional; min items 1, max items 4): Makes the trip multi-city: the legs after the first (`departure` -> `arrival` on `departure_date`), 1-4 of them, in date order. The response lists options for the first leg; follow `departure_token` for each next leg. Not combinable with `return_date`. - `multi_city[].departure` (string; required; min length 3, max length 80): IATA airport code (`JFK`), IATA city code (`NYC`, `LON`, `PAR`: every airport of the city), a Google city id from `/v1/serp/google_flights_location_search` (`/m/02_286`), or up to 7 of these comma-separated (`JFK,EWR`). - `multi_city[].arrival` (string; required; min length 3, max length 80): IATA airport code (`JFK`), IATA city code (`NYC`, `LON`, `PAR`: every airport of the city), a Google city id from `/v1/serp/google_flights_location_search` (`/m/02_286`), or up to 7 of these comma-separated (`JFK,EWR`). - `multi_city[].date` (string (date); required): Departure date of this leg, `YYYY-MM-DD`. - `multi_city[].times` (string | null; optional; pattern ^\d{1,2},\d{1,2}(,\d{1,2},\d{1,2})?$): Hour window `from,to` for departure, optionally followed by `from,to` for arrival (0-23; `8,12` = leaves 08:00-12:59). SerpApi's format. - `adults` (integer; optional; default 1; min 1, max 9): Number of adult passengers (12+ years old). - `children` (integer; optional; default 0; min 0, max 8): Number of children (2-11 years old). - `infants_in_seat` (integer; optional; default 0; min 0, max 4): Number of infants with seat (under 2 years old). - `infants_on_lap` (integer; optional; default 0; min 0, max 4): Number of lap infants (under 2 years old); at most one per adult. - `cabin_class` (string; optional; default economy; one of business, economy, first, premium_economy; pattern ^(economy|premium_economy|business|first)$): Cabin class: economy, premium_economy, business, first. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `hl` (string; optional; default en): Language code for results. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Market/country code (two letters). - `stops` (integer | null; optional; min 0, max 2): Maximum stops filter: 0=nonstop only, 1=max 1 stop, 2=max 2 stops. Omit for any number of stops. - `include_airlines` (string | null; optional; pattern ^[A-Za-z0-9_]{2,13}(,[A-Za-z0-9_]{2,13}){0,19}$): Comma-separated IATA airline codes and/or alliances (`STAR_ALLIANCE`, `SKYTEAM`, `ONEWORLD`) to keep, e.g. `AC,UA`. Cannot be combined with `exclude_airlines`. - `exclude_airlines` (string | null; optional; pattern ^[A-Za-z0-9_]{2,13}(,[A-Za-z0-9_]{2,13}){0,19}$): Comma-separated airline codes to drop. Google's rule: an itinerary also sold under a codeshare partner that is not excluded is kept. - `max_price` (integer | null; optional; min 1, max 1000000): Only itineraries at or below this price, in `currency`. - `max_duration` (integer | null; optional; min 30, max 5760): Maximum door-to-door travel time per leg, minutes. - `outbound_times` (string | null; optional; pattern ^\d{1,2},\d{1,2}(,\d{1,2},\d{1,2})?$): Hour window `from,to` for departure, optionally followed by `from,to` for arrival (0-23; `8,12` = leaves 08:00-12:59). SerpApi's format. First leg. - `return_times` (string | null; optional; pattern ^\d{1,2},\d{1,2}(,\d{1,2},\d{1,2})?$): Hour window `from,to` for departure, optionally followed by `from,to` for arrival (0-23; `8,12` = leaves 08:00-12:59). SerpApi's format. Return leg; needs `return_date`. - `carry_on_bags` (integer; optional; default 0; min 0, max 1): Carry-on bags per passenger to include in the price (Google adds the airline's bag fees). - `checked_bags` (integer; optional; default 0; min 0, max 2): Checked bags per passenger to include in the price. - `exclude_basic_economy` (boolean; optional; default false): Hide basic-economy fares (Google's "Economy (exclude Basic)"; offered on US routes). - `less_emissions` (boolean; optional; default false): Only flights with lower-than-typical emissions. - `layover_duration` (string | null; optional; pattern ^\d{1,4},\d{1,4}$): Layover length window `min,max` in minutes, e.g. `60,240`. - `connecting_airports` (string | null; optional; pattern ^[A-Za-z0-9]{3}(,[A-Za-z0-9]{3}){0,19}$): Only connect through these airports (comma-separated IATA codes). - `exclude_connecting_airports` (string | null; optional; pattern ^[A-Za-z0-9]{3}(,[A-Za-z0-9]{3}){0,19}$): Never connect through these airports. - `sort_by` (string; optional; default top_flights; one of arrival_time, departure_time, duration, emissions, price, top_flights; pattern ^(top_flights|price|departure_time|arrival_time|duration|emissions)$): Result order (SerpApi `sort_by` 1-6 in the same order): top_flights, price, departure_time, arrival_time, duration, emissions. With anything but top_flights Google returns no separate best group. Response fields: - `departure_airport` (string; required): Echo of the request's `departure`. - `arrival_airport` (string; required): Echo of the request's `arrival`. - `departure_date` (string (date); required): Date of the leg these options are for. - `return_date` (string (date); optional): Present only for round trips. - `currency` (string; required): The requested currency. - `adults` (integer; required) - `itineraries` (array of object; required): Options for the leg being chosen: Google's best flights first, then the others. - `itineraries[].legs` (array of object; required): The leg chosen in this call (one entry). Earlier legs are not repeated; `/v1/serp/google_flights_booking` returns every leg. - `itineraries[].price` (number | null; required): Google's displayed whole amount for the whole trip (every leg, all passengers), in `currency`. Google rounds up (527 where the exact fare is 526.19; see `price_exact`). When `priced_in` is set, the amount is in that currency instead. - `itineraries[].currency` (string; required): The requested currency. - `itineraries[].display_price` (string | null; required): `price` with its currency symbol, e.g. `$527`. Null when `price` is null or `priced_in` is set. - `itineraries[].booking_token` (string | null; required): Pass to `POST /v1/serp/google_flights_booking` for sellers, prices and booking links. Set only on complete itineraries (one-way options, and the options of a trip's last leg); null when `departure_token` is set. Compatibility: until 2026-09-30 this field held Google's raw price token on every itinerary; that value is now `price_token`. - `itineraries[].booking_url` (string | null; required): Google Flights booking page for the complete itinerary. Set together with `booking_token`. - `itineraries[].carbon_emissions_kg` (integer | null; required): CO2e estimate for this itinerary, kilograms (rounded). `carbon_emissions` has the same figure in grams. - `itineraries[].carbon_emissions_comparison` (string | null; required): e.g. `19% lower than typical` or `typical for this route`. - `itineraries[].trip_type` (string; required; one of one_way, round_trip, multi_city): `one_way`, `round_trip` or `multi_city`. - `itineraries[].total_stops` (integer; required): Stops across `legs`. - `itineraries[].is_direct` (boolean; required): `total_stops` is 0. - `itineraries[].departure_token` (string | null; required): Pass to `POST /v1/serp/google_flights_return` for the next leg's options after choosing this one. Set while legs remain to choose (round-trip outbound, multi-city legs before the last); null when `booking_token` is set. Self-contained: nothing else is needed with it. - `itineraries[].google_flights_url` (string | null; required): Google Flights page for this option: the search page with the earlier legs chosen, or the booking page once every leg is chosen. - `itineraries[].group` (string; required; one of best, other): `best` (Google's top flights) or `other`. Every option is `other` when `sort_by` is not `top_flights`. - `itineraries[].price_exact` (number | null; required): Price with minor units, from Google's price token (526.19 where `price` is 527). Null when the token has no amount or is in another currency. - `itineraries[].price_token` (string | null; required): Google's own opaque price token for this option, on every itinerary (returned as `booking_token` until 2026-09-30). Usable as an itinerary key; no endpoint takes it. - `itineraries[].priced_in` (string | null; required): Set only when Google priced this option in another currency than requested: that ISO 4217 code. `price` is then in this currency and `warnings` says so. - `itineraries[].carbon_emissions` (object | null; required): Null when Google gives no estimate. - `itineraries[].total_duration_minutes` (integer | null; required): Sum of the legs' door-to-door durations, minutes; null when one is unknown. - `itineraries[].carry_on_bags_included` (integer | null; required): Carry-on bags included in the fare, as Google states it; null when not stated. - `itineraries[].checked_bags_included` (integer | null; required): Checked bags included in the fare, as Google states it; null when not stated. - `itineraries[].airline_logo` (string | null; required): Logo URL of the main airline; null when several airlines share the itinerary. - `wire_bytes` (integer; required): Size of Google's response, bytes. - `elapsed_s` (number; required): Time Google took to answer, seconds. - `cheapest_price` (number | null; required): Lowest `price` in `itineraries`; null when none is priced. - `trip_type` (string; required; one of one_way, round_trip, multi_city): `one_way`, `round_trip` or `multi_city`. - `leg_index` (integer; required): Which leg these options are for: 0 = first (outbound), 1 = return or second multi-city leg, and so on. - `legs_total` (integer; required): Legs in the trip: 1 one-way, 2 round trip, 2-5 multi-city. - `itinerary_count` (integer; required): Number of entries in `itineraries`. - `best_count` (integer; required): How many `itineraries` have `group: best`. - `price_insights` (object | null; optional): Null when Google gives none (some filtered searches). Omitted when `itineraries` is empty; that answer is not billed. - `price_insights.lowest_price` (number | null; required): Lowest price Google shows for this search, in `currency`. - `price_insights.price_level` (string | null; required; one of low, typical, high): Google's verdict on today's price: `low` (below its typical range), `typical` (inside it) or `high` (above it). - `price_insights.typical_price_range` (array of number | null; required; min items 2, max items 2): `[low, high]`: Google's typical price range for this trip. - `price_insights.price_history` (array of array of number; required): `[[unix_seconds, price], ...]`: Google's price history for this trip, about 60 days. Empty when Google gives none. - `airlines_available` (array of object; required): Airlines and alliances Google offers as filters for this search; the codes work in `include_airlines`. - `airlines_available[].code` (string; required): IATA airline code, or `STAR_ALLIANCE` / `SKYTEAM` / `ONEWORLD`. - `airlines_available[].name` (string | null; required) - `airlines_available[].type` (string; required; one of alliance, airline) - `google_flights_url` (string; required): Google Flights search page for this trip. - `source` (string; required; one of rpc, html): `rpc` normally; `html` when the results came from Google's server-rendered page fallback, which holds only Google's first screen of results (about 8-10 itineraries). - `warnings` (array of string; required): Notices about this answer, e.g. that Google priced some options in another currency (see each itinerary's `priced_in`). Empty when none. ### Return and next-leg flights: `POST /v1/serp/google_flights_return` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-flights-return The return flights for a chosen outbound (or the next multi-city leg). SerpApi's `departure_token` flow: pass the `departure_token` of an itinerary from `/v1/serp/google_flights`. Prices are for the whole trip, as Google shows them. Last-leg options carry a `booking_token`. Request body (JSON): - `departure_token` (string; required; pattern ^gf1\.[A-Za-z0-9_\-]{16,16384}$): `departure_token` of an itinerary from `/v1/serp/google_flights` (or of a previous `/v1/serp/google_flights_return` leg of a multi-city trip). It carries the search, so nothing else is needed. Response fields: - `departure_airport` (string; required): Origin of the leg these options are for: airport codes or Google city ids, comma-separated. - `arrival_airport` (string; required): Destination of the leg these options are for: airport codes or Google city ids, comma-separated. - `departure_date` (string (date); required): Date of the leg these options are for (the return date of a round trip). - `return_date` (string (date); optional): Present only for round trips (the same date as `departure_date`). - `currency` (string; required): The requested currency. - `adults` (integer; required) - `itineraries` (array of object; required): Options for the leg being chosen: Google's best flights first, then the others. - `itineraries[].legs` (array of object; required): The leg chosen in this call (one entry). Earlier legs are not repeated; `/v1/serp/google_flights_booking` returns every leg. - `itineraries[].price` (number | null; required): Google's displayed whole amount for the whole trip (every leg, all passengers), in `currency`. Google rounds up (527 where the exact fare is 526.19; see `price_exact`). When `priced_in` is set, the amount is in that currency instead. - `itineraries[].currency` (string; required): The requested currency. - `itineraries[].display_price` (string | null; required): `price` with its currency symbol, e.g. `$527`. Null when `price` is null or `priced_in` is set. - `itineraries[].booking_token` (string | null; required): Pass to `POST /v1/serp/google_flights_booking` for sellers, prices and booking links. Set only on complete itineraries (one-way options, and the options of a trip's last leg); null when `departure_token` is set. Compatibility: until 2026-09-30 this field held Google's raw price token on every itinerary; that value is now `price_token`. - `itineraries[].booking_url` (string | null; required): Google Flights booking page for the complete itinerary. Set together with `booking_token`. - `itineraries[].carbon_emissions_kg` (integer | null; required): CO2e estimate for this itinerary, kilograms (rounded). `carbon_emissions` has the same figure in grams. - `itineraries[].carbon_emissions_comparison` (string | null; required): e.g. `19% lower than typical` or `typical for this route`. - `itineraries[].trip_type` (string; required; one of one_way, round_trip, multi_city): `one_way`, `round_trip` or `multi_city`. - `itineraries[].total_stops` (integer; required): Stops across `legs`. - `itineraries[].is_direct` (boolean; required): `total_stops` is 0. - `itineraries[].departure_token` (string | null; required): Pass to `POST /v1/serp/google_flights_return` for the next leg's options after choosing this one. Set while legs remain to choose (round-trip outbound, multi-city legs before the last); null when `booking_token` is set. Self-contained: nothing else is needed with it. - `itineraries[].google_flights_url` (string | null; required): Google Flights page for this option: the search page with the earlier legs chosen, or the booking page once every leg is chosen. - `itineraries[].group` (string; required; one of best, other): `best` (Google's top flights) or `other`. Every option is `other` when `sort_by` is not `top_flights`. - `itineraries[].price_exact` (number | null; required): Price with minor units, from Google's price token (526.19 where `price` is 527). Null when the token has no amount or is in another currency. - `itineraries[].price_token` (string | null; required): Google's own opaque price token for this option, on every itinerary (returned as `booking_token` until 2026-09-30). Usable as an itinerary key; no endpoint takes it. - `itineraries[].priced_in` (string | null; required): Set only when Google priced this option in another currency than requested: that ISO 4217 code. `price` is then in this currency and `warnings` says so. - `itineraries[].carbon_emissions` (object | null; required): Null when Google gives no estimate. - `itineraries[].total_duration_minutes` (integer | null; required): Sum of the legs' door-to-door durations, minutes; null when one is unknown. - `itineraries[].carry_on_bags_included` (integer | null; required): Carry-on bags included in the fare, as Google states it; null when not stated. - `itineraries[].checked_bags_included` (integer | null; required): Checked bags included in the fare, as Google states it; null when not stated. - `itineraries[].airline_logo` (string | null; required): Logo URL of the main airline; null when several airlines share the itinerary. - `wire_bytes` (integer; required): Size of Google's response, bytes. - `elapsed_s` (number; required): Time Google took to answer, seconds. - `cheapest_price` (number | null; required): Lowest `price` in `itineraries`; null when none is priced. - `trip_type` (string; required; one of one_way, round_trip, multi_city): `one_way`, `round_trip` or `multi_city`. - `leg_index` (integer; required): Which leg these options are for: 1 = return or second multi-city leg, and so on. - `legs_total` (integer; required): Legs in the trip: 1 one-way, 2 round trip, 2-5 multi-city. - `itinerary_count` (integer; required): Number of entries in `itineraries`. - `best_count` (integer; required): How many `itineraries` have `group: best`. - `price_insights` (object | null; optional): Usually null: Google rarely gives insights for a return or later leg. Omitted when `itineraries` is empty; that answer is not billed. - `price_insights.lowest_price` (number | null; required): Lowest price Google shows for this search, in `currency`. - `price_insights.price_level` (string | null; required; one of low, typical, high): Google's verdict on today's price: `low` (below its typical range), `typical` (inside it) or `high` (above it). - `price_insights.typical_price_range` (array of number | null; required; min items 2, max items 2): `[low, high]`: Google's typical price range for this trip. - `price_insights.price_history` (array of array of number; required): `[[unix_seconds, price], ...]`: Google's price history for this trip, about 60 days. Empty when Google gives none. - `airlines_available` (array of object; required): Airlines and alliances Google offers as filters for this search; the codes work in `include_airlines`. - `airlines_available[].code` (string; required): IATA airline code, or `STAR_ALLIANCE` / `SKYTEAM` / `ONEWORLD`. - `airlines_available[].name` (string | null; required) - `airlines_available[].type` (string; required; one of alliance, airline) - `google_flights_url` (string; required): Google Flights search page for this trip. - `source` (string; required; one of rpc, html): Always `rpc` for this call. - `warnings` (array of string; required): Notices about this answer, e.g. that Google priced some options in another currency (see each itinerary's `priced_in`). Empty when none. ### Flight booking options: `POST /v1/serp/google_flights_booking` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-flights-booking Who sells the itinerary and for how much (SerpApi `booking_options`). Airline direct and OTAs, each with price, fare name and rules, bag fees, the seller's local-currency price and Google's click-through as both a POST form (`booking_request`) and a GET link (`booking_url`). Google gathers seller prices while the request is open: expect 3-12 s. Request body (JSON): - `booking_token` (string; required; pattern ^gf1\.[A-Za-z0-9_\-]{16,16384}$): `booking_token` of a complete itinerary: a one-way result of `/v1/serp/google_flights`, or a return/last-leg result of `/v1/serp/google_flights_return`. Response fields: - `currency` (string; required): Currency of the original search. - `trip_type` (string; required; one of one_way, round_trip, multi_city): `one_way`, `round_trip` or `multi_city`. - `legs` (array of object; required): Every leg of the chosen itinerary, in order. - `legs[].segments` (array of object; required): Flights in order. - `legs[].departure_airport` (string; required): IATA code. - `legs[].arrival_airport` (string; required): IATA code. - `legs[].departure_time` (string; optional): Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. `2026-11-04T18:10:00`. Present only when known. - `legs[].arrival_time` (string; optional): Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. `2026-11-04T18:10:00`. Present only when known. - `legs[].duration_minutes` (integer | null; required): Door-to-door travel time including layovers, minutes. - `legs[].stops` (integer; required) - `legs[].layover_airports` (array of string; required): IATA codes of the connection airports. - `legs[].is_direct` (boolean; required): `stops` is 0. - `legs[].layovers` (array of object; required) - `legs[].airlines` (array of string; required): Airline names Google lists for this leg. - `booking_options` (array of object; required): Airline-direct and online travel agency sellers. - `booking_options[].book_with` (string; required): Seller name; several sellers are joined with ` and ` when the option is separate tickets. - `booking_options[].seller_code` (string | null; required): Google's code for the (first) seller: the IATA code for an airline, e.g. `LX`. - `booking_options[].is_airline` (boolean; required): Every seller is an airline (airline direct). - `booking_options[].price` (number | null; required): This seller's price for the whole trip, in `currency`, as Google shows it. - `booking_options[].currency` (string; required): Currency of the original search. - `booking_options[].display_price` (string | null; required): `price` with its currency symbol, e.g. `$527`. - `booking_options[].local_prices` (array of object; required): The seller's own price when it charges in another currency, e.g. CAD 749. - `booking_options[].marketed_as` (array of string; required): Flight numbers this seller sells the itinerary under, e.g. `LX 647`. - `booking_options[].booking_request` (object | null; required): Google's click-through as a form (SerpApi's shape): POST `post_data` as `application/x-www-form-urlencoded` to `url`. Null when the seller has no link (e.g. call to book). - `booking_options[].booking_url` (string | null; required): The same click-through as a GET link; Google answers it with a redirect to the seller's page. Null when `booking_request` is. - `booking_options[].seller_domain` (string | null; required): The seller's site as Google shows it, e.g. `www.swiss.com/...`. - `booking_options[].booking_phone` (string | null; required): Phone number of a call-to-book seller (which has no link). - `booking_options[].separate_tickets` (boolean; required): The option is several tickets bought from different sellers (see `sellers`). - `booking_options[].sellers` (array of string; required): Every seller of this option. - `booking_options[].option_title` (string | null; required): Fare family when Google names one, e.g. `Delta Main Basic`. - `booking_options[].extensions` (array of string; required): Fare rules Google lists, e.g. `No refunds`, `Free seat selection`, `Ticket changes for a fee`. Mostly shown for airline-direct sellers. - `booking_options[].baggage_prices` (array of string; required): Bag fees as Google words them, e.g. `1st checked bag: $45`, `1 free carry-on`. - `option_count` (integer; required): Number of entries in `booking_options`. - `cheapest_price` (number | null; required): Lowest `price` in `booking_options`; null when none is priced. - `price_insights` (object | null; optional): Null when Google gives none. Omitted when `booking_options` is empty; that answer is not billed. - `price_insights.lowest_price` (number | null; required): Lowest price Google shows for this search, in `currency`. - `price_insights.price_level` (string | null; required; one of low, typical, high): Google's verdict on today's price: `low` (below its typical range), `typical` (inside it) or `high` (above it). - `price_insights.typical_price_range` (array of number | null; required; min items 2, max items 2): `[low, high]`: Google's typical price range for this trip. - `price_insights.price_history` (array of array of number; required): `[[unix_seconds, price], ...]`: Google's price history for this trip, about 60 days. Empty when Google gives none. - `google_flights_url` (string; required): Google Flights booking page for this itinerary. - `wire_bytes` (integer; required): Size of Google's response, bytes. - `elapsed_s` (number; required): Time Google took to answer, seconds (typically 3-12 s: Google checks seller prices while the request is open). ### Flight location search: `POST /v1/serp/google_flights_location_search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-flights-locations Google Flights' own autocomplete: airports, cities (with their airports) and regions for a name. A city's `id` (`/m/...`) is accepted as `departure`/`arrival` by `/v1/serp/google_flights`. ~0.1 s; repeated queries are served from a 6-hour cache. Request body (JSON): - `q` (string; required; min length 1, max length 100): City, airport or region name, or a code (`paris`, `Heathrow`, `NYC`). - `hl` (string; optional; default en; pattern ^[A-Za-z]{2,3}(-[A-Za-z]{2,4})?$): Language of the returned names. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Market/country code (two letters). Response fields: - `q` (string; required): Echo of the request's `q`. - `locations` (array of object; required): Google's autocomplete results, in its order. An empty list is not billed. - `locations[].type` (string; required; one of airport, city, region, train_station) - `locations[].name` (string; required): e.g. `Paris, France`. - `locations[].iata` (string | null; required): IATA code of an airport or train station; null for cities and regions. - `locations[].id` (string | null; required): Google entity id, e.g. `/m/05qtj`. A city's id can be passed as `departure_id`/`arrival_id` (or a `multi_city` leg's `departure`/`arrival`) of `/v1/serp/google_flights` to search all of its airports. - `locations[].city` (string | null; required) - `locations[].description` (string | null; required): e.g. `Capital of France`, `Airport in France`. - `locations[].airports` (array of object; required): For a city: its airports and train stations. Empty otherwise. - `count` (integer; required): Number of entries in `locations`. - `wire_bytes` (integer; required): Size of Google's response, bytes; 0 when served from cache. - `elapsed_s` (number; required): Time Google took to answer, seconds; 0 when served from cache. - `cached` (boolean; required): Served from the 6-hour cache of repeated queries. ### Google Flights calendar: `POST /v1/serp/google_flights_calendar` Cost: 5 credits (5 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-flights-calendar Google Flights calendar/date-grid pricing. Similar to the standard SERP API google_flights_calendar. Returns cheapest prices across a date range for flexible-date comparison. Request body (JSON): - `departure` (string; required; min length 3, max length 3): IATA departure airport code. - `arrival` (string; required; min length 3, max length 3): IATA arrival airport code. - `departure_date` (string (date); required): Target outbound date (center of date range). - `return_date` (string (date) | null; optional): Target return date for round-trip. Omit for one-way. - `adults` (integer; optional; default 1; min 1, max 9): Number of passengers. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `hl` (string; optional; default en): Language code. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Market/country code. - `date_window_days` (integer; optional; default 7; min 1, max 30): Days before/after target date to include in grid. Response fields: - `departure_airport` (string; required): Echo of the request's `departure`. - `arrival_airport` (string; required): Echo of the request's `arrival`. - `currency` (string; required) - `adults` (integer; required) - `trip_type` (string; required; one of one_way, round_trip) - `prices` (array of object; required): One row per date combination in the window. - `prices[].departure_date` (string (date); required) - `prices[].return_date` (string (date); optional): Present only for round trips. - `prices[].price` (number | null; required): Cheapest fare Google shows for this date combination (whole trip), in `currency`; null when unpriced. - `prices[].currency` (string; required) - `prices[].display_price` (string | null; required): `price` with its currency symbol, e.g. `$245`. - `prices[].is_priced` (boolean; required): `price` is not null. - `wire_bytes` (integer | null; required): Size of Google's response, bytes; null when the grid was assembled from several searches. - `elapsed_s` (number; required): Seconds. - `cheapest_price` (number | null; required): Lowest `price` in `prices`. - `coverage` (string; required): `priced/total`, e.g. `14/15` (a string here). ## Cross-source Rate parity across OTAs and the source capability matrix. ### OTA sources: `GET /v1/ota/sources` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/ota-sources What each OTA can actually answer. Published because the three are not interchangeable — one returns a whole horizon, the others one date; only Agoda breaks out rooms — and a caller should pick on capability rather than by trial and error. Response fields: - `sources` (object; required) - `sources.booking` (object; required) - `sources.hotels` (object; required) - `sources.agoda` (object; required) - `sources.tripadvisor` (object; required) - `sources.hostelworld` (object; required) - `sources.expedia` (object; required) - `sources.vrbo` (object; required) ### OTA compare: `POST /v1/ota/compare` Cost: 20 credits (20 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/ota-compare Fan out across every source given an identifier. Fail-soft per source: this returns 200 with per-source status even when one OTA is blocked, because losing three good answers to one bad one is worse than a partial result the caller can see. `comparison.comparable` is false for a single priced source or mixed currencies; mixed-currency minima and spreads are not calculated. Request body (JSON): - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `booking_pagename` (string | null; optional): Booking slug. Omit to skip Booking entirely. - `booking_country` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter segment before the slug in the Booking URL. - `hotels_property_id` (string | null; optional): Hotels.com numeric id. Omit to skip Hotels.com. - `hotels_market` (string; optional; default US; one of AU, CA, DE, EU, FR, GB, IE, IT, NL, NZ, US): Hotels.com point-of-sale; also picks its currency. - `agoda_property_id` (string | null; optional): Agoda numeric id. Omit to skip Agoda. - `expedia_property_id` (string | null; optional): Expedia numeric id from `POST /v1/ota/expedia/search`. Omit to skip Expedia. - `expedia_market` (string; optional; default US; one of CA, US): Expedia point-of-sale; also picks its currency. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of ota_compare) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.currency` (string; required): Requested currency; used by Booking.com and Agoda. Hotels.com and Expedia price in their market's currency. - `search_parameters.booking_pagename` (string; optional): Present only when supplied. - `search_parameters.hotels_property_id` (string; optional): Present only when supplied. - `search_parameters.agoda_property_id` (string; optional): Present only when supplied. - `search_parameters.expedia_property_id` (string; optional): Present only when supplied. - `comparison` (object; required) - `comparison.status` (string; required; one of no_prices, single_source, mixed_currency, comparable) - `comparison.comparable` (boolean; required): True when at least two sources priced in one currency. - `comparison.reason` (string | null; required): Why the prices are not (fully) comparable. Null only when `status` is `comparable` and every price shares one basis; when bases differ it says the headline minimum mixes them. - `comparison.identifiers` (object; required): Echo of the identifiers used, keyed `booking` / `hotels` / `agoda` / `expedia` (supplied ones only). - `comparison.lowest_price` (number | null; required): Null when nothing priced or currencies are mixed. May span different price bases; see `price_basis_consistent`. - `comparison.lowest_source` (string | null; required) - `comparison.spread` (number | null; required): Highest minus lowest price per night; non-null only when `comparable` is true. - `comparison.prices` (object; required): Source -> price per night (priced sources only). - `comparison.currencies` (object; required): Source -> upper-case currency code (priced sources only). - `comparison.price_basis_consistent` (boolean; required): True when every priced source shares one price basis (also true when at most one priced). - `comparison.by_price_basis` (object; required): Priced sources grouped by price basis (keys as in `sources..price_basis`), so like is compared with like. Empty when nothing priced. - `comparison.price_provenance` (object; required): Source -> provenance of the compared price (priced sources only). - `sources` (object; required): One entry per requested source (`booking`, `hotels`, `agoda`, `expedia`). Fail-soft: a failed source is an entry with `status: error`, not a failed request. - `meta` (object; required) - `meta.requested` (integer; required) - `meta.ok` (integer; required): Sources that returned a price. - `meta.elapsed_s` (number; required) ## Official site The hotel's own booking engine, 31 engines supported. ### Official engines: `GET /v1/official/engines` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/official-engines Which booking engines can be scraped, and what each costs. Published because the spread is large — 0.2 s and no browser for SiteMinder against ~7 s and a browser per query for DerbySoft — and a caller batching a sweep should be able to plan around it. Response fields: - `extractable` (object; required): Booking engines rates can be extracted from, keyed by engine id (31 today). - `identified_only` (array of string; required): Engines that are detected but not yet extractable. - `retired` (array of string; required): Historical engines with no live booking flow. ### Official site rates: `POST /v1/official` Cost: 4 credits (4 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/official Rates from the hotel's own booking engine. The hotel website is resolved to its booking page, then its booking engine is detected automatically. The caller never chooses a vendor. Request body (JSON): - `url` (string; required; min length 8): The hotel's public homepage or property page. The API finds its booking link and detects the booking engine automatically; a direct booking URL is also accepted. - `check_in` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out` (string (date) | null; optional): Departure date. An alternative to `nights` — if both are given, this wins. - `nights` (integer; optional; default 1; min 1, max 30): Length of stay. Ignored when `check_out` is supplied. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `rooms` (integer; optional; default 1; min 1, max 8): Rooms requested. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required): `official_` + engine id. - `search_parameters.source_url` (string; required) - `search_parameters.booking_url` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.currency` (string; required) - `engine` (string; required): Detected engine id. - `source_url` (string; required) - `booking_url` (string; required) - `detected_by` (string; required): How the engine was detected, e.g. `url`, `redirect`, `booking_link`, `html_fingerprint`. - `discovery_pages` (integer; required) - `wrapper_resolutions` (integer; required) - `discovery_cache_hit` (boolean; required) - `discovery_elapsed_s` (number; required) - `collection_id` (string; required) - `observed_at` (string; required) - `property_ref` (string; required): Engine-native property id (may be empty). - `check_in` (string (date); required) - `check_out` (string (date); required) - `nights` (integer; required) - `currency` (string; required) - `sold_out` (boolean; required) - `cheapest_rate` (number | null; required): Cheapest public rate across available rooms. - `cheapest_member_rate` (number | null; required) - `member_rates_returned` (integer; required) - `rooms_returned` (integer; required) - `used_browser` (boolean; required) - `elapsed_s` (number; required) - `rooms` (array of object; required) - `rooms[].name` (string; required) - `rooms[].code` (string; required) - `rooms[].max_occupancy` (integer | null; required) - `rooms[].quantity` (integer | null; required) - `rooms[].available` (boolean; required) - `rooms[].cheapest_rate` (number | null; required): Cheapest PUBLIC rate in `rates`. - `rooms[].rates` (array of object; required) ## SERP-compatible Drop-in Google Hotels search, property and calendar shapes. ### Google Hotels search (SERP-compatible): `POST /v1/serp/google_hotels` Cost: 3 credits (3 per page of results; an empty page and failed requests are free). Docs: https://scrapercompany.com/docs/reference/serp-google-hotels Drop-in for the standard SERP API `engine=google_hotels`. Same request names and response hierarchy (`search_parameters`, `search_information`, `properties[]`, `brands[]`, `pagination`). Extracted prices are exact floats rather than rounded integers, and each property adds `prices[]` where Google attached seller rows. Filters this source cannot honour are refused with 422 instead of being ignored. Request body (JSON): - `q` (string; required; min length 2, max length 200): Destination query exactly as a traveller would type it into Google Hotels, e.g. `hotels in Montreal`, `Paris`, `hotels near JFK`. Google resolves it to a place; the response reports which in `search_information.location`. - `adults` (integer; optional; default 2; min 1, max 10): Adults in the room. Encoded as one guest entry each, the way Google's own control sends them. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter Google country (market). Sets the market; the currency is requested separately. - `hl` (string; optional; default en; pattern ^[a-z]{2,3}(-[A-Za-z]{2,4})?$): Interface language. Display strings follow it; hotel amenity names are always English. - `sort_by` (string; optional; default relevance; one of highest_rating, lowest_price, most_reviewed, relevance): Result order, as Google's Sort by control. - `price_min` (integer | null; optional; min 0): Minimum nightly price in `currency`. - `price_max` (integer | null; optional; min 0): Maximum nightly price in `currency`. - `free_cancellation` (boolean; optional; default false): Only properties Google lists with free cancellation. - `special_offers` (boolean; optional; default false): Only properties with a special offer. - `eco_certified` (boolean; optional; default false): Only eco-certified properties. - `engine` (string; optional; default google_hotels; one of google_hotels): Accepted for SERP API compatibility; must be `google_hotels`. - `property_type` (string; optional; default hotel; one of hotel, vacation_rental): `hotel` (default) is Google's own list, which Google may blend with vacation rentals; each result states its `type`. `vacation_rental` is refused with 422: Google does not honour the rentals-only category for this search, so it is refused rather than silently ignored. - `check_in_date` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out_date` (string (date); required): Departure date, after `check_in_date`; at most 30 nights. - `children_ages` (string | array of integer | null; optional): Comma-separated child ages, 0-17 (SERP API: `2,5`). - `rating` (integer | null; optional; one of 7, 8, 9): SERP API rating code: 7 (3.5+), 8 (4.0+), 9 (4.5+). - `hotel_class` (string | array of integer | null; optional): Comma-separated star classes, 2-5. - `amenities` (string | array of integer | null; optional): Comma-separated amenity ids (same ids as SERP API/SerpApi, e.g. 6 Pool, 35 Free Wi-Fi). - `property_types` (string | array of integer | null; optional): Comma-separated property-type ids, e.g. 19 Bed and breakfasts, 14 Hostels. - `brands` (string | array of integer | null; optional): Not supported: Google ignores brand filters on this search, so a non-empty value is refused with 422. - `for_displaced_individuals` (boolean; optional; default false): Not supported; `true` is refused with 422. - `bedrooms` (integer | null; optional; min 0): Vacation-rental filter. Not supported; a value above 0 is refused with 422. - `bathrooms` (integer | null; optional; min 0): Vacation-rental filter. Not supported; a value above 0 is refused with 422. - `bounding_box` (string | null; optional): Not supported; search by `q`. - `next_page_token` (string | null; optional; pattern ^[A-Za-z0-9_\-+/=]{1,200}$): Opaque cursor from `pagination.next_page_token` of the previous page. Resend the same query, stay, occupancy and filters with it, exactly as with SERP API. - `zero_retention` (boolean; optional; default false): Accepted for SERP API compatibility; search results are never persisted. Response fields: - `search_metadata` (object; required) - `search_metadata.status` (string; required; one of Success) - `search_metadata.created_at` (string (date-time); required): UTC, ISO-8601 with `Z`. - `search_metadata.request_time_taken` (number; required): Seconds. - `search_metadata.total_time_taken` (number; required): Seconds. - `search_parameters` (object; required): Echo of the effective request. Optional filters appear only when set. - `search_parameters.engine` (string; required; one of google_hotels) - `search_parameters.q` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.children_ages` (array of integer; required): One age per child; empty when none. - `search_parameters.currency` (string; required): Requested currency, upper-case. - `search_parameters.gl` (string; required): Market country code, lower-case. - `search_parameters.hl` (string; required) - `search_parameters.sort_by` (string; required; one of relevance, lowest_price, highest_rating, most_reviewed) - `search_parameters.price_min` (integer; optional): Present only when set in the request. - `search_parameters.price_max` (integer; optional): Present only when set in the request. - `search_parameters.min_rating` (number; optional): 3.5, 4.0 or 4.5. Present only when set in the request. Converted from the `rating` code (7, 8, 9). - `search_parameters.hotel_class` (array of integer; optional): Present only when set in the request. - `search_parameters.amenities` (array of integer; optional): Present only when set in the request. - `search_parameters.property_types` (array of integer; optional): Present only when set in the request. - `search_parameters.free_cancellation` (boolean; optional): Present only when true. - `search_parameters.special_offers` (boolean; optional): Present only when true. - `search_parameters.eco_certified` (boolean; optional): Present only when true. - `search_parameters.next_page_token` (string; optional): Page token this page was fetched with. Present only when one was sent. - `search_parameters.property_type` (string; required; one of hotel): Always `hotel`. - `search_information` (object; required) - `search_information.total_results` (integer | null; required): Total properties Google reports for the search. - `search_information.location` (string | null; required): Place Google resolved `q` to. - `search_information.currency_matches_request` (boolean; required): False when Google returned a currency other than the one requested. - `properties` (array of object; required): About 20 per page. - `properties[].type` (string; required; one of hotel, vacation_rental): Google blends vacation rentals into the default list; this says which each result is. - `properties[].property_token` (string; required): Google property token; pass it to `/v1/serp/google_hotels_property` or `/v1/calendar`. - `properties[].data_id` (string; optional): Google Maps data id (`0x...:0x...`). - `properties[].name` (string; required) - `properties[].link` (string; optional): The property's own website. - `properties[].description` (string; optional) - `properties[].gps_coordinates` (object; optional) - `properties[].city` (string; optional): The place Google resolved `q` to (same as `search_information.location`), not a per-property city. - `properties[].country` (string; optional): ISO 3166-1 alpha-2 country code. - `properties[].check_in_time` (string; optional): As displayed, e.g. `3:00 PM`. - `properties[].check_out_time` (string; optional) - `properties[].price_per_night` (object; optional): Present only when the stay total is known. - `properties[].total_price` (object; optional): Present only when the stay total is known. - `properties[].deal` (string; optional): Deal text, e.g. `27% less than usual`. - `properties[].deal_description` (string; optional): Badge Google renders: `Deal`, `Great Deal`, `Great Price`, or another label. - `properties[].nearby_places` (array of object; required) - `properties[].hotel_class` (string; optional): As displayed, e.g. `4-star hotel`. - `properties[].extracted_hotel_class` (integer; optional): Star class, 1-5. - `properties[].rating` (number; optional): Guest rating out of 5. - `properties[].reviews` (integer; optional) - `properties[].reviews_histogram` (object; optional): Review count per star rating, keyed `1`-`5`. - `properties[].location_rating` (number; optional): Overall location score, out of 5. - `properties[].proximity_to_things_to_do_rating` (number; optional): Score for proximity to things to do, out of 5. - `properties[].proximity_to_restaurants_rating` (number; optional): Score for proximity to restaurants, out of 5. - `properties[].proximity_to_transit_rating` (number; optional): Score for proximity to public transit, out of 5. - `properties[].airport_access_rating` (number; optional): Score for airport access, out of 5. - `properties[].reviews_breakdown` (array of object; required): Empty when Google gave none. - `properties[].amenities` (array of string; required): Hotel amenity names are always English; rentals use Google's own labels. - `properties[].excluded_amenities` (array of string; optional): Amenities a rental states it lacks, e.g. `No balcony`. - `properties[].essential_info` (array of string; optional): Rental basics such as `Entire apartment` or `Sleeps 2`. - `properties[].images` (array of object; required) - `properties[].thumbnail` (string; optional) - `properties[].prices` (array of object; optional): Seller rows Google attached to the card (an addition to the standard SERP API shape); mostly vacation rentals. - `properties[].currency` (string; optional): ISO 4217 code of every price on the property. - `brands` (array of object; required) - `brands[].id` (integer; required): Google brand id. - `brands[].title` (string; required): Brand name; empty string when Google did not name it. - `brands[].children` (array of object; required): Sub-brands. - `pagination` (object; required): Pages overlap by a few results (page 2 starts before page 1 ends); de-duplicate by `property_token`. - `pagination.records_from` (integer | null; required): 1-based position of the first result on this page. - `pagination.records_to` (integer | null; required): 1-based position of the last result on this page. - `pagination.next_page_token` (string | null; required): Send it back (as `page_token` on `/v1/hotels/search`, `next_page_token` on `/v1/serp/google_hotels`) with the same query, stay, party and filters for the next page. Null on the last page. ### Airbnb search (GET): `GET /api/v1/search` Cost: 8 credits (8 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/airbnb-search-get Drop-in GET endpoint for existing SERP API integrations. Keep ``engine``, every existing query parameter and either the ``api_key`` query credential or Bearer token; only replace the origin. ``engine=airbnb`` takes the parameters listed here. ``engine= google_autocomplete``, ``google_images`` and ``google_videos`` take the standard SERP API parameter names for those engines (validated by the same models as ``POST /v1/google/autocomplete``, ``/images``, ``/videos``) and answer the same body; each costs what its POST route costs. Parameters: - `engine` (string; optional; default airbnb; one of airbnb, google_autocomplete, google_images, google_videos): `airbnb` (the parameters below), or `google_autocomplete`, `google_images`, `google_videos` (the parameters of `POST /v1/google/autocomplete`, `/images`, `/videos`: `q`, `gl`, `hl`, `location`, `uule`, `page` and each engine's filters). - `q` (string | null; optional): Airbnb: destination text, required unless `bounding_box` is supplied. Google engines: the search query (required). - `bounding_box` (string | null; optional): Map bounds as `[[ne_lat,ne_lng],[sw_lat,sw_lng]]`; takes precedence over `q`. - `airbnb_domain` (string; optional; default airbnb.com; one of airbnb.ae, airbnb.am, airbnb.at, airbnb.az, airbnb.ba, airbnb.be, airbnb.ca, airbnb.cat, airbnb.ch, airbnb.cl, airbnb.cn, airbnb.co.cr, airbnb.co.id, airbnb.co.in, airbnb.co.kr, airbnb.co.nz, airbnb.co.uk, airbnb.co.ve, airbnb.com, airbnb.com.ar, airbnb.com.au, airbnb.com.bo, airbnb.com.br, airbnb.com.bz, airbnb.com.co, airbnb.com.ec, airbnb.com.ee, airbnb.com.gt, airbnb.com.hk, airbnb.com.hn, airbnb.com.my, airbnb.com.ni, airbnb.com.pa, airbnb.com.pe, airbnb.com.ph, airbnb.com.py, airbnb.com.ro, airbnb.com.sg, airbnb.com.sv, airbnb.com.tr, airbnb.com.tw, airbnb.com.ua, airbnb.com.vn, airbnb.cz, airbnb.de, airbnb.dk, airbnb.es, airbnb.fi, airbnb.fr, airbnb.gr, airbnb.gy, airbnb.hu, airbnb.ie, airbnb.is, airbnb.it, airbnb.jp, airbnb.lt, airbnb.lu, airbnb.lv, airbnb.me, airbnb.mx, airbnb.nl, airbnb.no, airbnb.pl, airbnb.pt, airbnb.rs, airbnb.ru, airbnb.se, airbnb.si, ar.airbnb.com, bg.airbnb.com, de.airbnb.lu, es.airbnb.com, fr.airbnb.be, fr.airbnb.ca, fr.airbnb.ch, ga.airbnb.ie, he.airbnb.com, hi.airbnb.co.in, hr.airbnb.com, it.airbnb.ch, ka.airbnb.com, kn.airbnb.co.in, mk.airbnb.com, mr.airbnb.co.in, mt.airbnb.com.mt, sk.airbnb.com, sq.airbnb.com, sw.airbnb.com, th.airbnb.com, xh.airbnb.co.za, zh-t.airbnb.com, zh.airbnb.com, zu.airbnb.co.za): Country/language Airbnb host. - `currency` (string | null; optional; one of AED, AUD, BAM, BGN, BRL, CAD, CHF, CLP, CNY, COP, CRC, CZK, DKK, EGP, EUR, GBP, GHS, GTQ, HKD, HNL, HUF, IDR, ILS, INR, JPY, KES, KRW, KZT, MAD, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, RUB, SAR, SEK, SGD, THB, TRY, TWD, UAH, UGX, USD, UYU, VND, ZAR): Airbnb-supported ISO 4217 display currency. - `include_taxes` (boolean; optional; default false): Include tax-inclusive totals when Airbnb exposes a tax line. - `check_in_date` (string (date) | null; optional): Exact check-in date in `YYYY-MM-DD` form. - `check_out_date` (string (date) | null; optional): Exact check-out date; defaults to the next day. - `time_period` (string | null; optional; one of one_month, one_week, weekend_trip): Flexible dates: `weekend_trip`, `one_week`, or `one_month`; cannot be mixed with exact dates. - `adults` (integer | null; optional): Adults aged 13+, from 0 through 16. - `children` (integer | null; optional): Children aged 2–12, from 0 through 15. - `infants` (integer | null; optional): Infants under 2, from 0 through 5. - `pets` (integer | null; optional): Pets, from 0 through 5. - `price_min` (integer | null; optional): Minimum displayed trip price. - `price_max` (integer | null; optional): Maximum displayed trip price. - `type_of_place` (string; optional; default any; one of any, entire_home, room): `any`, `room`, or `entire_home`. - `property_types` (string | null; optional): Comma-separated `house`, `guesthouse`, `apartment`, and/or `hotel`. - `bedrooms` (integer | null; optional): Minimum bedrooms, from 0 through 8. - `beds` (integer | null; optional): Minimum beds, from 0 through 8. - `bathrooms` (integer | null; optional): Minimum bathrooms, from 0 through 8. - `amenities` (string | null; optional): Comma-separated SERP API amenity names. - `next_page_token` (string | null; optional): Opaque cursor from `pagination.next_page_token` on the prior page. - `zero_retention` (boolean; optional; default false): Accepted for SERP API compatibility; raw search HTML and results are never persisted. Response fields: - `search_metadata` (object; required) - `search_metadata.id` (string; required) - `search_metadata.status` (string; required) - `search_metadata.created_at` (string; required) - `search_metadata.collection_id` (string; required) - `search_metadata.observed_at` (string; required) - `search_metadata.request_time_taken` (number; required) - `search_metadata.parsing_time_taken` (number; required) - `search_metadata.total_time_taken` (number; required) - `search_metadata.request_url` (string; required) - `search_metadata.wire_bytes` (integer; required) - `search_parameters` (object; required): Echo of the effective request. Every value is a string; parameters that were not set are omitted. - `search_parameters.engine` (string; required; one of airbnb) - `search_parameters.airbnb_domain` (string; required) - `search_information` (object; required) - `search_information.query_displayed` (string; required) - `search_information.results` (string; required) - `search_information.check_in_date` (string; optional) - `search_information.check_out_date` (string; optional) - `search_information.time_period` (string; optional) - `search_information.adults` (integer; optional) - `search_information.children` (integer; optional) - `search_information.infants` (integer; optional) - `search_information.pets` (integer; optional) - `search_information.guests` (string; required): e.g. `2 guests` or `Add guests`. - `properties` (array of object; required) - `properties[].position` (integer; required) - `properties[].id` (string; required) - `properties[].title` (string; optional) - `properties[].description` (string; optional) - `properties[].link` (string; required) - `properties[].booking_link` (string; required) - `properties[].booking_token` (string; required) - `properties[].rating` (number; optional) - `properties[].reviews` (integer; optional) - `properties[].price` (object; optional) - `properties[].check_in_date` (string; optional) - `properties[].check_out_date` (string; optional) - `properties[].time_period` (string; optional) - `properties[].accommodations` (array of string; optional) - `properties[].gps_coordinates` (object; optional) - `properties[].has_free_cancellation` (boolean; optional): Only present (as true) when advertised. - `properties[].badges` (array of string; optional) - `properties[].images` (array of string; optional) - `properties[].distance` (string; optional) - `properties[].extracted_distance` (number; optional) - `pagination` (object; optional): Present only when another page exists. - `pagination.next_page_token` (string; required) ### Google Hotels property (SERP-compatible): `POST /v1/serp/google_hotels_property` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/serp-google-hotels-property Drop-in shape for the standard SERP API google_hotels_property. Repointing an existing integration is a base-URL change. `extracted_price` is populated where SERP API may omit it, and prices are exact floats rather than rounded integers. Request body (JSON): - `property_token` (string; required; min length 8): Google property token — The standard SERP API name for the same value `/v1/search` returns as `token`. - `check_in_date` (string (date); required): First night of the stay, `YYYY-MM-DD`. - `check_out_date` (string (date); required): Departure date. Must be after `check_in_date`. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter country for the Google request, the standard SERP API spelling of `market`. - `property_name` (string; optional; default ): Optional. Improves official-site detection when the hotel's own row is labelled with its brand name. - `sources` (array of string | null; optional; min items 1, max items 20): Optional seller allowlist. Names are canonicalized, so `Expedia.com` and `Expedia` are equivalent. Omit for all Google sellers. - `source_coverage` (string; optional; default full; one of adaptive, full): `full` starts iPhone and desktop renders in parallel for maximum breadth. `adaptive` starts with iPhone and fetches desktop only when a requested seller is absent. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of google_hotels_property) - `search_parameters.property_token` (string; required) - `search_parameters.check_in_date` (string (date); required) - `search_parameters.check_out_date` (string (date); required) - `search_parameters.adults` (integer; required) - `search_parameters.currency` (string; required) - `search_parameters.gl` (string; required) - `search_parameters.nights` (integer; required) - `search_parameters.sources` (array of string; optional): Present only when `sources` was requested. - `search_parameters.source_coverage` (string; optional): Present only when `sources` was requested. - `property` (object; required) - `property.property_token` (string; required) - `property.name` (string; required) - `property.hotel_class` (string; required) - `property.hotel_class_stars` (integer | null; required) - `property.rating` (number | null; required) - `property.reviews` (integer | null; required) - `property.deal` (string | null; required) - `property.deal_description` (string | null; required) - `property.has_deal` (boolean; required) - `property.price_insights` (object; required) - `property.all_offers` (array of object; required) - `property.featured_offers` (array of object; required): Offers Google rendered as featured cards. - `property.price_per_night` (object | null; required): Lowest all-in nightly price across offers. - `property.provenance` (object | null; required): Provenance of the lowest-priced offer. - `property.currency_verified` (boolean; required) - `property.requested_market` (string; required) - `property.egress_market` (string | null; required) - `property.egress_geo_locked_ok` (boolean; required) - `property.price_insights_market_verified` (boolean; required) - `property.tax_profile` (object | null; required) - `meta` (object; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) - `meta.offers` (integer; required) - `meta.priced` (integer; required) - `meta.property_fetch` (string; required) - `meta.tax_profile_cache` (string; required) ### Google Hotels calendar (SERP-compatible): `POST /v1/serp/google_hotels_calendar` Cost: 5 credits (5 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/serp-google-hotels-calendar No SERP API equivalent — a whole forward horizon in one call. Other SERP APIs bill one request per stay date; this returns ~330 nights in a single ~105 KB response. `extracted_price_before_taxes` uses the standard SERP API base-plus-mandatory-fees basis; `extracted_price_base` and `fees` preserve the itemised values. Request body (JSON): - `property_token` (string; required; min length 8): Google property token, as returned by `/v1/search`. - `days` (integer; optional; default 90; min 1, max 330): Nights to price in one call. Max 330. - `start` (string (date) | null; optional): First stay date. Defaults to tomorrow. - `adults` (integer; optional; default 2; min 1, max 8): Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter country for the request. - `los` (integer; optional; default 1; min 1, max 30): Length of stay each night is priced at. The per-night figure genuinely moves with LOS. Response fields: - `search_parameters` (object; required) - `search_parameters.engine` (string; required; one of google_hotels_calendar) - `search_parameters.property_token` (string; required) - `search_parameters.days` (integer; required) - `search_parameters.adults` (integer; required) - `search_parameters.currency` (string; required) - `search_parameters.gl` (string; required) - `search_parameters.los` (integer; required) - `calendar` (array of object; required): One row per priced night. - `calendar[].date` (string (date); required) - `calendar[].price` (object; required): The market-correct nightly figure (same as `rate` on `/v1/calendar`). - `calendar[].extracted_price_before_taxes` (number | null; required): Base + mandatory fees (SERP API basis). - `calendar[].extracted_price_base` (number | null; required) - `calendar[].extracted_price_total` (number | null; required) - `calendar[].tax` (number | null; required) - `calendar[].fees` (number | null; required) - `calendar[].currency` (string; required) - `calendar[].rates_include_tax` (boolean; required) - `calendar[].provenance` (object; required): Provenance of one calendar row. - `unavailable_dates` (array of string (date); required) - `tax_profile` (object | null; required) - `tax_profile.rate` (number; required) - `tax_profile.confidence` (string; required; one of high, low, none) - `meta` (object; required) - `meta.coverage` (number; required): Share of requested nights priced, 0-1. - `meta.collection_id` (string; required) - `meta.observed_at` (string; required) - `meta.wire_bytes` (integer; required) - `meta.elapsed_s` (number; required) - `meta.retries` (integer; required) ## Guest reviews Guest reviews from Tripadvisor, Booking.com, Expedia, Hotels.com and Google Hotels, with provenance per page. ### Google Hotels reviews: `POST /v1/hotels/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-hotels-reviews Google Hotels guest reviews for one property token. Google mixes its own reviews with Tripadvisor's, Priceline's and others'; each row names its `provider` and keeps that provider's rating scale (5 for Google/Tripadvisor, 10 for Priceline) rather than a silently renormalised one. Ten reviews per page; `pages` follows Google's continuation token, and `next_page_token` continues past that. Request body (JSON): - `property_token` (string; required; min length 10, max length 200): Token returned by `POST /v1/hotels/search` or `POST /v1/hotels/property`. - `pages` (integer; optional; default 1; min 1, max 10): How many 10-review pages to follow. - `page_token` (string | null; optional): Continuation token from a previous answer's `next_page_token`. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country for the request. - `hl` (string; optional; default en): Language for the request. ### Expedia reviews: `POST /v1/ota/expedia/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/expedia-reviews Expedia guest reviews via the site's own registered reviews query. One request, no cookies, with the same retries as search and rates. Ratings are 0-10 parsed from the upstream score label; the "Verified review" disclaimer and "Liked: …" themes ride in `labels`, exactly as Expedia publishes them. Page by `start_index += size`. Request body (JSON): - `property_id` (string; required; min length 1, pattern ^\d+$): Numeric id returned by `POST /v1/ota/expedia/search`. - `size` (integer; optional; default 10; min 1, max 25): Reviews per page. - `start_index` (integer; optional; default 0; min 0): Row to start from; page by `start_index += size`. - `market` (string; optional; default US; one of CA, US): Point-of-sale; also selects the currency. ### Hotels.com reviews: `POST /v1/ota/hotels/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hotels-com-reviews Hotels.com guest reviews via the site's own registered reviews query. The same registered query Expedia answers, POSTed to the Hotels.com host with the Hotels.com point-of-sale. One POST, no browser; page by `start_index += size`. Request body (JSON): - `property_id` (string; required; min length 1, pattern ^\d+$): Numeric id returned by `POST /v1/ota/hotels/search`, or from `hotels.com/h38766175.Hotel-Information` (not the legacy `ho…` number). - `size` (integer; optional; default 10; min 1, max 25): Reviews per page. - `start_index` (integer; optional; default 0; min 0): Row to start from; page by `start_index += size`. - `market` (string; optional; default US; one of AU, CA, DE, EU, FR, GB, IE, IT, NL, NZ, US): Point-of-sale; also selects the currency. ### Tripadvisor reviews: `POST /v1/ota/tripadvisor/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/tripadvisor-reviews Tripadvisor guest reviews for one locationId. One persisted-query request through the same session warmup pricing uses. Ratings are 0-5; each review keeps the author, stay type, stay date, management reply and language the site publishes. Page by `offset += limit`. Request body (JSON): - `location_id` (string; required; min length 1, pattern ^\d+$): Numeric id in the property URL, e.g. `208453` from `/Hotel_Review-g60763-d208453-...`. - `limit` (integer; optional; default 10; min 1, max 30): Reviews per page (the backend accepts up to 30). - `offset` (integer; optional; default 0; min 0): Row to start from; page by `offset += limit`. ### Booking.com reviews: `POST /v1/ota/booking/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/booking-reviews Booking.com guest reviews for one property slug. The bootstrap is the same WAF-cleared page fetch the calendar uses; it yields the CSRF token plus the numeric ids the reviews query needs. Ratings are 0-10; each review keeps the guest, their country, the room type, the stay dates, and the property's reply. `text` filters by keyword server-side. That answer is billed like any other: only a reply with nothing in it is free. Request body (JSON): - `pagename` (string; required; min length 2): URL slug returned by `POST /v1/ota/booking/search`. - `country` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter segment before the slug in that URL. - `skip` (integer; optional; default 0; min 0): Reviews to skip before this page. - `limit` (integer; optional; default 10; min 1, max 25): Reviews per page (Booking caps at 25). - `sort` (string; optional; default MOST_RELEVANT; one of MOST_RELEVANT, NEWEST_FIRST, OLDEST_FIRST): One of Booking's own sort enums. - `text` (string | null; optional; max length 100): Keyword filter Booking applies server-side. ## Property lookup Confirm a property by its mailing address before targeting it. ### Property details: `POST /v1/hotels/property` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hotels-property The address-bearing render for one property token. The search card omits the mailing address; pinning the token answers with the details widget, parsed like any property card: name, mailing address, phone, rating, review count, class, times. Use it to confirm a `/v1/hotels/search` result is the property you meant before targeting it with rate or review calls. The stay dates it prices are transport for this call and not its answer. Request body (JSON): - `property_token` (string; required; min length 10, max length 200): Token returned by `POST /v1/hotels/search`. - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country for the request. - `hl` (string; optional; default en): Language for the request. ### Resolve by name and address: `POST /v1/hotels/resolve` Cost: 12 credits (12 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/hotels-resolve Look up a hotel by name and place, identify it by address. Runs the destination search for `q` (name plus city, region or country; `gl` biases the market), then fetches each of the top `limit` candidates' details record to attach the mailing address and phone. The answer lists the properties with their `property_token`, ready for `/v1/calendar`, `/v1/offers` and `/v1/hotels/reviews`, so the lookup happens once and the token is stored. Request body (JSON): - `q` (string; required; min length 2, max length 200): Hotel name plus city, region or country. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market for the search. - `hl` (string; optional; default en): Language for the search. - `limit` (integer; optional; default 3; min 1, max 3): How many candidates to resolve with addresses (1-3). - `currency` (string; optional; default USD; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum. ## Google News Keyword search and section headlines from Google's own RSS wire. ### Google News: `POST /v1/news` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/news One page (up to 100) of Google News results. This is Google's own published RSS wire — the same feed reader apps consume — so it carries the feed's semantics: newest first, one page per request, a `when:` freshness operator instead of a date range, and `link` values that are Google's canonical redirects to the publisher. `q` searches; `topic` reads a section feed; with neither the edition's top stories answer. Request body (JSON): - `q` (string | null; optional; max length 200): Search query. Omit to read `topic` (or top stories). - `topic` (string | null; optional; one of business, entertainment, health, nation, science, sports, technology, top_stories, world): Section feed: one of Google's reader sections. - `when` (string | null; optional; pattern ^\d+[hdmy]$): Freshness window appended to `q` (`1h`, `1d`, `7d`, `1y`). - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market. - `hl` (string; optional; default en): Language. - `ceid` (string | null; optional; pattern ^[A-Z]{2}:[a-z]{2}$): Explicit edition override (`CA:fr`, `GB:en`); built from `gl`/`hl` when omitted. ## Google Search Organic results, People Also Ask and the AI Overview, rendered. ### Google search: `POST /v1/google/search` Cost: 5 credits (5 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/google-search One rendered page of Google web results. Google serves a JavaScript shell to plain HTTP, so this renders the page in a real browser — seconds per call, the honest cost of the flagship. The answer carries the organic list, the People Also Ask questions (the questions only: answers load on expansion and are not in the DOM), the AI Overview text when Google generates one, and related searches. `link` is Google's `/goto` redirect unless `resolve=true`, which follows each one (one HTTP request per result). `location` (a canonical place name such as `Austin,Texas,United States`) or a raw `uule` localizes the results to a city; set `gl` to the place's country. Request body (JSON): - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market (Google `gl`): results are localized to this country. - `hl` (string; optional; default en): Interface language (Google `hl`). - `location` (string | null; optional; min length 2, max length 200): City-level geo-targeting: a Google canonical place name such as `Austin,Texas,United States` (The standard SERP API `location`). Encoded into Google's `uule` (`w+` form). Set `gl` to the place's country. Cannot be combined with `uule`. - `uule` (string | null; optional; min length 10, max length 1024): Raw Google `uule` passthrough (`w+...` canonical-name or `a+...` coordinate form), for callers that already encode their own. A `w ` whose `+` was decoded to a space is accepted. Cannot be combined with `location`. - `q` (string; required; min length 1, max length 400): Search query. - `page` (integer; optional; default 1; min 1, max 10): Result page (10 results per page). - `num` (integer; optional; default 10; min 1, max 20): Results per page. - `resolve` (boolean; optional; default false): Follow each result's `/goto` redirect to the destination URL (one HTTP request per result). ## Bing Organic results with trackers decoded to destination URLs. ### Bing search: `POST /v1/bing/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/bing-search One page of Bing organic results, up to 35 per request. Bing answers plain HTTP with no JS and no tokens. Each result keeps the title, the destination URL (Bing's click tracker is decoded back to the destination; an undecodable tracker is returned as-is rather than dropped), the display URL and the snippet. `related_searches` carries Bing's own refinement suggestions when the page shows them. Request body (JSON): - `q` (string; required; min length 1, max length 400): Search query. - `first` (integer | null; optional; min 1, max 1000): 1-based result to start from; 11 pages past the first ten. - `count` (integer; optional; default 10; min 1, max 35): Results per page (Bing serves up to 35). - `market` (string | null; optional; pattern ^[a-z]{2,3}-[A-Za-z]{2,4}$): Bing `mkt` (`en-US`, `fr-CA`); Bing geo-resolves when omitted. ## Google Trends Interest over time and top/rising related queries. ### Trends interest over time: `POST /v1/trends/interest` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/trends-interest Google Trends interest over time, one 0-100 timeline. Values are relative to the keyword's own peak in the window (100 = busiest point) — not absolute volume, exactly as Google's charts state. `time_range` uses Google's own grammar. Request body (JSON): - `keyword` (string; required; min length 1, max length 200): Search term to chart. - `geo` (string; optional; default US; one of AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UK, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW): Two-letter country. - `time_range` (string; optional; default today 1-m): Google's window grammar: `today 1-m` (default), `now 7-d`, `today 12-m`, `all`, or `2026-01-01 2026-06-30`. - `hl` (string; optional; default en-US): Language. ### Trends related queries: `POST /v1/trends/related` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/trends-related Google Trends related queries, split top and rising. Top values are 0-100 relative to the top query; rising values are growth percentages, and above 5000% Google answers "Breakout", carried as `breakout: true` with a null value. Request body (JSON): - `keyword` (string; required; min length 1, max length 200): Search term. - `geo` (string; optional; default US; one of AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UK, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW): Two-letter country. - `time_range` (string; optional; default today 1-m): Google's window grammar (see interest over time). - `hl` (string; optional; default en-US): Language. ## Google Maps Places search and place detail with review counts. ### Maps places search: `POST /v1/maps/search` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/maps-search One page of Google Maps place cards. `q` is whatever the Maps search box takes — a business name, a category in a place, a landmark. Each card carries name, address, coordinates, rating, phone, website, category and the `place_token` the detail call keys off. The review count is only on the detail record. Request body (JSON): - `q` (string; required; min length 1, max length 200): Maps search query. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market. - `hl` (string; optional; default en): Language. ### Maps place detail: `POST /v1/maps/detail` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/maps-detail One place's detail card: the search fields plus the review count. Token and name come from the same `POST /v1/maps/search` row — the token pin answers only when the query names the same place. Request body (JSON): - `place_token` (string; required; min length 10): Place token from `POST /v1/maps/search` (`0x…:0x…`). - `name` (string; required; min length 1, max length 200): The place's name, from the same search row as the token. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market. - `hl` (string; optional; default en): Language. ## Google Jobs Job cards with apply sources, rendered. ### Jobs search: `POST /v1/jobs/search` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/jobs-search One rendered page of Google Jobs cards. Google serves a JavaScript shell to plain HTTP, so this renders the jobs panel in a real browser — seconds per call. Each card carries the title, company, location, the upstream publisher (`via`), the relative posting age (Google publishes no absolute dates here), the employment type, and the apply links with their sources. Request body (JSON): - `q` (string; required; min length 1, max length 300): Jobs query. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market. - `hl` (string; optional; default en): Language. ## Google Shopping Product cards with price, merchant and condition. ### Shopping search: `POST /v1/shopping/search` Cost: 3 credits (3 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/shopping-search One rendered page of Google Shopping cards (~10 per page). Google serves a JavaScript shell to plain HTTP, so this renders the shopping SERP in a real browser — seconds per call. Each card carries the title, price, merchant and condition chips ("Pre-owned"), plus Google's `data-pid`. Google renders the same product more than once; the answer dedupes by `data-pid`. Request body (JSON): - `q` (string; required; min length 1, max length 300): Shopping query. - `gl` (string; optional; default us; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Country market. - `hl` (string; optional; default en): Language. ## Amazon Product search and a product's ratings histogram with featured reviews. ### Amazon search: `POST /v1/amazon/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/amazon-search One page (~48) of Amazon search results. Over plain HTTP. Prices follow the local point-of-sale — a Canadian exit answers CAD — so `price_text` keeps the display string verbatim and `currency` carries the best-effort guess from its symbol. Sponsored rows come labelled in `sponsored` rather than dropped. Request body (JSON): - `q` (string; required; min length 1, max length 300): Search query. - `page` (integer; optional; default 1; min 1, max 20): Result page. - `sort` (string | null; optional; one of relevanceblender, price-asc-rank, price-desc-rank, review-rank, date-desc-rank): Amazon's own `s=` sort value; omit for Amazon's default. - `relevanceblender`: Featured (Amazon's default ranking) - `price-asc-rank`: Price: low to high - `price-desc-rank`: Price: high to low - `review-rank`: Avg. customer review - `date-desc-rank`: Newest arrivals Deprecated alias: `relevanceblanks` is accepted and treated as `relevanceblender`. - `min_rating` (number | null; optional; min 0, max 4.5): Amazon's customer-rating filter (0..4.5). ### Amazon reviews: `POST /v1/amazon/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/amazon-reviews A product's ratings histogram and featured reviews. The `/product-reviews` list requires sign-in (measured: redirected to sign-in over plain HTTP and in a fresh browser), so the answer is the product page's own reviews widget, rendered in a real browser: the 5→1 histogram, the global ratings count, and the featured reviews (title, rating, date, author, body, "Verified Purchase", helpful votes). Request body (JSON): - `asin` (string; required; min length 10, max length 10, pattern ^[A-Z0-9]+$): Product ASIN. ## Walmart Product search and reviews from the store's own JSON, over plain HTTP. ### Walmart search: `POST /v1/walmart/search` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/walmart-search One page (~40) of Walmart search results. Walmart's own `__NEXT_DATA__` store over plain HTTP — no browser. Each item carries name, brand, price with currency, rating, review count, and the item id the reviews call keys off. Sponsored items come labelled in `sponsored` rather than dropped. Request body (JSON): - `q` (string; required; min length 1, max length 200): Search query. - `page` (integer; optional; default 1; min 1, max 50): Result page. - `sort` (string | null; optional; one of best_match, price_low, price_high, rating, best_seller, new): Walmart's own `sort=` value; omit for Walmart's default. - `best_match`: Best match (Walmart's default) - `price_low`: Price: low to high - `price_high`: Price: high to low - `rating`: Highest customer rating - `best_seller`: Best sellers - `new`: Newest ### Walmart reviews: `POST /v1/walmart/reviews` Cost: 2 credits (2 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/walmart-reviews One page (10) of Walmart reviews for an item. Plain HTTP — no browser, no tokens. The answer carries the review list (rating, title, text, date normalized from Walmart's M/D/YYYY, the "Verified Purchase" badge) plus the summary: average, total, per-star counts and percentages, recommended percentage, and Walmart's own `next_page` url. Request body (JSON): - `item_id` (string; required; min length 1, pattern ^\d+$): Numeric item id returned by `POST /v1/walmart/search`. - `page` (integer; optional; default 1; min 1, max 100): Review page. - `sort` (string; optional; default relevancy; one of relevancy, most-helpful, most-recent, highest-rating, lowest-rating): Walmart's own review sort. - `relevancy`: Most relevant (Walmart's default) - `most-helpful`: Most helpful - `most-recent`: Newest first - `highest-rating`: Highest rating first - `lowest-rating`: Lowest rating first ## Indeed Job records with salary, posting age and company ratings, over plain HTTP. ### Indeed jobs: `POST /v1/indeed/jobs` Cost: 1 credit (1 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/indeed-jobs One page (~45) of Indeed job records. Indeed answers plain HTTP with its own embedded job-cards model — no browser, no tokens. Each record carries the jobkey, title, company, location, salary (verbatim text plus Indeed's extracted min/max and period), the relative posting age, the creation date from Indeed's epoch, the company's rating, and Indeed's own redirect link. Sponsored rows come labelled, not dropped. Request body (JSON): - `q` (string; required; min length 1, max length 300): Job query. - `location` (string | null; optional; max length 120): Indeed's `l` parameter: a city, state or `remote`. - `page` (integer; optional; default 1; min 1, max 30): Result page. - `radius_km` (integer | null; optional; min 0, max 2000): Indeed's `radius`, in km. - `fromage_days` (integer | null; optional; min 0, max 30): Posting age limit, in days (Indeed's `fromage`). ## Jobs Asynchronous calendar batches with webhooks. ### Create a calendar job: `POST /v1/jobs` Cost: from 5 credits (each succeeded item is priced like POST /v1/calendar, surcharges included (5 for a default item); failed items are free). Docs: https://scrapercompany.com/docs/reference/jobs-create Persist before returning 202; execution can survive API restarts. Parameters: - `Idempotency-Key` (string; required; min length 1, max length 200): Unique per logical submission. Reusing it with the same body returns the original job; a different body is 409. Request body (JSON): - `items` (array of object; required; min items 1, max items 50): One to 50 Google calendar requests. Each item keeps its own market, currency, horizon, occupancy and price basis. - `items[].token` (string; required; min length 8): Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`. - `items[].market` (string | null; optional; one of AG, AT, AU, BE, BZ, CA, CH, DE, ES, FR, GB, IE, IT, MX, NL, NZ, PT, US): Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`. - `items[].country` (string | null; optional; one of ad, ae, af, ag, ai, al, am, ao, aq, ar, as, at, au, aw, ax, az, ba, bb, bd, be, bf, bg, bh, bi, bj, bl, bm, bn, bo, bq, br, bs, bt, bv, bw, by, bz, ca, cc, cd, cf, cg, ch, ci, ck, cl, cm, cn, co, cr, cu, cv, cw, cx, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fk, fm, fo, fr, ga, gb, gd, ge, gf, gg, gh, gi, gl, gm, gn, gp, gq, gr, gs, gt, gu, gw, gy, hk, hm, hn, hr, ht, hu, id, ie, il, im, in, io, iq, ir, is, it, je, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, kw, ky, kz, la, lb, lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mf, mg, mh, mk, ml, mm, mn, mo, mp, mq, mr, ms, mt, mu, mv, mw, mx, my, mz, na, nc, ne, nf, ng, ni, nl, no, np, nr, nu, nz, om, pa, pe, pf, pg, ph, pk, pl, pm, pn, pr, ps, pt, pw, py, qa, re, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, sh, si, sj, sk, sl, sm, sn, so, sr, ss, st, sv, sx, sy, sz, tc, td, tf, tg, th, tj, tk, tl, tm, tn, to, tr, tt, tv, tw, tz, ua, ug, uk, um, us, uy, uz, va, vc, ve, vg, vi, vn, vu, wf, ws, xk, ye, yt, za, zm, zw): Two-letter `gl` override. Normally set by `market`. - `items[].currency` (string | null; optional; one of AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR): ISO currency for the returned prices. - `items[].days` (integer; optional; default 90; min 1, max 330): Nights to price, starting at `start`. Max 330. - `items[].start` (string (date) | null; optional): First stay date. Defaults to tomorrow. - `items[].adults` (integer; optional; default 2; min 1, max 8): Occupancy: number of adults, 1-8. Children are not supported by the Google calendar. - `items[].los` (integer; optional; default 1; min 1, max 30): Length of stay per quote. Nightly price genuinely moves with LOS. - `items[].rates_include_tax` (boolean | null; optional): Overrides the market default; pass the property's own setting - `items[].is_hostel` (boolean; optional; default false): Hostels are priced per bed rather than per room, so occupancy changes the rate differently. Set this and the per-person maths is applied. - `items[].probe_min_stay` (boolean; optional; default true): Re-ask for any night that will not price as a single night. Google returns a two-night-minimum night identically to a sold-out one — empty, with no reason and no min-stay field — so without this, weekends silently vanish. On a beach market in August that was every Friday and Saturday on half the comp set. Filled rows carry `min_length_of_stay` and a per-night rate derived from the longer stay. Costs one extra call per probe level, not per date. - `items[].basis` (string; optional; default cheapest; one of cheapest, mainstream; pattern ^(cheapest|mainstream)$): What the nightly figure should mean. **`cheapest` (default)** is the fast calendar path: one small request for the whole horizon. It returns Google's lowest bookable rate, including aggregators. The base/fees/taxes/total split and SERP-compatible `rate_before_taxes_with_fees` remain populated. **`mainstream`** also returns `rate_mainstream_total` / `rate_mainstream_base` / `mainstream_source` / `aggregator_discount` — the cheapest rate on Booking, Expedia, Hotels.com, Priceline, Tripadvisor or Agoda, which is what a comp-set audit means by 'the OTA rate'. `rate_total` is left untouched, so both bases are available. This is intentionally expensive: it samples multi-megabyte offers pages and, when an aggregator sets the floor, re-prices each date. Measured on a 14-day request it took about 8s versus 0.4s for `cheapest`; use it selectively. `basis_applied` reports which path ran. - `items[].verify_sources` (integer; optional; default 0; min 0, max 5): Spot-check this many nights against the per-OTA offers page and return a `source_check` block. The Google calendar gives one price per night and never says which source it came from — usually a mainstream OTA, but where a discounter undercuts them it reports the discounter. Measured on four properties: three matched the cheapest mainstream OTA to the cent, the fourth's figure was Super.com's at 15% under. Costs one ~3 MB offers fetch per sampled night, so it is a sample, not every date. - `items[].label` (string | null; optional; max length 200): Optional customer label returned with this item. - `priority` (integer; optional; default 5; min 0, max 9): Queue priority from 0 (lowest) to 9 (highest). FIFO is preserved among jobs with the same priority. - `callback_url` (string | null; optional; max length 2048): Optional public HTTPS endpoint. ScraperCompany POSTs a signed `job.completed` event to it after the batch finishes. If webhook delivery is not enabled for the service, a submission with `callback_url` is rejected with 503. Response fields: - `id` (string; required): `refreshjob_...` - `job_id` (string; required): Same as `id`. - `poll_url` (string; required): `/v1/jobs/{job_id}` - `status` (string; required; one of queued, running, succeeded, partial, failed) - `priority` (integer; required) - `callback_url` (string | null; required) - `callback_status` (string; required; one of not_configured, pending, delivered, failed) - `callback_attempts` (integer; required) - `callback_last_error` (string | null; required) - `artifact_uri` (string | null; required) - `artifact_sha256` (string | null; required) - `result_summary` (object; required): Empty object until the job finishes. - `result_summary.rates` (integer; optional) - `result_summary.wire_bytes` (integer; optional) - `result_summary.database` (object; optional) - `error` (string | null; required) - `items_total` (integer; required) - `items_succeeded` (integer; required) - `items_failed` (integer; required) - `created_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `started_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `finished_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `updated_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `items` (array of object; required) - `items[].id` (string; required): `refreshitem_...` - `items[].item_index` (integer; required) - `items[].token` (string; required) - `items[].label` (string | null; required) - `items[].status` (string; required; one of queued, running, succeeded, failed) - `items[].request` (object; required): One property in an asynchronous calendar batch. - `items[].result` (object | null; required): The item's calendar payload. Only populated with `include_results=true` once the item succeeded; otherwise null. - `items[].error` (string | null; required) - `items[].attempts` (integer; required) - `items[].started_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `items[].finished_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `items[].updated_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. ### Get a calendar job: `GET /v1/jobs/{job_id}` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/jobs-get Poll a batched calendar job and read each item's status. A submitted job (`POST /v1/jobs`) returns immediately with a job id; this is how you learn the outcome. Each item reports its own status, so one failed property does not hide the ones that succeeded. Results are omitted unless `include_results` is set. Free. Parameters: - `job_id` (string; required) - `include_results` (boolean; optional; default false): Include each completed calendar payload. Leave false for a small status-only response. Response fields: - `id` (string; required): `refreshjob_...` - `job_id` (string; required): Same as `id`. - `poll_url` (string; required): `/v1/jobs/{job_id}` - `status` (string; required; one of queued, running, succeeded, partial, failed) - `priority` (integer; required) - `callback_url` (string | null; required) - `callback_status` (string; required; one of not_configured, pending, delivered, failed) - `callback_attempts` (integer; required) - `callback_last_error` (string | null; required) - `artifact_uri` (string | null; required) - `artifact_sha256` (string | null; required) - `result_summary` (object; required): Empty object until the job finishes. - `result_summary.rates` (integer; optional) - `result_summary.wire_bytes` (integer; optional) - `result_summary.database` (object; optional) - `error` (string | null; required) - `items_total` (integer; required) - `items_succeeded` (integer; required) - `items_failed` (integer; required) - `created_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `started_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `finished_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `updated_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `items` (array of object; required) - `items[].id` (string; required): `refreshitem_...` - `items[].item_index` (integer; required) - `items[].token` (string; required) - `items[].label` (string | null; required) - `items[].status` (string; required; one of queued, running, succeeded, failed) - `items[].request` (object; required): One property in an asynchronous calendar batch. - `items[].result` (object | null; required): The item's calendar payload. Only populated with `include_results=true` once the item succeeded; otherwise null. - `items[].error` (string | null; required) - `items[].attempts` (integer; required) - `items[].started_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `items[].finished_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `items[].updated_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. ## Stored rates Read stored observations without calling a source. ### Stored rates: `GET /v1/rates/stored` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/stored-rates Stored-rate lookup with explicit freshness metadata. Parameters: - `token` (string; required; min length 8): Google property token whose rates have already been collected into stored rates (for example by a `POST /v1/jobs` batch). - `start` (string (date) | null; optional): Inclusive first stay date. - `end` (string (date) | null; optional): Inclusive last stay date. - `limit` (integer; optional; default 500; min 1, max 2000) Response fields: - `source` (string; required; one of google_hotels) - `source_property_id` (string; required): The requested token. - `count` (integer; required) - `last_observed_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `last_success_at` (string | null; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `age_seconds` (integer | null; required) - `freshness` (string; required; one of missing, fresh, stale, expired): `fresh` <= 24 h, `stale` <= 48 h, `expired` older, `missing` when never collected. - `rates` (array of object; required) - `rates[].property_name` (string; required) - `rates[].stay_date` (string (date); required) - `rates[].occupancy_key` (string; required): e.g. `adults=2` - `rates[].los` (integer; required) - `rates[].rate` (number | null; required) - `rates[].rate_base` (number | null; required) - `rates[].rate_before_taxes_with_fees` (number | null; required) - `rates[].rate_total` (number | null; required) - `rates[].tax` (number | null; required) - `rates[].fees` (number | null; required) - `rates[].currency` (string; required) - `rates[].market` (string | null; required) - `rates[].rates_include_tax` (boolean; required) - `rates[].min_length_of_stay` (integer | null; required) - `rates[].observed_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `rates[].last_changed_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `rates[].collection_id` (string; required) - `rates[].observation_id` (string; required) - `rates[].provenance` (object; required): Provenance of one calendar row. ### Storage status: `GET /v1/storage/status` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/storage-status Operational status and record counts for the stored-rates service. ## Usage Usage totals and request history for your key. ### Usage: `GET /v1/usage` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/usage Request counts, errors, bytes, and latency for the calling key only. Parameters: - `period` (string; optional; default 30d; pattern ^(24h|7d|30d|90d)$): Aggregation window: 24 hours, 7, 30, or 90 days. Response fields: - `key` (object; required) - `key.name` (string; required) - `key.prefix` (string; required): First characters of the key, for display. - `key.rate_limit_per_min` (integer; required): This key's requests-per-minute limit. - `key.role` (string; required) - `period` (object; required) - `period.name` (string; required; one of 24h, 7d, 30d, 90d) - `period.start` (string (date-time); required) - `period.end` (string (date-time); required) - `totals` (object; required) - `totals.requests` (integer; required) - `totals.successful` (integer; required) - `totals.errors` (integer; required) - `totals.rate_limited` (integer; required) - `totals.response_bytes` (integer; required) - `totals.avg_duration_ms` (integer; required) - `totals.p95_duration_ms` (integer; required) - `by_status` (array of object; required) - `by_status[].status` (integer; required) - `by_status[].requests` (integer; required) - `by_endpoint` (array of object; required): Top 50 endpoints by request count. - `by_endpoint[].method` (string; required) - `by_endpoint[].path` (string; required) - `by_endpoint[].requests` (integer; required) - `by_endpoint[].errors` (integer; required) - `by_endpoint[].avg_duration_ms` (integer; required) - `by_endpoint[].p95_duration_ms` (integer; required) - `by_day` (array of object; required) - `by_day[].date` (string (date); required) - `by_day[].requests` (integer; required) - `by_day[].errors` (integer; required) - `by_day[].response_bytes` (integer; required) ### Request history: `GET /v1/requests` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/requests Newest-first metadata with keyset pagination and optional filters. Parameters: - `limit` (integer; optional; default 50; min 1, max 200) - `cursor` (string | null; optional): Opaque `next_cursor` from the previous page. - `status` (integer | null; optional; min 100, max 599) - `method` (string | null; optional; pattern ^(GET|POST|PUT|PATCH|DELETE)$) - `path` (string | null; optional; max length 300): Exact normalized route path, such as `/v1/calendar`. Response fields: - `requests` (array of object; required): Newest first. - `requests[].id` (string; required): `req_...`; equals the `x-request-id` response header. - `requests[].method` (string; required) - `requests[].path` (string; required): Route path, e.g. `/v1/calendar`. - `requests[].status` (integer; required) - `requests[].duration_ms` (integer; required) - `requests[].response_bytes` (integer; required) - `requests[].request` (object; required): Sanitized request metadata; each key present only when the request had it. - `requests[].created_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. - `count` (integer; required) - `has_more` (boolean; required) - `next_cursor` (string; optional): Present only when `has_more` is true; pass it back as the `cursor` query parameter. ### Request detail: `GET /v1/requests/{request_id}` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/request-detail Return 404 for missing records and records owned by another key. Parameters: - `request_id` (string; required) Response fields: - `id` (string; required): `req_...`; equals the `x-request-id` response header. - `method` (string; required) - `path` (string; required): Route path, e.g. `/v1/calendar`. - `status` (integer; required) - `duration_ms` (integer; required) - `response_bytes` (integer; required) - `request` (object; required): Sanitized request metadata; each key present only when the request had it. - `request.path` (object; optional): Path parameters. - `request.query` (object; optional): Query parameters (credentials redacted). - `request.body` (any; optional): JSON body (credentials redacted), or `{truncated, bytes}` / `{invalid_json, bytes}`. - `created_at` (string; required): Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`. ## Billing Plan, credit balance, ledger and the cost table. ### Billing summary: `GET /v1/billing` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/billing Plan, credit balance and when the current period ends. The first call a new integration should make: it reports whether the key is metered at all, what it has left and what renews when. Free. Response fields: - `mode` (string; required; one of off, shadow, enforce): Credit metering mode: `shadow` (metered and recorded, never blocks) during the beta; `enforce` once paid plans are on sale. - `plan` (object; required) - `plan.code` (string; required; one of free, starter, growth, scale, enterprise): Plan code. - `plan.name` (string; required) - `plan.monthly_credits` (integer; required): Credits granted at the start of each period. - `plan.price_usd` (integer; required): Monthly price in USD; 0 = free, -1 = custom (sales). - `plan.concurrency` (integer; required): Concurrent metered requests allowed once enforcement is on. - `credits` (object; required) - `credits.balance` (integer; required): Credits on the account. In shadow mode this can go negative; the overdraft is forgiven at renewal. - `credits.reserved` (integer; required): Credits held by requests that are still running. - `credits.available` (integer; required): `balance - reserved`. - `credits.credits_used` (integer; required): Credits charged this period. - `credits.credits_refunded` (integer; required): Credits returned this period. - `credits.billable_requests` (integer; required): Requests charged this period. - `period` (object; required) - `period.start` (string (date-time); required) - `period.end` (string (date-time); required): Renewal time; unspent credits expire then. - `subscription` (object; optional) - `subscription.status` (string; optional) - `subscription.stripe_managed` (boolean; optional) ### Credit ledger: `GET /v1/billing/ledger` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/billing-ledger Credit movements newest first, one page at a time. Each row names the route and the amount, so a bill can be reconciled against the calls that caused it. Paginate with `before` using the `next_before` value from the previous page. Free. Parameters: - `limit` (integer; optional; default 50; min 1, max 200) - `before` (integer | null; optional; min 1): Return entries with an id below this. Response fields: - `entries` (array of object; required): Newest first. - `entries[].id` (integer; required): Entry id; pass the last one as `before` to page. - `entries[].kind` (string; required): `usage`, `grant`, `expiry`, `refund`, `adjustment`, ... - `entries[].amount` (integer; required): Signed credit change (negative for usage). - `entries[].balance_after` (integer; required) - `entries[].route` (string; optional): Route template for usage entries. - `entries[].request_id` (string; optional): `x-request-id` of the charged request. - `entries[].detail` (object; optional) - `entries[].created_at` (string (date-time); required) - `next_before` (integer | null; required): Pass as `before` for the next page; null on the last page. ### Plans and costs: `GET /v1/billing/plans` Cost: free (0 (failed requests are free)). Docs: https://scrapercompany.com/docs/reference/billing-plans Every plan, plus the credit cost of every endpoint. This is the authoritative price list — the same table that meters requests — so a caller can cost a workload before spending anything on it. `GET /v1` carries the same per-endpoint costs. Free. Response fields: - `plans` (array of object; required) - `plans[].code` (string; required; one of free, starter, growth, scale, enterprise): Plan code. - `plans[].name` (string; required) - `plans[].monthly_credits` (integer; required): Credits granted at the start of each period. - `plans[].price_usd` (integer; required): Monthly price in USD; 0 = free, -1 = custom (sales). - `plans[].concurrency` (integer; required): Concurrent metered requests allowed once enforcement is on. - `costs` (array of object; required): Base credit cost of every metered operation. - `costs[].method` (string; required) - `costs[].path` (string; required) - `costs[].credits` (integer; required) - `free` (array of string; required): Operations that never cost credits. - `notes` (array of string; required) - `mode` (string; required; one of off, shadow, enforce)