Skip to content
Booking.com

Booking.com search

Resolve a hotel name to Booking.com's country/slug identifier.

POST/v1/ota/booking/search
1 credit

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

POSThttps://api.scrapercompany.com/v1/ota/booking/search

Authenticate with your API key in the x-api-key header (see Authentication).

Body

JSON object. Unknown fields are rejected with 422.

  • namestringrequiredmin length 1

    Hotel name as a guest would search for it.

  • citystringdefault

    Strongly recommended for common hotel names. It is sent to Booking.com with the name so results come from the intended city.

  • limitintegerdefault 5min 1, max 10

    Maximum candidates to return, best match first.

Example request

curl -X POST "https://api.scrapercompany.com/v1/ota/booking/search" \
  -H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Moxy Boston Downtown",
    "city": "Boston"
  }'

Response

200 — Candidate Booking.com URL slugs, ranked against the requested hotel name. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).

200 response
{
  "search_parameters": {
    "engine": "booking_search",
    "name": "Moxy Boston Downtown",
    "city": "Boston",
    "limit": 5
  },
  "search_status": "matched",
  "recommended_match": {
    "pagename": "moxy-boston-downtown",
    "country": "us",
    "name": "Moxy Boston Downtown",
    "url": "https://www.booking.com/hotel/us/moxy-boston-downtown.html",
    "rank": 0,
    "name_score": 1,
    "identity_score": 1,
    "match_score": 1,
    "confidence": "high"
  },
  "warnings": [],
  "matches": [
    {
      "pagename": "moxy-boston-downtown",
      "country": "us",
      "name": "Moxy Boston Downtown",
      "url": "https://www.booking.com/hotel/us/moxy-boston-downtown.html",
      "rank": 0,
      "name_score": 1,
      "identity_score": 1,
      "match_score": 1,
      "confidence": "high"
    }
  ],
  "meta": {
    "source": "booking",
    "matches": 1,
    "selection_method": "name_city_confidence",
    "match_threshold": 0.8,
    "match_margin": 0.12,
    "wire_bytes": 1384521,
    "elapsed_s": 1.214
  }
}

Response fields

Fields marked required are always present; others appear when they apply.

  • search_parametersobjectrequired
    Show 4 child fields
    • search_parameters.enginestringrequired

      One ofbooking_search

    • search_parameters.namestringrequired
    • search_parameters.citystringrequired
    • search_parameters.limitintegerrequired
  • search_statusstringrequired

    matched only when the top candidate clears the identity threshold and margin.

    One ofmatchedambiguousnot_found

  • recommended_matchobject | nullrequired

    Safe to store; null unless search_status is matched.

    Show 9 child fields
    • recommended_match.pagenamestringrequired

      URL slug; pass as pagename.

    • recommended_match.countrystringrequired

      Two-letter URL segment; pass as country.

    • recommended_match.namestringrequired
    • recommended_match.urlstringrequired
    • recommended_match.rankintegerrequired
    • recommended_match.name_scorenumberrequired
    • recommended_match.identity_scorenumberrequired
    • recommended_match.match_scorenumberrequired
    • recommended_match.confidencestringrequired

      One ofhighmediumlow

  • warningsarray of stringrequired
  • matchesarray of objectrequired

    Candidates, best first, for manual review.

    Show 9 child fields
    • matches[].pagenamestringrequired

      URL slug; pass as pagename.

    • matches[].countrystringrequired

      Two-letter URL segment; pass as country.

    • matches[].namestringrequired
    • matches[].urlstringrequired
    • matches[].rankintegerrequired
    • matches[].name_scorenumberrequired
    • matches[].identity_scorenumberrequired
    • matches[].match_scorenumberrequired
    • matches[].confidencestringrequired

      One ofhighmediumlow

  • metaobjectrequired
    Show 7 child fields
    • meta.sourcestringrequired
    • meta.matchesintegerrequired
    • meta.selection_methodstringrequired
    • meta.match_thresholdnumberrequired
    • meta.match_marginnumberrequired
    • meta.wire_bytesintegerrequired
    • meta.elapsed_snumberrequired

Errors

Errors return a JSON body with a detail field. Failed requests are not charged. See Errors for the full list and retry advice.

StatusMeaningRetry?
401Unauthorized

Missing or invalid API key.

{"detail":"missing or invalid API key"}
No, fix the request
402Payment Required

Not enough credits for this request. Only returned once credit enforcement is switched on; during the beta metering runs in shadow mode and never blocks.

{"detail":"insufficient credits: this request costs 5, 0 available. Credits renew 2026-11-01."}
No, fix the request
422Unprocessable Content

Request validation failed. detail is a list of problems for schema errors, or a string for semantic checks performed by the endpoint.

{"detail":[{"loc":["body","name"],"msg":"Field required","type":"missing"}]}
No, fix the request
429Too Many Requests

Too many requests: the key's requests-per-minute limit was exceeded, or (once credit enforcement is on) the plan's concurrent-request limit. No rate-limit or Retry-After headers are sent; back off and retry.

{"detail":"rate limit 60/min exceeded"}
Yes, with backoff
502Bad Gateway

The upstream source failed, blocked the request or returned an unusable answer. Safe to retry later; failed requests are not charged.

{"detail":"RuntimeError"}
Yes, with backoff

Try it

  1. Export your key: export SCRAPERCOMPANY_API_KEY=sk_... (no key yet? request access).
  2. Copy the cURL example above and run it in a terminal.
  3. Or open the interactive playground on api.scrapercompany.com, paste your key and pick this endpoint.

Credits

1 credit per successful call. Failed, blocked and empty results are free. Credit metering is in beta and does not block requests yet.