# Mercado Livre Brazil - Deals, Prices, Sellers & Product Videos (`abotapi/mercadolivre-com-br-scraper`) Actor

Scrape Mercado Livre Brazil's best-sellers, category and product-video feeds without login. Extract prices, discounts, instalments, sold counts, shipping, sellers, images and videos. Category mode auto-pages the app's home tabs. Keyword search is sign-in gated.

- **URL**: https://apify.com/abotapi/mercadolivre-com-br-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Features:** Limited permissions
- **Stats:** 133 total users, 39 monthly users, 68.2% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.10 / 1,000 product results

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

## Mercado Livre Brazil Scraper: Deals, Prices, Sellers and Product Videos

Mercado Livre Brazil Scraper turns Mercado Livre Brazil (mercadolivre.com.br), Latin America's largest online marketplace, into structured product data. The default category mode walks the marketplace's best-sellers and category feeds with auto-paging, no login needed. Every product comes back with its price, old price, discount percentage, sold counts, shipping signals, images and sellers. A video mode returns the marketplace's product-clip feed with playable video URLs, view counts, prices and discounts. Export to JSON, CSV or Excel, pull the results through the API, or schedule the actor to track only what changed.

### Why This Scraper?

- **Auto-paging category feeds.** Walk every tab the app's home page shows (Tudo, Moda, Beleza, Celulares, Veículos, Supermercado, Lar, Computação, Televisores, Tv, Primeira Compra) with continuous auto-paging. The feed keeps serving fresh products page after page, just set max products.
- **Sold counts and shipping signals.** Every card carries its marketplace sold count, free-shipping flag, FULL badge and coupon percentage where present.
- **Incremental mode.** Schedule the actor and only pay for new and changed products; unchanged rows are suppressed automatically.
- **Product videos included.** A dedicated video mode returns the marketplace's product-clip feed: playable video URLs, view counts, prices, discounts and seller names for every clip.
- **Clean, honest output.** Every product carries its marketplace id, canonical URL, prices, discount percentage, sold counts, shipping signals and the seller's details. The dataset schema declares every field the Output tab renders.

### Use Cases

- **Price monitoring:** track best-sellers and category feeds on a schedule to spot price drops and discount trends.
- **Market research:** walk category feeds across the app's tabs to see what's actually selling.
- **Competitive analysis:** extract sold counts, discounts and shipping signals to benchmark sellers and products.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live record.

| Field | Example | Source |
|---|---|---|
| `itemId` / `productId` | `"MLB50196682"` / `"MLB12345678"` | every product |
| `title` | `"Sony PlayStation Store Gift Card R$ 150"` | category mode |
| `price` / `originalPrice` / `discountPct` | `150.0` / `199.0` / `25` | when the card carries them |
| `currency` | `"BRL"` | every product |
| `soldText` | `"+5mil"`, `"+1000"` | best-sellers cards |
| `installmentsText` | `"5x R$ 30 sem juros"` | when the card carries them |
| `freeShipping` / `full` | `true` | when present |
| `couponPct` | `15` | coupon-eligible products |
| `shippedFrom` | `"Internacional"` | cross-border products |
| `sellerId` / `officialStoreId` / `logisticType` | `3339513751` / `307542` / `"fulfillment"` | merged from the home feed |
| `categoryId` / `categoryIdPath` / `domainId` / `vertical` | `"MLB271772"` / `["MLB117798"]` / `"MLB-AIR_CONDITIONERS"` / `"CORE"` | merged from the home feed |
| `imageUrl` / `videoUrl` | `https://http2.mlstatic.com/...webp` | every product |
| `bestSeller` / `lightningOffer` | `true` | badges on the card |
| `catalogListing` / `catalogProductId` | `true` / `"MLB12345678"` | catalog products |
| `sellerName` | `"COMERCIAL ELETRO"` | video mode |
| `viewsText` / `durationSec` | `"9.406.217 de visualizações"` / `55` | video mode |
| `couponPct` / `shippedFrom` | `15` / `"Internacional"` | when present |
| `viewsText` / `durationSec` | `"9.406.217 de visualizações"` / `55` | video mode |

### How to Use

1. Pick a **mode**: `category` (default, walks the category feeds with auto-paging) or `videos` (the marketplace's product-clip feed).
2. For category mode, optionally select **categories** to walk (multi-select: Moda, Beleza, Celulares, Veículos, Supermercado, Primeira Compra, Lar, Computação, Televisores, Tv). Empty walks the general Tudo feed.
3. Set **Max products** to cap the run. Auto-paging continues until the cap or the feed runs out of fresh products.

#### Run it from your code

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("n95g7MqAgRI3UrYX0").call(run_input={
    "mode": "category",
    "category": ["moda", "celulares"],
    "maxItems": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('n95g7MqAgRI3UrYX0').call({
    mode: 'category',
    category: ['moda', 'celulares'],
    maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Connection and cost shape

The category and video feeds are served by the marketplace's own mobile API and answer every anonymous visitor, no login, no browser and no rendering engine are needed. Runs use the Residential proxy tier with country Brazil by default. Compute is billed by RAM-seconds: a full 144-product pull costs a fraction of a cent.

#### Output views

The dataset has two views: **Products** (overview) and **Changes** (incremental status and `changedFields`).

#### Resume and recurring updates

**Incremental mode** (`incrementalMode`) is for recurring monitoring of the same category feed. The first run returns everything as `NEW`. Later runs return `NEW` and `UPDATED` products (with `changedFields` naming what moved), and suppress `UNCHANGED` ones unless **Emit unchanged** is on. **Emit expired** additionally tombstones products that a run no longer finds as `EXPIRED`, but only once a run has completely scanned the tracked feed: never when Max products capped it, never after a resume, and never when a run collected nothing. **State key** names a campaign or deliberately shares one. **What is compared:** every returned field except `scrapedAt` (changes on every scrape), `reviews` (the review rows; a new review still moves `reviewCount` and `rating`, which are compared), `searchPosition` (rank on the page), `totalResults` (size of the result set), `searchKeyword` (the query that found the product), `resultType` and `sponsored` (how this run found the row) and `highlight` (the ranking badge such as MAIS VENDIDO), which depend on the page rather than on the product. **Ignore fields when detecting changes** (`ignoreFieldsForChanges`) adds your own exclusions.

### Send results into your apps (MCP connectors)

Connect the actor's dataset to Notion and other MCP-compatible endpoints using the **MCP connectors** input. See the [MCP connectors documentation](https://docs.apify.com/platform/integrations/mcp) for details.

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `category` | `category`: walk the category feeds. `videos`: the product-clip feed. |
| `category` | array (multi-select) | `[]` | Which category tabs to walk, in order. Empty walks the general Tudo feed. |
| `maxItems` | integer | `20` | Hard cap on products returned and billed. |
| `maxPages` | integer | `0` | Optional bound on pages walked per category. 0 = unlimited. |
| `proxy` | object | Residential BR | Apify Proxy configuration. |
| `incrementalMode` | boolean | `false` | Only return new/changed products on scheduled re-runs. |
| `emitUnchanged` | boolean | `false` | Include unchanged products in incremental runs. |
| `emitExpired` | boolean | `false` | Tombstone products no longer found. |
| `stateKey` | string | (empty) | Name a campaign to share or isolate its baseline. |
| `ignoreFieldsForChanges` | array | `[]` | Fields to exclude from change detection. |
| `mcpConnectors` | array | `[]` | MCP connector targets. |
| `notionParentPageUrl` | string | — | Notion parent page for MCP export. |
| `maxNotifyListings` | integer | `50` | Max listings per notification. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live record.

```json
{
  "itemId": "MLB50196682",
  "title": "Sony PlayStation Store Gift Card R$ 150 (Digital)",
  "price": 150,
  "currency": "BRL",
  "soldText": "+50mil",
  "installmentsText": "5x R$ 30 sem juros",
  "imageUrl": "https://http2.mlstatic.com/D_Q_NP_2X_902418-...webp",
  "url": "https://www.mercadolivre.com.br/MLB50196682"
}
```

### Plan Requirement

You pay per product returned, plus one Actor start charge per run. The **Pricing** tab shows the current rates. Use **Max products** to cap the cost of any run.

### FAQ

#### How much does it cost?

You pay per product returned, plus one Actor start charge per run. The **Pricing** tab shows the current rates. Use **Max products** to cap the cost of any run.

#### Is it legal to scrape Mercado Livre?

Scraping publicly available data is generally legal as long as you do not breach any agreements or access data behind authentication. This actor only reads publicly visible product feeds.

#### Can I get only new or changed products on a schedule?

Yes, turn on **Incremental mode** and schedule the actor. The first run returns everything; later runs only return new and changed products. See **Resume and recurring updates** above.

#### Can I use it with AI agents or MCP?

Yes, connect the dataset to any MCP-compatible client using the **MCP connectors** input, or pull the results through the API.

#### A category link that carries a keyword

If you paste a category path with a keyword, the marketplace may serve it as the plain keyword search and drop the category, so the results can differ from what the category alone would show.

### 🔗 More scrapers you might like

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🛒 <a href="https://apify.com/abotapi/americanas-com-br-scraper"><b>Americanas Brazil</b></a><br>Scrape Americanas Brazil (americanas.com.br) by keyword, department or pasted link...</td><td>🔌 <a href="https://apify.com/abotapi/casasbahia-com-br-scraper"><b>Casas Bahia Brazil Electronics &amp; Home Goods Scraper</b></a><br>Scrape products from Casas Bahia Brazil by keyword, department, or URL. Filter by brand...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/netshoes-scraper"><b>Netshoes Brazil</b></a><br>Scrape sportswear and footwear from netshoes.com.br. Search by keyword with the store's...</td><td>🛒 <a href="https://apify.com/abotapi/drogasil-com-br-scraper"><b>Drogasil Brazil Pharmacy, Health &amp; Beauty Scraper</b></a><br>Scrape Drogasil (drogasil.com.br) medicines, health and beauty products by keyword...</td></tr>
<tr><td>🏠 <a href="https://apify.com/abotapi/quintoandar-scraper"><b>QuintoAndar Scraper</b></a><br>Scrape QuintoAndar property listings across Brazil with 80+ fields, including rent, sale...</td><td>🏠 <a href="https://apify.com/abotapi/zapimoveis-scraper"><b>Zap Imóveis Scraper</b></a><br>Scrape Zap Imóveis sale, rental and new-development listings by city, filters or URL...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/mercadolivre-com-br-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `mode` (type: `string`):

category: walk the marketplace's category feeds (the tabs shown on the app's home page), with auto-paging. videos: the marketplace's product-clip feed. Both are the surfaces that answer anonymous visitors; every other link kind (product, search, store pages) is behind the marketplace's sign-in wall, so URL mode was removed.

## `category` (type: `array`):

Which category feeds to walk, in order (used by category mode only). Empty walks the general Tudo feed.

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

Hard cap on how many products this run returns and bills for, across every keyword or link.

## `maxPages` (type: `integer`):

Optional bound on result pages walked for each keyword or search link. Each page holds up to 48 products. 0 (the default) means unlimited: the walk goes as deep as the marketplace serves and stops on Max products, on a page that returns nothing new, or on the internal 400-page safety stop.

## `proxy` (type: `object`):

Apify Proxy with the Residential tier and country Brazil is required for search results and product pages. Category and deals pages are gated the same way. If your account cannot use this tier, the run continues on a backup connection and reports clearly if no page could be loaded.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning or charging for products already collected there. Use this after an interrupted run. The walk restarts from the first result page and steps over the products that run already collected, so raise Max result pages per search when you resume a deep pull. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products. What is compared: every returned field (price, original price, discount, installments, shipping, seller, stock, rating and review count, title, images and so on); changedFields names the ones that moved. What is excluded: scrapedAt (changes on every scrape), reviews (the review rows themselves; a new review still shows up through the review count and rating), and the search-context fields searchPosition (rank on the page), totalResults (size of the result set), searchKeyword (the query that found the product), resultType and sponsored (how this run found the row) and highlight (the ranking badge); these depend on the page and query, not on the product. A changed promotions entry does count as a change. Add more with Ignore fields when detecting changes. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each keyword, filter and detail setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the keywords, filters and detail settings, so different searches never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, so never when Max products capped it or when Resume was used. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.

## `ignoreFieldsForChanges` (type: `array`):

Output field names that should NOT make a product count as UPDATED, even when they changed (incremental mode only). Matches a field name at any nesting depth. Ignored fields are still returned in the output. Always excluded: scrapedAt, reviews, searchPosition, totalResults, searchKeyword, resultType, sponsored and highlight (they depend on the page and query that found the product, not on the product).

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "category",
  "category": [],
  "maxItems": 20,
  "maxPages": 0,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BR"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `changes` (type: `string`):

No description

# 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 = {
    "mode": "category",
    "category": [],
    "maxItems": 20,
    "maxPages": 0,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "BR"
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": [],
    "maxNotifyListings": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/mercadolivre-com-br-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 = {
    "mode": "category",
    "category": [],
    "maxItems": 20,
    "maxPages": 0,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "BR",
    },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
    "maxNotifyListings": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/mercadolivre-com-br-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 '{
  "mode": "category",
  "category": [],
  "maxItems": 20,
  "maxPages": 0,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BR"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}' |
apify call abotapi/mercadolivre-com-br-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/mercadolivre-com-br-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/n95g7MqAgRI3UrYX0/builds/8ew4h9xg3a0lP7SPD/openapi.json
