Rate-code matching

Rate-code matching across official sites and OTAs

Compare a non-refundable rate with a non-refundable rate and a member price with a member price. Every plan comes back with a normalised category, the brand's own rate code where it has one, and whether it is refundable.

Built for revenue management systems, rate shoppers, parity tools, hotel bi teams.

Endpoints used

One night, grouped by what is actually sold

Plans from each channel sorted into comparable categories, so the cheapest offer in each group is a fair comparison.

Example · rate-code matching

Is the cheapest rate really cheaper, or a different offer?

  1. POST /v1/official
  2. POST /v1/ota/booking/rooms
  3. POST /v1/ota/expedia
  4. your comparison

Best available, refundablerate_category: "bar"

  • Official site — Best Available Rate$228.00
  • Booking.com — Standard rate$236.40
  • Expedia — Room only$231.90

Pay now, non-refundablerate_category: "advance_purchase"

  • Official site — Advance Purchase, non-refundable$199.00
  • Booking.com — Non-refundable, non-refundable$212.40

Signed-in membersrate_category: "member"

  • Official site — Member Rate$216.60
  • Expedia — Member price$219.00

Eligibility required (AAA)rate_category: "qualified"

  • Official site — AAA Rate$205.10

Fictional hotel, one night, illustrative rates. The cheapest plan in each group is highlighted.

Fictional hotel, illustrative rates. rate_category is the API's field.

Are we comparing the same rate on every channel?

The cheapest number on a rate-shopping screen is often a different product: a non-refundable advance-purchase rate against a flexible one, a member price against the public rate, or an AAA rate most guests cannot book. Compare them blindly and the parity alerts and price recommendations built on top are wrong.

Every site names its plans differently, and chains add their own codes. Matching them by hand does not scale past a few hotels, so the category has to arrive with the rate, decided the same way for every channel.

How teams build it

  1. 1Resolve the property once

    Turn the hotel name into its Google property token and its OTA ids, and store them with the hotel record.

    POST /v1/search
  2. 2Read the official site, qualified rates included

    Pass the hotel's website. The API detects which of 44 booking engines it runs. Ask for qualified_rates (aaa, senior, government) where the engine offers them.

    POST /v1/official
  3. 3Read the OTA rooms and plans

    Booking.com and Expedia return each room with its rate plans, cancellation terms and the site’s own plan code.

    POST /v1/ota/booking/rooms
  4. 4Compare within a category

    Group plans by rate_category, then compare the cheapest offer in each group across channels. Member and qualified rates never count as the public price.

What you get back

rate_category
a normalised category on every plan: bar, rack, advance_purchase, member, points, package, promo, qualified or unknown
rate_category_source
how the category was decided: the brand’s own flag or the plan’s name
rate_code
the brand’s or the site’s own code for the plan, where it shows one
Refundability and meals
refundable and meal_plan where the brand states them
curl -X POST "https://api.scrapercompany.com/v1/official" \
  -H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.ihg.com/intercontinental/hotels/us/en/new-york/nychc/hoteldetail",
    "check_in": "2026-12-21",
    "nights": 1,
    "currency": "USD"
  }'
Response (trimmed)
{
  "search_parameters": {
    "engine": "official_brand_ihg",
    "source_url": "https://www.ihg.com/intercontinental/hotels/us/en/new-york/nychc/hoteldetail",
    "booking_url": "https://www.ihg.com/intercontinental/hotels/us/en/new-york/nychc/hoteldetail",
    "check_in_date": "2027-02-11",
    "check_out_date": "2027-02-12",
    "adults": 2,
    "currency": "USD"
  },
  "engine": "brand_ihg",
  "source_url": "https://www.ihg.com/intercontinental/hotels/us/en/new-york/nychc/hoteldetail",
  "booking_url": "https://www.ihg.com/intercontinental/hotels/us/en/new-york/nychc/hoteldetail",
  "detected_by": "url",
  "discovery_pages": 0,
  "wrapper_resolutions": 0,
  "discovery_cache_hit": false,
  "discovery_elapsed_s": 0.001,
  "collection_id": "ratecol_0123456789abcdef0123456789abcdef",
  "observed_at": "2026-08-07T01:23:45.678Z",
  "property_ref": "NYCHC",
  "check_in": "2027-02-11",
  "check_out": "2027-02-12",
  "nights": 1,
  "currency": "USD",
  "sold_out": false,
  "cheapest_rate": 631,
  "cheapest_member_rate": 612.07,
  "member_rates_returned": 2,
  "rooms_returned": 1,
  "elapsed_s": 1,
  "rooms": [
    {
      "name": "Premium Room",
      "code": "CDXG",
      "max_occupancy": 2,
      "quantity": 9,
      "available": true,
      "cheapest_rate": 631,
      "rates": [
        {
          "currency": "USD",
          "rate_plan": "Reward Nights",
          "rate_code": "IVANI",
          "rate_category": "points",
          "rate_category_source": "brand_flag",
          "refundable": true,
          "access_type": "points",
          "loyalty_points": 123000,
          "loyalty_program": "IHG One Rewards",
          "points": 123000,
          "points_basis": "stay",
          "is_discounted": false
        },
        {
          "price": 79,
          "currency": "USD",
          "rate_plan": "Reward Nights (points + cash)",
          "rate_code": "IVANI",
          "rate_category": "points",
          "rate_category_source": "brand_flag",
          "refundable": true,
          "access_type": "points_and_cash",
          "loyalty_points": 113000,
          "loyalty_cash": 79,
          "loyalty_program": "IHG One Rewards",
          "points": 113000,
          "points_basis": "stay",
          "cash_component": 79,
          "is_discounted": false
        }
      ]
    }
  ],
  "loyalty": {
    "program": "IHG One Rewards",
    "exposed_unauthenticated": {
      "program": "IHG One Rewards",
      "member": true,
      "points": true,
      "points_and_cash": true,
      "login_required_for": [],
      "notes": "Reward Nights (IVANI) carry pointsOnly and pointsCash options in the anonymous availability API."
    },
    "rates_by_access_type": {
      "public": 2,
      "member": 2,
      "points": 1,
      "points_and_cash": 2,
      "corporate": 0,
      "qualified": 0
    },
    "public_best": {
      "room": "Premium Room",
      "room_code": "CDXG",
      "rate_plan": "Early Saver Rate",
      "price": 631,
      "currency": "USD"
    },
    "member_best": {
      "room": "Premium Room",
      "room_code": "CDXG",
      "rate_plan": "Early Saver Member Exclusive",
      "price": 612.07,
      "currency": "USD",
      "discount_vs_public": {
        "amount": 18.93,
        "percent": 3,
        "public_price": 631,
        "public_rate_plan": "Early Saver Rate",
        "currency": "USD",
        "basis": "room_cheapest_public"
      }
    },
    "points_best": {
      "room": "Premium Room",
      "room_code": "CDXG",
      "rate_plan": "Reward Nights",
      "access_type": "points",
      "points": 123000,
      "points_basis": "stay"
    },
    "points_plus_cash_best": {
      "room": "Premium Room",
      "room_code": "CDXG",
      "rate_plan": "Reward Nights (points + cash)",
      "access_type": "points_and_cash",
      "points": 103000,
      "points_basis": "stay",
      "cash_component": 149,
      "currency": "USD"
    },
    "points_value_cents_per_point": {
      "value": 0.513,
      "unit": "cents_per_point",
      "derivation": "derived",
      "formula": "(public_cash - cash_component) / points * 100",
      "currency": "USD",
      "room": "Premium Room",
      "public_cash": 631,
      "public_rate_plan": "Early Saver Rate",
      "cash_component": 0,
      "points": 123000,
      "points_rate_plan": "Reward Nights",
      "points_access_type": "points",
      "public_price_basis": "stay"
    }
  }
}

A revenue tool matches rates for 20 hotels over the next 7 nights every morning

Illustrative scenario, not a customer

CallPer dayCredits eachCredits a day
Official-site rates, 20 hotels × 7 nights1404560
Booking.com rooms and plans, 20 hotels × 7 nights140121,680
Credits a month
67,200
Fits on
Growth
Plan price
$149 a month

30 days a month. Failed and empty requests cost nothing, so a bad day costs less. Compare plans

Which plans carry a rate code?

Chain official sites return the brand's own rate_code; OTA plans carry the site's plan code where it shows one. Every plan gets a rate_category, and rate_category_source says whether it came from the brand's flag or the plan's name.

What are qualified rates?

Eligibility-restricted rates (AAA, senior, government) that hotel engines such as Hilton, Marriott and Radisson offer. Ask for them with qualified_rates; they come back with rate_category "qualified" and never count as the public price.

Are member prices counted as the cheapest rate?

No. Member and loyalty prices are labelled and kept out of cheapest_rate, so the headline price stays comparable with what a signed-out guest sees on an OTA.

What if a plan cannot be classified?

It comes back as rate_category "unknown", so you can leave it out of comparisons instead of guessing.

Start with 50 free calls

Create an account and verify your email: your own API keys and a free trial of 50 calls or 14 days, whichever ends first, no card needed. Then buy a credit pack from $15 or pick a plan from $49 a month.