# Expedia Brazil Car Rentals Scraper (`xtracto/expedia-brazil-car-rentals`) Actor

Scrape car rental offers from Expedia Brazil (expedia.com.br) in Brazilian Reais. Pick from 24 Brazilian airports and a date range, and get vehicle model, daily rate in R$, rental company and transmission for every available car.

- **URL**: https://apify.com/xtracto/expedia-brazil-car-rentals.md
- **Developed by:** [Farhan Febrian Nauval](https://apify.com/xtracto) (community)
- **Categories:** Travel
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Expedia Brazil Car Rentals Scraper

Get live rental-car prices from **Expedia Brazil** (expedia.com.br) in Brazilian Reais. Pick one or more of 24 Brazilian airports and a date range; every available car comes back with its model, daily rate in R$, rental company and transmission.

### Why use this actor

- **Prices in R$**, from the Brazilian point of sale, through Brazilian IPs — the same offers a customer in Brazil sees
- **24 major Brazilian airports** built in, from Guarulhos and Galeão down to Caxias do Sul — just tick the ones you want
- **Every rental company Expedia lists**: Localiza, Movida, Foco, Alamo, Enterprise, National
- No account, no login, no API key
- One row per car offer, ready to download as JSON, CSV or Excel

A single run over all 24 airports returns roughly **1,300 offers in about 3 minutes**.

### Supported pick-up airports

| | | |
|---|---|---|
| Recife (REC) | São Paulo Congonhas (CGH) | Belo Horizonte (CNF) |
| Curitiba (CWB) | Florianópolis (FLN) | Fortaleza (FOR) |
| Rio de Janeiro Galeão (GIG) | São Paulo Guarulhos (GRU) | João Pessoa (JPA) |
| Maceió (MCZ) | Natal (NAT) | Porto Alegre (POA) |
| Salvador (SSA) | Campinas (VCP) | Goiânia (GYN) |
| Porto Seguro (BPS) | Campo Grande (CGR) | Vitória (VIX) |
| Aracaju (AJU) | Navegantes (NVT) | Rio de Janeiro Santos Dumont (SDU) |
| Canoas (QNS) | Caxias do Sul (CXJ) | Ribeirão Preto (RAO) |

Leave the list empty to search all of them at once.

### Input

```json
{
  "pickupLocations": ["REC", "GRU"],
  "startDate": "2026-09-07 10:30:00",
  "endDate": "2026-09-08 10:30:00",
  "maxResultsPerSearch": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "BR"
  }
}
```

| Field | Type | Description |
|---|---|---|
| `pickupLocations` | array | Airports to search, as IATA codes. Empty = all 24. Also accepts a raw Expedia region id. |
| `startDate` | string | Pick-up date and time, `YYYY-MM-DD HH:MM:SS`. Required. |
| `endDate` | string | Drop-off date and time, `YYYY-MM-DD HH:MM:SS`. Must be after `startDate`. Required. |
| `maxResultsPerSearch` | integer | Cap offers per airport. `0` = every offer. |
| `sessionHuntAttempts` | integer | How hard to work at getting past Expedia's bot protection. Default 80; raise it if runs fail to start. |
| `pageCount` | integer | Offers requested per call. Default 100, which covers a Brazilian airport's whole inventory. |
| `currency` / `locale` | string | Default `BRL` / `pt_BR`. Leave them alone unless you know why you're changing them. |
| `proxyConfiguration` | object | **Brazilian residential proxy required.** Default is already set correctly. |

Expedia's pickers only offer `:00` and `:30` slots, so times are snapped to the nearest half hour.

### Output

One row per car offer. The four headline fields are flat and always populated:

```json
{
  "vehicleModel": "Volkswagen Polo, Fiat Argo or similar",
  "dailyRate": 154.02,
  "rentalCompany": "Foco",
  "transmission": "Manual",

  "currency": "BRL",
  "dailyRateFormatted": "R$ 154,02",
  "dailyRateBasis": "total_divided_by_days",
  "totalPrice": 154.02,
  "totalPriceFormatted": "R$ 154",
  "priceIncludesTaxesAndFees": true,

  "vehicleCategory": "Compacto",
  "passengerCapacity": "5",
  "doors": "4/5 portas",
  "mileage": "Quilometragem ilimitada",
  "airConditioning": true,
  "vehicleImageUrl": "https://mediaim.expedia.com/cars/...jpg",
  "rentalCompanyLogoUrl": "https://mediaim.expedia.com/cars/logos/FO.png",

  "pickupLocation": "Aeroporto de Recife",
  "pickupAirportCode": "REC",
  "pickupCounter": "Balcão e carro no terminal",
  "startDate": "2026-09-07 10:30:00",
  "endDate": "2026-09-08 10:30:00",
  "rentalDays": 1,

  "rating": "82%",
  "ratingLabel": "Bom",
  "badges": ["Oferta incrível"],
  "bookingUrl": "https://www.expedia.com.br/carsearch/details?...",

  "recordType": "CAR_OFFER",
  "_input": "Aeroporto de Recife",
  "_source": "S1-graphql",
  "_scrapedAt": "2026-08-25T14:09:17Z"
}
```

| Field | Description |
|---|---|
| `vehicleModel` | The car, or the "X, Y or similar" group Expedia guarantees |
| `dailyRate` | Price per day in R$ (see the note below) |
| `rentalCompany` | Localiza, Movida, Foco, Alamo, Enterprise, National… |
| `transmission` | `Automatic` or `Manual`, normalised from Expedia's Portuguese label (kept verbatim in `transmissionRaw`) |
| `totalPrice` | Full rental price for the whole period, taxes and fees included |
| `bookingUrl` | Direct link to book this exact offer on Expedia |

Expedia's own nested objects (`vehicle`, `vendor`, `priceSummary`, `tripLocations`, `review`, `offerBadges`, `infositeURL`) are passed through unchanged alongside these, so anything not promoted above is still there.

#### How the daily rate is calculated

Expedia Brazil quotes the **rental total**, not a per-day figure — its results header reads *"O valor total inclui impostos e taxas"* (the total includes taxes and fees). So `dailyRate` is `totalPrice ÷ rentalDays`, and `dailyRateBasis` records that. For a one-day rental the two are identical: a search for 7→8 September at Recife returns R$ 154 as both the total and the daily rate.

If Expedia ever starts publishing a real per-day price on the Brazilian site, the actor uses it directly and `dailyRateBasis` becomes `expedia_lead_price`.

### Notes and limits

- **A Brazilian residential proxy is required** and configured by default. Expedia's bot protection accepts only a small share of residential IPs, so the actor tries a series of them at the start of each run until one is accepted — this is why a run takes a minute or two to produce its first result. Once through, that one session covers every airport in the run.
- **Every airport always produces a row.** If one returns nothing, you get a `SEARCH_STATUS` row with an `_error` explaining why (`no_availability`, `empty_result`, `blocked_by_akamai`) rather than a silently short dataset.
- Some airports genuinely have no rental desks. **Canoas (QNS)** returns Expedia's own "no cars available at this location" message for every date tested — that is real, not a scraping failure.
- Inventory per airport is small (typically 30–75 cars) and one search captures all of it.
- Prices and availability are point-in-time and change constantly.

### Related actors

Part of an Expedia suite — one actor per travel type: Cars, Stays, Flights, Packages, Cruises.

# Actor input Schema

## `pickupLocations` (type: `array`):

Brazilian pick-up airports to search. Leave the list empty to search all 24. Values are IATA codes; the actor also accepts a raw Expedia region id (dpln) if you need an airport that is not on this list.

## `startDate` (type: `string`):

Pick-up date and time in YYYY-MM-DD HH:MM:SS format, e.g. 2026-09-07 10:30:00. Use this for a single rental period; for many periods in one run use Date ranges below. Expedia only offers :00 and :30 slots, so the time is snapped to the nearest half hour.

## `endDate` (type: `string`):

Drop-off date and time in YYYY-MM-DD HH:MM:SS format, e.g. 2026-09-08 10:30:00. Must be after the start date. Ignored when Date ranges is set.

## `dateRanges` (type: `array`):

Search several rental periods in a single run. Every airport is searched for every period listed here, and they all share one warm-up, which makes this far cheaper than one run per period. Format: \[{"startDate": "2026-09-07 10:30:00", "endDate": "2026-09-08 10:30:00"}, {"startDate": "2026-09-14 10:30:00", "endDate": "2026-09-21 10:30:00"}]. Overrides the single Start date / End date fields above.

## `maxResultsPerSearch` (type: `integer`):

Cap the number of car offers emitted per airport. 0 = no cap (every offer Expedia lists).

## `sessionHuntAttempts` (type: `integer`):

How many Brazilian exit IPs to try before giving up on finding one Expedia's bot protection accepts. Only about 1 in 20 residential IPs gets through, but a single accepted one covers the whole run, so the default of 80 leaves a wide margin. Raise it if runs fail to start; each attempt costs a second or two.

## `pageCount` (type: `integer`):

Expedia's selPageCount. 100 returns a Brazilian airport's full inventory in a single call, so there is normally nothing to paginate.

## `currency` (type: `string`):

Currency for prices. Keep BRL (R$) — the Brazilian point of sale is what this actor is built and tested for.

## `locale` (type: `string`):

Expedia locale. Keep pt\_BR — vehicle attributes such as the transmission chip are read from the Portuguese labels.

## `proxyConfiguration` (type: `object`):

Must be a Brazilian residential proxy. Expedia picks the point of sale from the exit IP: from a non-Brazilian IP it switches away from expedia.com.br pricing and returns a different currency instead of R$.

## Actor input object example

```json
{
  "pickupLocations": [
    "REC"
  ],
  "startDate": "2026-09-07 10:30:00",
  "endDate": "2026-09-08 10:30:00",
  "dateRanges": [
    {
      "startDate": "2026-09-07 10:30:00",
      "endDate": "2026-09-08 10:30:00"
    },
    {
      "startDate": "2026-09-14 10:30:00",
      "endDate": "2026-09-21 10:30:00"
    }
  ],
  "maxResultsPerSearch": 0,
  "sessionHuntAttempts": 80,
  "pageCount": 100,
  "currency": "BRL",
  "locale": "pt_BR",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BR"
  }
}
```

# Actor output Schema

## `vehicleModel` (type: `string`):

Car model, cleaned of the 'or similar' suffix Expedia appends.

## `dailyRate` (type: `string`):

Price per rental day. Expedia Brazil publishes a total, so this is normally the total divided by the billable days - see dailyRateBasis. Numeric value.

## `dailyRateFormatted` (type: `string`):

Daily rate rendered as Brazilian currency, e.g. R$ 129,90.

## `dailyRateBasis` (type: `string`):

How the daily rate was derived: total\_divided\_by\_days, expedia\_lead\_price, or unavailable.

## `rentalCompany` (type: `string`):

Supplier offering the car, e.g. Localiza, Movida, Unidas.

## `transmission` (type: `string`):

Normalised transmission type - Automatic or Manual.

## `currency` (type: `string`):

ISO currency code of the prices, normally BRL.

## `totalPrice` (type: `string`):

Total cost for the whole rental period, taxes and fees included. Numeric value.

## `totalPriceFormatted` (type: `string`):

Total cost as Expedia displays it.

## `priceIncludesTaxesAndFees` (type: `string`):

Always true on the Brazilian storefront, which quotes tax-inclusive totals. Boolean value.

## `vehicleCategory` (type: `string`):

Expedia's size class, e.g. Economy, Compact, SUV.

## `vehicleModelRaw` (type: `string`):

Model string exactly as Expedia returned it, before cleaning.

## `transmissionRaw` (type: `string`):

Transmission text exactly as Expedia returned it, in Portuguese.

## `passengerCapacity` (type: `string`):

Seat count as listed on the offer.

## `doors` (type: `string`):

Number of doors as listed on the offer.

## `mileage` (type: `string`):

Mileage terms, e.g. unlimited kilometres.

## `airConditioning` (type: `string`):

Air-conditioning note when the offer states one.

## `otherAttributes` (type: `string`):

Remaining vehicle attributes Expedia lists that do not map to a dedicated field.

## `vehicleImageUrl` (type: `string`):

Photo of the vehicle class.

## `rentalCompanyLogoUrl` (type: `string`):

Supplier logo image.

## `pickupLocation` (type: `string`):

The airport input this row came from.

## `pickupAirportCode` (type: `string`):

IATA code of the pick-up airport, e.g. GRU, GIG, BSB.

## `pickupRegionId` (type: `string`):

Expedia's internal region identifier used for the search.

## `pickupLocationName` (type: `string`):

Full airport name as Expedia resolved it.

## `pickupCounter` (type: `string`):

Where the car is collected, e.g. at the terminal or via shuttle.

## `startDate` (type: `string`):

Pick-up date and time used for the search.

## `endDate` (type: `string`):

Drop-off date and time used for the search.

## `rentalDays` (type: `string`):

Billable days. Expedia charges a started 24-hour block as a full day, so this is rounded up. Whole number.

## `searchUrl` (type: `string`):

The Expedia search page matching this query.

## `bookingUrl` (type: `string`):

Direct link to this specific offer on Expedia.

## `rating` (type: `string`):

Supplier rating shown on the offer, when present. Numeric value.

## `ratingLabel` (type: `string`):

Wording Expedia pairs with the rating, e.g. Bom, Muito bom.

## `badges` (type: `string`):

Promotional labels on the offer, e.g. free cancellation. List of values.

## `recordType` (type: `string`):

CAR\_OFFER for a real offer, SEARCH\_STATUS for a diagnostic row explaining why a search produced no offers.

## `_error` (type: `string`):

Set only on SEARCH\_STATUS rows - why that search returned nothing.

## `_errorDetail` (type: `string`):

Extra context for the error, when available.

## `_input` (type: `string`):

The airport input that produced this row.

## `_source` (type: `string`):

Which extraction path produced the row.

## `_scrapedAt` (type: `string`):

UTC timestamp of the scrape, ISO 8601.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "pickupLocations": [
        "REC"
    ],
    "startDate": "2026-09-07 10:30:00",
    "endDate": "2026-09-08 10:30:00",
    "dateRanges": [
        {
            "startDate": "2026-09-07 10:30:00",
            "endDate": "2026-09-08 10:30:00"
        },
        {
            "startDate": "2026-09-14 10:30:00",
            "endDate": "2026-09-21 10:30:00"
        }
    ],
    "currency": "BRL",
    "locale": "pt_BR"
};

// Run the Actor and wait for it to finish
const run = await client.actor("xtracto/expedia-brazil-car-rentals").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "pickupLocations": ["REC"],
    "startDate": "2026-09-07 10:30:00",
    "endDate": "2026-09-08 10:30:00",
    "dateRanges": [
        {
            "startDate": "2026-09-07 10:30:00",
            "endDate": "2026-09-08 10:30:00",
        },
        {
            "startDate": "2026-09-14 10:30:00",
            "endDate": "2026-09-21 10:30:00",
        },
    ],
    "currency": "BRL",
    "locale": "pt_BR",
}

# Run the Actor and wait for it to finish
run = client.actor("xtracto/expedia-brazil-car-rentals").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "pickupLocations": [
    "REC"
  ],
  "startDate": "2026-09-07 10:30:00",
  "endDate": "2026-09-08 10:30:00",
  "dateRanges": [
    {
      "startDate": "2026-09-07 10:30:00",
      "endDate": "2026-09-08 10:30:00"
    },
    {
      "startDate": "2026-09-14 10:30:00",
      "endDate": "2026-09-21 10:30:00"
    }
  ],
  "currency": "BRL",
  "locale": "pt_BR"
}' |
apify call xtracto/expedia-brazil-car-rentals --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xtracto/expedia-brazil-car-rentals"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/V2GSq84lR35dWVLPi/builds/9EKPcas6So6nkB8rH/openapi.json
