# Webmotors Scraper (`dami_studio/webmotors-scraper`) Actor

Webmotors scraper for Brazilian car listings. Make and model with the site's filters, or pasted links: version, both years, price and its FIPE percentage, mileage, gearbox, fuel, colour, body, features, seller type, town and photos. $6.50 per 1,000 listings.

- **URL**: https://apify.com/dami_studio/webmotors-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** E-commerce, Business, Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.20 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**Webmotors scraper for a make and model with the site's own filters, or Webmotors search links, one row per Brazilian car listing**: make, model, version, both years, the asking price and where it sits against the FIPE table, mileage, gearbox, fuel, colour, body, the listing's feature list, dealer or private seller, the town, photos and a link.

One search never reaches past 10,000 listings, so a wide search such as every Chevrolet has to be split by price, year or state. Street addresses, postcodes and the phone numbers sellers type into their blurbs are left out on purpose.

| | |
|---|---|
| **Input** | A make and model with filters, or Webmotors search links |
| **Output** | One row per car listing: make, model, version, both years, price and FIPE position, mileage, gearbox, fuel, colour, body, features, seller type, town, photos |
| **Ceiling** | 10,000 listings per search, 50,000 per run |
| **Account needed** | None |
| **Price** | $6.50 per 1,000 listings on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 750 |

### 🔍 What Webmotors Scraper does

Every row comes from the site's own search results. No listing page is opened, so anything that only lives on a car's own page, such as the full options list, the seller's phone or a financing quote, is not here.

`fipePercent` is the field to sort on. Brazil prices used cars against the FIPE table and Webmotors shows each listing's position on it: `105` means the seller asks 5% above FIPE for that exact version and year, and `92` means 8% below.

Listings carry two years, the year built and the model year, and they often differ. Both are in the row, and the year filter works on the model year.

Ask the site for a make it does not know and it answers with every car it has, 353,000 of them. So the run checks that the answer names the make and model you asked for before keeping a row. A typo returns nothing and costs nothing.

Fuel is a filter on the site, not a field on the listing. With the fuel filter set, every row is tagged with it. Without it, the fuel is read from the version text, which names it on about 8 listings in 10, and the rest are `null` rather than guessed.

The street and house number, the CEP and the neighbourhood are dropped, and a private seller gets no dealer name or id. Phone numbers and email addresses in the free text become `[telefone removido]` or `[email removido]`. One typed in an unusual way can still slip through; if you spot one, report it.

### 📋 What data you get from each Webmotors listing

| What you get | Field |
|---|---|
| Webmotors' listing id and the link | `listingId`, `url` |
| Title, make, model and version | `title`, `make`, `model`, `version` |
| Year built and model year | `yearFabrication`, `yearModel` |
| Asking price and its position against the FIPE table | `price`, `currency`, `fipePercent` |
| Mileage, gearbox, and the fuel with where it came from | `mileageKm`, `transmission`, `fuel`, `fuelSource` |
| Colour, body, doors, engine size, power and traction | `color`, `bodyType`, `doors`, `engineSize`, `horsePower`, `traction` |
| Boot, fuel tank and wheel size | `trunkCapacity`, `fuelTankCapacity`, `wheelSize` |
| Armoured, auction history, new or used | `armored`, `hadAuctionHistory`, `condition` |
| The badges the seller ticked, and the seller's blurb | `features`, `description` |
| Dealer or private, the site's seller label, and a dealer's name and id | `sellerType`, `sellerCategory`, `dealerName`, `dealerId` |
| Town and state | `city`, `state` |
| Photos and how many there are | `images`, `imageCount` |
| Which search found it, where in it, and when it was read | `searchUrl`, `page`, `position`, `scrapedAt` |

### ▶️ How to scrape Webmotors listings

1. Open [Webmotors Scraper](https://apify.com/dami_studio/webmotors-scraper) and click **Try for free**.
2. Type a **Make**, and a **Model** if you want one, or paste results pages into **Search links**.
3. Pick any filters from the drop-downs, such as **State**, **Price to (R$)** or **Gearbox**.
4. Set **Maximum listings** and an **Order**.
5. Click **Start**, then export the dataset as CSV, JSON or Excel. Open `RUN_REPORT` if the count looks short.

### 💰 How much does it cost to scrape Webmotors?

**$6.50 per 1,000 listings** on the Free plan. Paid plans pay a little less: $6.40 on Starter, $6.30 on Scale and $6.20 on Business. On the free plan, the $5 Apify gives you each month covers about 750 listings.

Not charged: the sample row, a make, model or filter value the site does not know, a search that finds nothing, cars from outside your search, a car found twice in one run, and a search that could not be loaded. If you set a maximum charge for the run, it stops when the next listing is no longer covered and says so. A maximum that does not cover a single listing stops the run before it searches.

### 📥 What you give it

```json
{
  "make": "Fiat",
  "model": "Argo",
  "state": "São Paulo (SP)",
  "priceTo": 90000,
  "yearFrom": 2022,
  "mileageTo": 60000,
  "transmission": "Automática",
  "sellerType": "Pessoa Física",
  "sort": "price-asc",
  "maxItems": 500
}
```

| Field | Default | What it is |
|---|---|---|
| `make` | none: no form search, and a free sample row unless `searchUrls` is set | The make as Webmotors spells it: Fiat, Volkswagen, Chevrolet, Mercedes-Benz, Caoa Chery. |
| `model` | every model of that make | The model as the site names it: Argo, Onix, Corolla, Compass. It needs a make. |
| `maxItems` | `100` | Listings across every search, 1 to 50,000. The form starts at 50. Each search gets an equal share, and what one does not use passes to the next. |
| `sort` | `relevance` | `relevance`, `year-desc`, `mileage-asc`, `price-asc` or `price-desc`. When there are more cars than your limit, it decides which ones you get. |
| `searchUrls` | none | Up to 10 results pages from webmotors.com.br. A page that names several makes or models brings back all of them. The fields on this form do not apply to a pasted link, and a single car's page is skipped. |
| `state` | the whole country | As the form lists it, such as `São Paulo (SP)`. There is no city filter, but every row carries the town. |
| `priceFrom`, `priceTo` | no bound | Asking price in reais. |
| `yearFrom`, `yearTo` | no bound | Model year. |
| `mileageFrom`, `mileageTo` | no bound | Kilometres. A `mileageTo` of 0 means brand-new cars only. |
| `fuel` | no filter | The site's own values, such as `Gasolina e álcool` for a flex car. |
| `transmission` | no filter | `Automática`, `Manual`, `CVT` and the site's other gearbox names, kept apart the way the site keeps them. |
| `bodyType` | no filter | `Utilitário esportivo` is an SUV and `Perua/SW` an estate. |
| `color` | no filter | The colour the seller picked. `Indefinida` is the site's catch-all. |
| `armored` | no filter | `Sem blindagem` or `Com blindagem`. |
| `sellerType` | no filter | `Loja` for an independent dealer, `Concessionária` for a franchised one, `Pessoa Física` for a private seller. |
| `features` | no filter | Equipment, from the site's own list. |
| `attributes` | no filter | Listing badges such as `Aceita troca` (takes a trade-in), `IPVA pago` or `Alienado` (still under finance). |

### 📤 What you get back

A real row, a private seller whose blurb had a phone number in it:

```json
{
  "listingId": "79971170",
  "title": "FIAT ARGO 1.8 E.TORQ FLEX HGT AT6",
  "make": "FIAT",
  "model": "ARGO",
  "version": "1.8 E.TORQ FLEX HGT AT6",
  "yearFabrication": 2020,
  "yearModel": 2021,
  "price": 77968,
  "currency": "BRL",
  "fipePercent": 100,
  "mileageKm": 36000,
  "transmission": "Automática",
  "fuel": "Gasolina e álcool",
  "fuelSource": "version",
  "color": "Preto",
  "bodyType": "Hatchback",
  "doors": 4,
  "engineSize": "1.8",
  "horsePower": "139 cv",
  "traction": "Dianteira",
  "trunkCapacity": "300 l",
  "fuelTankCapacity": "48 l",
  "wheelSize": "16",
  "armored": false,
  "hadAuctionHistory": false,
  "condition": "used",
  "features": ["Único dono", "IPVA pago", "Licenciado"],
  "description": "Vidro com Insulfime AntiVandalismo / Segredo nos Pneus / Banco de Couro Chamar no Whatsapp [telefone removido]",
  "sellerType": "private",
  "sellerCategory": "Pessoa Física",
  "dealerName": null,
  "dealerId": null,
  "city": "São Paulo",
  "state": "São Paulo (SP)",
  "url": "https://www.webmotors.com.br/comprar/fiat/argo/18-etorq-flex-hgt-at6/4-portas/2020-2021/79971170",
  "images": ["https://image.webmotors.com.br/_fotos/anunciousados/gigante/2026/202609/20260921/fiatargo18etorqflexhgtat6-WMIMAGEM20300903419.jpg"],
  "imageCount": 7,
  "searchUrl": "https://www.webmotors.com.br/carros/estoque/fiat/argo?tipoveiculo=carros&marca1=fiat&modelo1=argo",
  "page": 1,
  "position": 3,
  "scrapedAt": "2026-09-29T13:28:10.357Z"
}
```

| Field | How to read it |
|---|---|
| `fipePercent` | The asking price as a percentage of the FIPE price for that version and year. Can be `null`. |
| `yearFabrication`, `yearModel` | The year built and the model year. |
| `condition` | `used` or `new`. The site has no working new-or-used filter, so filter on this after the run. |
| `fuel`, `fuelSource` | The fuel, and whether it came from your filter or from the version text. |
| `sellerType`, `sellerCategory`, `dealerName`, `dealerId` | Dealer or private, the site's own seller label, and for a dealer only, its trading name and id. |
| `features` | The badges the seller ticked, such as `IPVA pago`. |
| `description` | The seller's blurb, with phone numbers and email addresses replaced. |
| `hadAuctionHistory`, `armored` | Whether the car has been through an auction, and whether it is armoured. |

Some spec fields are blank when the seller left them blank.

### 🧾 Reading the output

| Row | How to spot it | Charged |
|---|---|---|
| A listing | a `listingId`, and no `_sample` or `charged` field | yes |
| The sample row | `_sample: true`, `charged: false`. Only when the run had no make and no usable link | no |
| A note | `_diagnostic: true`, `charged: false`, an `errorCode`, and the `searchUrl` or `parameter` it is about | no |

| `errorCode` | What happened |
|---|---|
| `UNKNOWN_FILTER_VALUE` | A pasted link carried a value the site would ignore: one missing from the site's own list for that filter, a price, year or mileage that is not a plain number, or a single-choice filter given twice. That link was not searched. The row adds the `value` and the `knownValues`. |
| `NOT_SERVED` | Webmotors did not return results for that search this time, or sent back mostly cars of another make or model. There is one per search, also when other searches in the same run brought listings back. Run it again in a few minutes. |
| `NOT_FOUND` | Webmotors has no make or model by that name, so the search brought nothing back. Check the spelling. One per search, like `NOT_SERVED`. |
| `NO_RESULTS` | Webmotors has no listings for that search right now. One per search, like `NOT_SERVED`. |
| `TIME_LIMIT` | The run reached its time limit before any listing came back. `searchUrls` lists the searches it did not read. |
| `COST_LIMIT` | The maximum charge you set for the run does not cover a single listing, so nothing was searched. |
| `UNEXPECTED_ERROR` | The run stopped early on an unexpected error. The results before this row are kept. |

What happened to each search goes in the `RUN_REPORT` record in the run's key-value store: the site's answer, how many listings it holds, pages read and failed, repeats and off-search rows left out, and why the run stopped.

| A search's `status` | What it means |
|---|---|
| `ok`, `no-results`, `not-found` | The site answered. `not-found` is a make or model it does not know. |
| `off-search` | Most of a page was cars of another make or model, so the search was stopped there and nothing was charged for it. On an `ok` search, `stoppedBecause: "off-search"` means it stopped that way after some listings came back. |
| `all-repeats` | Every listing it found had already come back from an earlier search in the same run, so it added none and was charged nothing. |
| Anything else | That search did not load, and nothing was charged for it. |

`stoppedBecause: "site-ceiling"` means a search hit the 10,000 limit.

A run ends as Failed only when something broke on our side. Anything the site or your settings decided ends as Succeeded, with the notes above and an amber status when nothing came back.

### 💡 What people use it for

- Finding cars priced under the market: filter on `fipePercent` below 100, which already allows for the version and year.
- A dealer pricing a trade-in against the live listings of the same version, year and state.
- Watching one model's asking prices week by week with a scheduled run.
- Counting how much of a model is sold by dealers against private sellers, by state.

### 🚧 What it does not do

- **More than 10,000 listings from one search.** Split it by price band, year or state.
- **A new-or-used filter or a city filter.** The site's own versions of both change nothing. Filter on `condition` and `city` after the run.
- **Listing pages.** No full options list, no seller phone, no financing quote.
- **Hand-edited links the site would misread.** Those get a free `UNKNOWN_FILTER_VALUE` row instead of a search. For several colours, join them in one filter with `|`, like `cor=Branco|Preto`. Parameters with no list here, such as the plate ending, go through unchecked.
- **Motorbikes, trucks or anything but cars.**
- **Contact details of any kind.**
- It is not an official Webmotors tool. Dami's Studio is independent and is not affiliated with or endorsed by Webmotors, or by any other company named on this page.

### 🧭 Which car listings scraper do you need?

| If you want | Use |
|---|---|
| Used and new cars across eight European countries | [AutoScout24 Scraper](https://apify.com/dami_studio/autoscout24-scraper) |
| Cars for sale in Brazil, with each price's position against the FIPE table | This one |
| Cars, property and second-hand goods in Israel | [Yad2 Scraper](https://apify.com/dami_studio/yad2-scraper) |
| Classified ads on OLX Brazil, from any search or category page | [OLX Brazil Scraper](https://apify.com/dami_studio/olx-brazil-scraper) |
| A US vehicle's factory specification and open recalls, from its VIN | [VIN Decoder & Recalls API](https://apify.com/dami_studio/vin-decoder-recalls-scraper) |

### ❓ Questions people ask

#### Does it need a Webmotors account or an API key?

No. There is nothing to sign in to.

#### Can I get the seller's phone number?

No, by design.

#### Why is my search capped at 10,000?

That is how deep the site lets any one search go. Split the search by state, price band or model year and run the parts.

#### Can it do motorbikes?

Not at the moment. Webmotors lists them, but this searches cars only.

#### Can I call it from code or connect it to an AI assistant?

The [API tab](https://apify.com/dami_studio/webmotors-scraper/api/python) has code for Python, JavaScript and the CLI.
MCP clients like Claude and ChatGPT use
`https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/webmotors-scraper`; coding assistants can load [our
skill file](https://api.apify.com/v2/key-value-stores/BTBHU3DdiuoF4JOsK/records/apify-classifieds-property-SKILL.md).
All three bill your Apify account at the same price.

#### Is scraping Webmotors legal?

These are public listings, and the run leaves out addresses, postcodes and the phone numbers sellers type in. Rows still carry dealer names and sellers' blurbs, which Brazil's LGPD can cover, so have a reason for collecting them. Apify's write-up on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a fair start, and we are not lawyers.

### 🆘 If something breaks

Open the **Issues** tab on the actor page. Include the run ID, the search you ran, and the `RUN_REPORT` record if you can.

# Actor input Schema

## `make` (type: `string`):

The make as Webmotors spells it: Fiat, Volkswagen, Chevrolet, Mercedes-Benz, Caoa Chery. A make the site doesn't know returns nothing and charges nothing. Leave it empty if you only use search links below.

## `model` (type: `string`):

Optional, and it needs a make above. The model as the site names it: Argo, Onix, Corolla, Compass. A model the site doesn't know returns nothing and charges nothing.

## `maxItems` (type: `integer`):

The most listings returned in one run, across every search. Each one returned is charged once. Repeats are skipped and cost nothing. Webmotors lets a single search reach 10,000 listings; past that, narrow it by price, year or state.

## `sort` (type: `string`):

The order listings are read in. With a limit below the number of listings, this decides which ones you get.

## `searchUrls` (type: `array`):

Or paste up to 10 results pages from webmotors.com.br, with the filters you picked there. One car's page is not a search and is skipped. The fields on this form don't apply to a pasted link.

## `state` (type: `string`):

Only cars sold in this state. Leave it empty for the whole country. There is no city filter on the search this actor uses, but every row carries the town, so you can narrow it afterwards.

## `priceFrom` (type: `integer`):

Lowest asking price, in reais.

## `priceTo` (type: `integer`):

Highest asking price, in reais.

## `yearFrom` (type: `integer`):

Earliest model year. Brazilian listings carry two years, the year built and the model year; this is the model year.

## `yearTo` (type: `integer`):

Latest model year.

## `mileageFrom` (type: `integer`):

Lowest mileage, in kilometres.

## `mileageTo` (type: `integer`):

Highest mileage, in kilometres. Set it to 0 to get only brand-new cars.

## `fuel` (type: `string`):

Flex cars are "Gasolina e álcool". Set this and every row comes back tagged with it; leave it empty and the fuel is read out of the version text instead, which names it on about 8 of every 10 listings.

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

The site keeps CVT, DCT and the other automatics apart, so pick the one you mean.

## `bodyType` (type: `string`):

"Utilitário esportivo" is the site's name for an SUV; "Perua/SW" is an estate.

## `color` (type: `string`):

The colour the seller picked. "Indefinida" is the site's own catch-all.

## `armored` (type: `string`):

Armoured cars are a real slice of the Brazilian market, so the site filters on it.

## `sellerType` (type: `string`):

"Loja" is an independent dealer, "Concessionária" a franchised one, "Pessoa Física" a private seller.

## `features` (type: `array`):

Every item you pick has to be on the car. The list is the site's own, in its own words.

## `attributes` (type: `array`):

The badges sellers put on a listing. "Aceita troca" means they'll take a trade-in, "IPVA pago" that this year's road tax is paid, "Alienado" that the car still has finance on it.

## Actor input object example

```json
{
  "make": "Fiat",
  "model": "Argo",
  "maxItems": 50,
  "sort": "relevance"
}
```

# Actor output Schema

## `results` (type: `string`):

One row per listing: make, model, version, year built and model year, price, the FIPE comparison, mileage, gearbox, fuel, colour, body, features, seller type and town, photos and a link. A search that finds nothing adds no rows.

## `report` (type: `string`):

Each search with what Webmotors answered, how many listings it has, pages read, repeats and off-search rows left out, and why the run stopped.

# 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 = {
    "make": "Fiat",
    "model": "Argo",
    "maxItems": 50,
    "sort": "relevance"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/webmotors-scraper").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 = {
    "make": "Fiat",
    "model": "Argo",
    "maxItems": 50,
    "sort": "relevance",
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/webmotors-scraper").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 '{
  "make": "Fiat",
  "model": "Argo",
  "maxItems": 50,
  "sort": "relevance"
}' |
apify call dami_studio/webmotors-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/webmotors-scraper"
        }
    }
}
```

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/SJtlLDlLeMyxgac0I/builds/YOSaB4pi2xz41NlpR/openapi.json
