Skip to content
Expedia

Expedia rates

Expedia's own rooms and rate plans.

POST/v1/ota/expedia
8 credits

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

POSThttps://api.scrapercompany.com/v1/ota/expedia

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

Body

JSON object. Unknown fields are rejected with 422.

  • property_idstringrequiredmin 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_instring (date)required

    First night of the stay, YYYY-MM-DD.

  • check_outstring (date) | null

    Departure date. An alternative to nights — if both are given, this wins.

  • nightsintegerdefault 1min 1, max 28

    Length of stay. Ignored when check_out is supplied.

  • adultsintegerdefault 2min 1, max 8

    Adults in the room.

  • marketstringdefault 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.

    One ofCAUS

  • roomsbooleandefault true

    Return every room type and rate plan (~50-250 KB upstream). False returns the headline price only (~6 KB). Same credit cost.

Example request

curl -X POST "https://api.scrapercompany.com/v1/ota/expedia" \
  -H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "property_id": "12570",
    "check_in": "2026-11-30",
    "nights": 1,
    "adults": 2,
    "market": "US"
  }'

Response

200 — Headline plus rooms and rate plans. `total` is upstream (taxes and fees included); `taxes_and_fees` is derived and says so in its provenance. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).

200 response
{
  "search_parameters": {
    "engine": "expedia_property",
    "property_id": "12570",
    "check_in_date": "2029-04-10",
    "check_out_date": "2029-04-11",
    "adults": 2,
    "market": "US",
    "currency": "USD",
    "rooms": true
  },
  "property": {
    "property_id": "12570",
    "total": 475,
    "price_per_night": 374,
    "basis": "sticky_bar",
    "total_text": "$475",
    "nightly_text": "$374 nightly",
    "currency": "USD",
    "currency_verified": true,
    "available": true,
    "cheapest_total": 475,
    "provenance": {
      "schema_version": 1,
      "observation_id": "rateobs_0123456789abcdef0123456789abcdef",
      "collection_id": "ratecol_0123456789abcdef0123456789abcdef",
      "observed_at": "2026-08-07T01:23:45.678Z",
      "source": "expedia_com",
      "source_kind": "ota_offer",
      "collector": "scrapingme.ota.expedia",
      "source_property_id": "12570",
      "requested_market": "US",
      "requested_currency": "USD",
      "returned_currency": "USD",
      "egress_mode": "direct",
      "price_basis": "stay_headline",
      "derivation": "upstream"
    }
  },
  "rooms": [
    {
      "unit_id": "403873",
      "name": "Room, 1 King Bed",
      "cheapest_total": 635,
      "offers": [
        {
          "plan_id": "266071241",
          "room_type_id": "403873",
          "total": 635,
          "nightly": 509,
          "taxes_and_fees": 126,
          "currency": "USD",
          "total_text": "$635 total",
          "nightly_text": "$509 nightly",
          "taxes_and_fees_included": true,
          "payment_model": "PAY_NOW",
          "hotel_collect": false,
          "member_only": false,
          "refundable": false,
          "cancellation_text": "Non-Refundable",
          "extras_text": "No extras",
          "strikeout_text": "",
          "inventory_type": "MERCHANT",
          "business_model": "EXPEDIA_COLLECT",
          "messages": [],
          "provenance": {
            "schema_version": 1,
            "observation_id": "rateobs_0123456789abcdef0123456789abcdef",
            "collection_id": "ratecol_0123456789abcdef0123456789abcdef",
            "observed_at": "2026-08-07T01:23:45.678Z",
            "source": "expedia_com",
            "source_kind": "ota_rate_plan",
            "collector": "scrapingme.ota.expedia",
            "source_property_id": "12570",
            "requested_market": "US",
            "requested_currency": "USD",
            "returned_currency": "USD",
            "egress_mode": "direct",
            "price_basis": "stay_total_including_taxes_and_fees",
            "derivation": "upstream",
            "upstream_rate_id": "266071241"
          },
          "taxes_and_fees_provenance": {
            "schema_version": 1,
            "observation_id": "rateobs_0123456789abcdef0123456789abcdef",
            "collection_id": "ratecol_0123456789abcdef0123456789abcdef",
            "observed_at": "2026-08-07T01:23:45.678Z",
            "source": "expedia_com",
            "source_kind": "ota_rate_plan",
            "collector": "scrapingme.ota.expedia",
            "source_property_id": "12570",
            "requested_market": "US",
            "requested_currency": "USD",
            "returned_currency": "USD",
            "egress_mode": "direct",
            "price_basis": "taxes_and_fees_combined",
            "derivation": "total_minus_nightly_times_nights",
            "upstream_rate_id": "266071241"
          }
        },
        {
          "plan_id": "266071239",
          "room_type_id": "403873",
          "total": 742,
          "nightly": 599,
          "taxes_and_fees": 143,
          "currency": "USD",
          "total_text": "$742 total",
          "nightly_text": "$599 nightly",
          "taxes_and_fees_included": true,
          "payment_model": "PAY_LATER",
          "hotel_collect": true,
          "member_only": false,
          "refundable": true,
          "cancellation_text": "Fully refundable before Nov 14",
          "extras_text": "No extras",
          "strikeout_text": "",
          "inventory_type": "DIRECT_AGENCY",
          "business_model": "HOTEL_COLLECT",
          "messages": [],
          "provenance": {
            "schema_version": 1,
            "observation_id": "rateobs_0123456789abcdef0123456789abcdef",
            "collection_id": "ratecol_0123456789abcdef0123456789abcdef",
            "observed_at": "2026-08-07T01:23:45.678Z",
            "source": "expedia_com",
            "source_kind": "ota_rate_plan",
            "collector": "scrapingme.ota.expedia",
            "source_property_id": "12570",
            "requested_market": "US",
            "requested_currency": "USD",
            "returned_currency": "USD",
            "egress_mode": "direct",
            "price_basis": "stay_total_including_taxes_and_fees",
            "derivation": "upstream",
            "upstream_rate_id": "266071239"
          }
        }
      ]
    }
  ],
  "meta": {
    "source": "expedia",
    "nights": 1,
    "wire_bytes": 181597,
    "elapsed_s": 0.62,
    "room_types": 37,
    "offers": 149,
    "egress_mode": "direct",
    "comparable_across_markets": false,
    "collection_id": "ratecol_0123456789abcdef0123456789abcdef",
    "observed_at": "2026-08-07T01:23:45.678Z"
  }
}

Response fields

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

  • search_parametersobjectrequired
    Show 8 child fields
    • search_parameters.enginestringrequired

      One ofexpedia_property

    • search_parameters.property_idstringrequired
    • search_parameters.check_in_datestring (date)required
    • search_parameters.check_out_datestring (date)required
    • search_parameters.adultsintegerrequired
    • search_parameters.marketstringrequired

      US or CA.

    • search_parameters.currencystringrequired

      The market's currency (USD for US, CAD for CA).

    • search_parameters.roomsbooleanrequired

      Whether room types and rate plans were requested.

  • propertyobjectrequired
    Show 14 child fields
    • property.property_idstringrequired
    • property.totalnumber | nullrequired

      Headline stay total for all nights; see basis and taxes_and_fees_included. Null when nothing priced.

    • property.price_per_nightnumber | nullrequired

      Headline nightly price, before taxes and fees (Expedia rounds it to whole units).

    • property.basisstring | nullrequired

      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.

      One ofsticky_barcheapest_offer

    • property.total_textstringrequired

      Headline total as displayed; empty when not shown.

    • property.nightly_textstringrequired

      Headline nightly price as displayed; empty when not shown.

    • property.taxes_and_fees_includedboolean | nullrequired

      True when the headline total is labelled "with taxes and fees"; null when no such label was shown.

    • property.fees_includedboolean | nullrequired

      True when the headline total is labelled "All fees included"; null when no such label was shown.

    • property.currencystringrequired

      Currency the point-of-sale actually priced in.

    • property.currency_verifiedbooleanrequired

      Whether currency equals the market's currency.

    • property.availablebooleanrequired

      False when nothing is bookable for this stay as asked.

    • property.unavailable_reasonstring | nullrequired

      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_totalnumber | nullrequired

      Lowest offer total across rooms; null when rooms was false or no offer priced.

    • property.provenanceobjectrequired

      Where, when and how one normalized price was observed.

      Show 15 child fields
      • property.provenance.schema_versionintegerrequired

        Provenance schema version (currently 1).

      • property.provenance.observation_idstringrequired

        Deterministic id of this price observation (rateobs_...).

      • property.provenance.collection_idstringrequired

        Id shared by every price from one upstream fetch (ratecol_...).

      • property.provenance.observed_atstringrequired

        UTC observation time, ISO-8601.

      • property.provenance.sourcestringrequired

        Upstream source, e.g. google_hotels_calendar.

      • property.provenance.source_kindstringrequired

        Kind of source, e.g. calendar, offer, ota_calendar, official.

      • property.provenance.collectorstringrequired

        Identifier of the collector that produced the price.

      • property.provenance.source_property_idstringrequired

        Property identifier at the source.

      • property.provenance.requested_marketstring | nullrequired
      • property.provenance.requested_currencystring | nullrequired
      • property.provenance.returned_currencystring | nullrequired
      • property.provenance.egress_modestringrequired

        How the request reached the source, e.g. direct.

      • property.provenance.price_basisstringrequired

        What the price represents, e.g. room_base_before_taxes_and_fees.

      • property.provenance.derivationstringrequired

        How the figure was derived, e.g. normalized_upstream.

      • property.provenance.upstream_rate_idstring | nullrequired

        Source-native rate/room id when available.

  • roomsarray of objectrequired

    Every room type with its offers. Empty when the request set rooms: false.

    Show 4 child fields
    • rooms[].unit_idstringrequired

      Room type id. A vacation rental listed on Expedia is one room with unit_id = property_id and name entire unit.

    • rooms[].namestringrequired

      Room name as displayed, e.g. Room, 1 King Bed.

    • rooms[].cheapest_totalnumber | nullrequired

      Lowest total among this room's offers; null when none priced.

    • rooms[].offersarray of objectrequired
      Show 23 child fields
      • rooms[].offers[].plan_idstringrequired

        Expedia rate-plan id.

      • rooms[].offers[].room_type_idstringrequired
      • rooms[].offers[].totalnumber | nullrequired

        Stay total for all nights, as the source states it; taxes_and_fees_included / fees_included repeat its label. Null when the plan carried no price.

      • rooms[].offers[].nightlynumber | nullrequired

        Average nightly price before taxes and fees; Expedia rounds it to whole units.

      • rooms[].offers[].taxes_and_feesnumber | nullrequired

        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.

      • rooms[].offers[].currencystringrequired

        ISO 4217 code read back from the reply.

      • rooms[].offers[].total_textstringrequired

        Total as displayed, e.g. $635 total.

      • rooms[].offers[].nightly_textstringrequired

        Nightly price as displayed, e.g. $509 nightly.

      • rooms[].offers[].taxes_and_fees_includedboolean | nullrequired

        True when the source labels the total "Total with taxes and fees". Null means no such label was shown, not that taxes are excluded.

      • rooms[].offers[].fees_includedboolean | nullrequired

        True when the source labels the total "All fees included". Null means no such label was shown.

      • rooms[].offers[].payment_modelstringrequired

        PAY_NOW, PAY_LATER or PAY_LATER_WITH_DEPOSIT; empty when not stated. A plan sold both ways is two offers.

        One ofPAY_NOWPAY_LATERPAY_LATER_WITH_DEPOSIT

      • rooms[].offers[].hotel_collectboolean | nullrequired

        True when the property collects payment; null when not stated.

      • rooms[].offers[].member_onlybooleanrequired

        True when booking the plan requires signing in as a member.

      • rooms[].offers[].refundableboolean | nullrequired

        Tri-state, from the room card's cancellation option: true = refundable / free cancellation, false = non-refundable, null = not stated (not the same as non-refundable).

      • rooms[].offers[].cancellation_textstringrequired

        Cancellation option as displayed, e.g. Fully refundable before Nov 14; for display only, use refundable. Empty when not stated.

      • rooms[].offers[].extrasstring | nullrequired

        Add-on code, e.g. breakfast, breakfast-for-two; null for no extras or when not stated.

      • rooms[].offers[].extras_textstringrequired

        Add-on as displayed, e.g. No extras; empty when not stated.

      • rooms[].offers[].strikeout_textstringrequired

        Struck-through comparison price as displayed; empty when none.

      • rooms[].offers[].inventory_typestringrequired

        Source inventory type, e.g. MERCHANT, TRIPCOM, DIRECT_AGENCY, VRBO; empty when not stated.

      • rooms[].offers[].business_modelstringrequired

        EXPEDIA_COLLECT or HOTEL_COLLECT; empty when not stated.

      • rooms[].offers[].messagesarray of stringrequired

        Highlighted plan messages, e.g. Reserve now, pay deposit; usually empty for hotel rooms.

      • rooms[].offers[].provenanceobjectrequired

        Where, when and how one normalized price was observed.

      • rooms[].offers[].taxes_and_fees_provenanceobject | nullrequired

        Provenance of taxes_and_fees (price_basis: taxes_and_fees_combined, derivation: total_minus_nightly_times_nights); null when taxes_and_fees is null.

  • metaobjectrequired
    Show 10 child fields
    • meta.sourcestringrequired

      One ofexpedia

    • meta.collection_idstringrequired
    • meta.observed_atstringrequired
    • meta.nightsintegerrequired
    • meta.wire_bytesintegerrequired

      Bytes received from the source.

    • meta.elapsed_snumberrequired
    • meta.egress_modestringrequired

      How the request was routed: direct or proxy.

      One ofdirectproxy

    • meta.room_typesintegerrequired

      0 when rooms was false.

    • meta.offersintegerrequired

      Offers across all rooms; 0 when rooms was false.

    • meta.comparable_across_marketsbooleanrequired

      Always false: the display basis differs by market.

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
404Not Found

The property, stay, job or record was not found.

{"detail":"job not found"}
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
503Service Unavailable

Temporarily unavailable: a dependency of this endpoint is down, or the upstream source changed its contract. Retry later.

{"detail":"database unavailable: OperationalError"}
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

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