# Mercado Livre Scraper — Products, Prices & Sellers (`bgfc97/mercadolivre-scraper`) Actor

🔥 Up to 30% OFF! Scrape Mercado Livre (Brasil) — no login. Search, listing or product URLs: price, discount, installments, PIX, seller & reputation, rating, reviews, sold qty, 60+ specs, all images. Perfect for price monitoring & market research. ⚡

- **URL**: https://apify.com/bgfc97/mercadolivre-scraper.md
- **Developed by:** [Bruno](https://apify.com/bgfc97) (community)
- **Categories:** E-commerce, Business
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.39 / 1,000 product scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 / Mercado Libre Scraper

Scrape products from **Mercado Livre** (Brazil) and **Mercado Libre** (Argentina, Mexico, Chile,
Colombia, Uruguay) — by **search keyword**, **listing/category/seller URL**, or **direct product
URL** — and get back a rich, structured record for every product: price, original price, discount,
installments, seller + reputation, rating, reviews, sold quantity, images, full specs and more.

**No login. No cookies. No API key.** Public data only — the client just runs it.

### What you get (fields)

Every product row includes, when present on the page:

| Field | Description |
|---|---|
| `itemId` | Mercado Livre id (e.g. `MLB1046215784`) |
| `title` | Product title |
| `price` / `priceText` / `currency` | Current price (number + raw + symbol) |
| `originalPrice` / `discountPercent` | List price before discount, and the % off |
| `installments` | Installment plan text (e.g. `10x R$335,48 sem juros`) |
| `pixInfo` | Pix price/discount line (product pages) |
| `seller` / `sellerReputation` / `officialStore` | Store name, reputation line, official-store flag |
| `rating` / `reviewsCount` | Average star rating and number of reviews |
| `soldQuantity` | Units sold (e.g. `10 mil`) |
| `condition` | New / used |
| `availability` | Stock / fulfillment status |
| `freeShipping` / `fullShipping` / `shippingText` | Shipping flags + raw shipping text |
| `category` | Breadcrumb category path (product pages) |
| `pictures[]` | Up to 25 full-size image URLs (product pages) |
| `attributes[]` | Full specification table `{name, value}` (product pages) |
| `description` | Full product description text (product pages) |
| `tags[]` | Promo labels (`OFERTA DO DIA`, `MAIS VENDIDO`, `X% OFF`, …) |
| `url` / `permalink` | Clean canonical URL + the raw link (ads resolved to a clean `/p/` URL) |
| `isAd` | Whether the card was a sponsored result |
| `position` | Rank within the search results |

### Input

```json
{
  "search": ["iphone 15"],
  "country": "BR",
  "sort": "price_asc",
  "condition": "new",
  "minPrice": 1000,
  "maxPrice": 5000,
  "freeShippingOnly": true,
  "maxItems": 100,
  "itemUrls": ["https://www.mercadolivre.com.br/produto/p/MLB123456"],
  "startUrls": ["https://www.mercadolivre.com.br/ofertas?category=MLB1051"]
}
```

- **search** — keywords/phrases, each opened as its own results page on the chosen `country`'s
  storefront and paginated automatically up to `maxItems`.
- **country** (default `BR`) — `BR`, `AR`, `MX`, `CL`, `CO`, `UY`. Only affects `search`.
- **sort** — `relevance` (default), `price_asc`, `price_desc`. (search only)
- **condition** — `all` (default), `new`, `used`. (search only)
- **minPrice** / **maxPrice** — price-range filter in the country's currency. (search only)
- **freeShippingOnly** — restrict to free-shipping products. (search only)
- **startUrls** — arbitrary listing/category/seller/pre-filtered-search URLs, crawled and paged as
  result pages.
- **itemUrls** — full product permalinks, opened and scraped in full detail (always, regardless of
  `maxItems`).
- **maxItems** (default 50, max 2000) — cap on products from `search` + `startUrls` combined.
- **proxyConfiguration** (default: Apify `RESIDENTIAL`) — kept on `RESIDENTIAL` internally since
  that is what gets past the site's anti-bot.
- **timeoutSecs** (default 45) — per-page load timeout.
- **capsolverApiKey** (optional) — solve a sitekey captcha (Turnstile/hCaptcha/reCAPTCHA) via
  CapSolver if one is ever shown.

At least one of `search`, `startUrls` or `itemUrls` is required.

### How it gets the data (reliably, and cheaply)

Mercado Livre's public REST API is now locked behind authentication (it returns `403 forbidden` to
anonymous callers), and the storefront's search (`lista.`/`listado.`) and product (`/p/…`) pages
answer a cold HTTP request — or a naive headless browser — with a **"Segurança" / account-
verification** wall (their in-house *suspicious-traffic* device check). This actor gets through the
way a real shopper does:

1. A real **headful** Chrome session (Playwright/Crawlee) on an Apify **residential** IP, with a
   consistent desktop fingerprint and human-like mouse/scroll activity.
2. It **warms up on the homepage first** so the site's security SDK establishes device trust, then
   reaches results by **typing into the storefront's own search box** (an in-site navigation) rather
   than a cold deep-link — which is what trips the wall.
3. If a verification interstitial still appears, it lets the automatic device check clear itself
   (and solves a press-and-hold challenge if one is shown) before retrying on a **fresh residential
   session** — a clean draw then passes straight through.
4. To keep cost down, **images, media and fonts are blocked** at the network layer, so each page
   only pulls the HTML it needs (far less residential-proxy bandwidth).

If a product genuinely cannot be loaded after all retries, the row carries an honest `error` field
describing what was seen — **never fabricated data**. Error rows are not charged for.

### Use cases

- Price & discount monitoring across BR/AR/MX/CL/CO/UY — no login or token.
- Competitor / seller / catalog research and BI pipelines.
- Deal and stock tracking.

### ⭐ Enjoying this Actor?

A quick **rating/review** helps others find it.

# Actor input Schema

## `search` (type: `array`):

One or more keywords/phrases to search for, e.g. "iphone 15", "tenis nike". Each keyword is opened as its own search-results page on the chosen country's storefront (a real browser session, not the REST API) and the rendered result cards are scraped, paging automatically until Max items is reached. Leave empty if you only use startUrls / itemUrls.

## `country` (type: `string`):

Which Mercado Livre / Mercado Libre country site to use for keyword search. Only affects `search` (startUrls / itemUrls are opened exactly as given).

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

Result ordering for keyword search.

## `condition` (type: `string`):

Filter keyword search by item condition.

## `freeShippingOnly` (type: `boolean`):

If enabled, keyword search is filtered to products with free shipping.

## `minPrice` (type: `integer`):

Lower bound of the price filter for keyword search, in the country's currency. Leave empty for no lower bound.

## `maxPrice` (type: `integer`):

Upper bound of the price filter for keyword search, in the country's currency. Leave empty for no upper bound.

## `startUrls` (type: `array`):

Arbitrary Mercado Livre listing URLs to crawl as result pages — a category page, an official-store page, a seller's listings, or a pre-filtered search URL copied from your browser. Each is scraped and paged automatically up to Max items. For individual product pages use `itemUrls` instead.

## `itemUrls` (type: `array`):

Full product permalinks to open directly and scrape in full detail, e.g. "https://www.mercadolivre.com.br/produto-xyz/p/MLB123456" or any "...MLB-..." product URL. Always opened in full regardless of Max items.

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

Overall cap on how many products come out of the search keyword(s) + startUrls combined (does not limit itemUrls, which are always opened in full). The crawler pages through the storefront (~50 products per page) until it reaches this cap.

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

Apify Proxy configuration. RESIDENTIAL is strongly recommended (and used as a fallback regardless of this setting) — Mercado Livre shows a bot-check / captcha-wall page to datacenter IPs, which a residential IP in a real browser reliably gets past.

## `timeoutSecs` (type: `integer`):

How long to wait for each page (search results or product page) to load and render before giving up and retrying with a fresh browser session / proxy IP.

## `capsolverApiKey` (type: `string`):

Optional. If Mercado Livre's bot-check page shows a recognized, sitekey-based widget (Cloudflare Turnstile, hCaptcha, or reCAPTCHA v2), this actor will solve it automatically via CapSolver (capsolver.com, paid, key not included) and continue. If the challenge is a different kind (e.g. a behavioral press-and-hold check with no such widget), or this is left empty, or the solve fails, the actor falls back to retrying with a fresh residential session and — if that still doesn't get through — reports an honest error instead of guessing.

## Actor input object example

```json
{
  "search": [
    "iphone"
  ],
  "country": "BR",
  "sort": "relevance",
  "condition": "all",
  "freeShippingOnly": false,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "timeoutSecs": 45
}
```

# Actor output Schema

# 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 = {
    "search": [
        "iphone"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bgfc97/mercadolivre-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 = { "search": ["iphone"] }

# Run the Actor and wait for it to finish
run = client.actor("bgfc97/mercadolivre-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 '{
  "search": [
    "iphone"
  ]
}' |
apify call bgfc97/mercadolivre-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bgfc97/mercadolivre-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/fsrJ5zsHdGSmGV0QW/builds/3qkJ9QXeughqgQdbT/openapi.json
