# MercadoLibre Scraper — Products, Prices & Reviews (`memo23/mercadolibre-scraper`) Actor

MercadoLibre and Mercado Livre scraper for Mexico, Brazil, Argentina, Colombia, Chile, Uruguay and Peru. Search a keyword, category or product URL. One row per listing with title, price, condition, rating, seller and images. Optional detail and reviews. JSON, CSV or Excel.

- **URL**: https://apify.com/memo23/mercadolibre-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce, AI, Agents
- **Features:** Limited permissions
- **Stats:** 450 total users, 98 monthly users, 89.8% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.40 / 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

## MercadoLibre Scraper — Products, Prices & Reviews

Scrape product data from **MercadoLibre** across Latin America — title, price, condition, rating, review count, seller and images. Search by keyword, paste a category listing URL, or a direct product URL. The actor **solves MercadoLibre's proof-of-work bot gate for you** and returns clean structured rows. Seven country sites, pay per result, no monthly fee.

#### How it works

![How the MercadoLibre Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-mercadolibre.png)

#### ✨ Why use this scraper?

- **Beats the bot gate.** MercadoLibre fronts search/listing pages with a JavaScript proof-of-work challenge; this actor solves it server-side (no browser) and retries across residential IPs until it gets through — you just get the data.
- **7 country sites in one actor.** Mexico, Argentina, Brazil, Colombia, Chile, Uruguay and Peru — prices returned in each site's currency.
- **Three ways in.** Keyword search, category/listing URL, or direct product URL — mixed freely in one run, auto-classified per entry.
- **Clean canonical URLs.** Sponsored/ad cards are de-duplicated to their real `/p/MLM…` product URLs, not click-tracking links.
- **Optional full detail.** Turn on `enrichDetail` to add brand, rating, review count, condition and the image gallery from each product page.
- **Pay per result.** Billed per product row with a strict `maxItems` cap, so a run never collects (or charges) more than you set.

#### 🎯 Use cases

| You are… | Use it to… |
|---|---|
| **Pricing / competitive intelligence** | Track competitor prices and availability across LATAM marketplaces |
| **Resellers & dropshippers** | Source products, monitor prices and stock, sync catalogs |
| **Market research** | Measure assortment, pricing and ratings by country and category |
| **Brand monitoring** | Watch how your products are listed, priced and rated by third-party sellers |
| **Deal / price monitors** | Track price drops on specific products on a schedule |

#### 📥 Supported inputs

| Input | Example | What you get |
|---|---|---|
| Search keyword (`searchTerms`) | `iphone` | Search results on the chosen country site |
| Category / listing URL | `https://listado.mercadolibre.com.mx/celulares` | Every product in that listing |
| Product URL | `https://www.mercadolibre.com.mx/p/MLM123456` | That single product |
| Country | `MLM` / `MLA` / `MLB` / `MCO` / `MLC` / `MLU` / `MPE` | Which site to search |

**Not supported:** seller back-office data, checkout, or anything behind a MercadoLibre account login.

#### 🔄 How it works

1. **Classify** — each entry is tagged as a keyword search, a category listing, or a product URL.
2. **Fetch + solve** — pages are fetched over HTTP with a real Chrome TLS fingerprint; when the proof-of-work gate appears, the actor solves `sha256(nonce + r)` and replays the solution cookies.
3. **Paginate** — listings walk `_Desde_N` pages until empty or `maxItems`.
4. **Parse** — product cards (and, with `enrichDetail`, each product page's JSON-LD) are mapped to one normalized row.
5. **Push** — one row per product to the dataset (JSON or CSV), de-duplicated by canonical URL.

#### ⚙️ Input parameters

| Field | Type | Description |
|---|---|---|
| `searchTerms` | array | Keywords to search on the selected country site. |
| `startUrls` | array | Listing URLs, product URLs, or bare keywords — auto-classified. |
| `country` | string | Country site: `MLM` (default), `MLA`, `MLB`, `MCO`, `MLC`, `MLU`, `MPE`. |
| `enrichDetail` | boolean | Fetch each product page for brand, rating, condition and images (slower). Default `false`. |
| `maxReviews` | integer | Also scrape up to N recent reviews per product (rating, text, date). `0` = off. |
| `maxItems` | integer | Hard cap on products collected (and billed). Default `1000`. |
| `maxConcurrency` | integer | Parallel jobs (kept low — each request solves a challenge). Default `4`. |
| `proxy` | object | Proxy configuration. **Residential strongly recommended.** |

#### 📊 Output overview

One row per product, identical shape across every country site and discovery mode. Search/category rows carry the essentials (title, price, currency, canonical URL, image); with `enrichDetail` each row is enriched from its product page (brand, condition, rating, review count, full images); with `maxReviews` each row also carries up to N recent individual reviews. Export as JSON or CSV.

#### 📦 Output sample

A real row (search on MLM, `enrichDetail` on):

```json
{
  "type": "product",
  "site": "MLM",
  "country": "com.mx",
  "productId": "MLM1018500844",
  "title": "Apple iPhone 13 128 GB Medianoche",
  "url": "https://www.mercadolibre.com.mx/p/MLM1018500844",
  "price": 12999,
  "currency": "MXN",
  "brand": "Apple",
  "condition": "New",
  "conditionRaw": "Nuevo",
  "available": true,
  "rating": 4.9,
  "reviewCount": 7945,
  "reviews": [
    { "rating": 4, "text": "Es original, llegó rápido y bien empacado.", "date": "Hace 8 meses" }
  ],
  "primaryImage": "https://http2.mlstatic.com/D_NQ_NP_2X_634187-MLA104668423005_012026-F.webp",
  "images": [
    "https://http2.mlstatic.com/D_NQ_NP_2X_634187-MLA104668423005_012026-F.webp",
    "https://http2.mlstatic.com/D_NQ_NP_2X_691262-MLA96638020530_112025-F.webp",
    "https://http2.mlstatic.com/D_NQ_NP_2X_893480-MLA104269335127_012026-F.webp"
  ],
  "description": "iPhone 13. Pantalla Super Retina XDR de 6.1 pulgadas...",
  "sellerName": "Apple Store Oficial",
  "attributes": {
    "Marca": "Apple",
    "Modelo": "iPhone 13",
    "Memoria interna": "128 GB",
    "Tamaño de la pantalla": "6.1 \"",
    "Con NFC": "Sí"
  },
  "amenities": [],
  "address": null,
  "coordinates": null,
  "maintenanceFee": null,
  "rooms": null,
  "bedrooms": null,
  "bathrooms": null,
  "totalArea": null,
  "coveredArea": null,
  "discoveryMode": "search",
  "sourceUrl": "https://listado.mercadolibre.com.mx/iphone",
  "scrapedAt": "2026-06-27T06:30:00.000Z"
}
```

#### 🗂 Key output fields

| Group | Fields |
|---|---|
| **Identity** | `productId`, `title`, `url`, `site`, `country` |
| **Pricing** | `price`, `currency` |
| **Detail** (with `enrichDetail`) | `brand`, `condition`, `conditionRaw`, `available`, `rating`, `reviewCount` |
| **Specs** (with `enrichDetail`) | `description`, `sellerName`, `attributes` — every spec row the page lists, verbatim — and `amenities[]` |
| **Real estate** (with `enrichDetail`) | `address`, `coordinates`, `rooms`, `bedrooms`, `bathrooms`, `totalArea`, `coveredArea`, `maintenanceFee` |
| **Reviews** (with `maxReviews`) | `reviews[]` — each `rating`, `text`, `date` |
| **Media** | `primaryImage`, `images[]` — the full gallery, at full resolution |
| **Provenance** | `discoveryMode`, `sourceUrl`, `scrapedAt` |

##### Real estate (Inmuebles / Imóveis)

Property listings return the same row with the real-estate fields filled in. `attributes`
holds every row of the listing's spec table in the site's own language, so nothing the page
states is lost; `rooms`, `bedrooms`, `bathrooms`, `totalArea` and `coveredArea` are lifted
out of it as numbers for sorting and filtering. Where a spec is a range (common on
developments — `45.2 m² a 51.3 m²`), the number reports the lower bound and `attributes`
keeps the full text.

```json
{
  "title": "Departamento En Venta En Lomas De Zamora - 3 Ambientes - Con Cochera",
  "price": 320000,
  "currency": "USD",
  "sellerName": "Brusipropiedadesok",
  "address": "Colombres 565, Lomas de Zamora, Lomas de Zamora, Bs.As. G.B.A. Sur",
  "coordinates": { "latitude": -34.7634181, "longitude": -58.4056116 },
  "maintenanceFee": "Expensas desde $ 260.000",
  "rooms": 3,
  "bedrooms": 2,
  "bathrooms": 2,
  "totalArea": 98,
  "coveredArea": 80,
  "attributes": {
    "Superficie total": "98 m²",
    "Superficie cubierta": "80 m²",
    "Superficie de balcón": "18 m²",
    "Ambientes": "3",
    "Dormitorios": "2",
    "Baños": "2",
    "Cocheras": "1",
    "Ascensor": "Sí"
  }
}
```

#### ❓ FAQ

**Does it get past MercadoLibre's bot protection?** Yes — listing and product pages are gated by a JavaScript proof-of-work challenge. The actor solves it server-side and retries across IPs, so you don't need a browser or a CAPTCHA solver.

**Do I need a proxy?** Yes — use **residential** (the default). MercadoLibre blocks datacenter IPs outright, and the gate is served unevenly across IPs, so the actor relies on residential rotation.

**Which countries are supported?** Mexico, Argentina, Brazil, Colombia, Chile, Uruguay and Peru. Set `country` to the matching site code.

**How do I get brand, rating and condition?** Enable `enrichDetail`. It fetches each product's page (one extra request per product) and reads its structured data.

**Can I scrape individual reviews?** Set `maxReviews` to N — each product then includes up to N recent reviews (`rating`, `text`, `date`). Works with or without `enrichDetail`. Reviews are billed per review grabbed.

**Why are some fields null in search mode?** Without `enrichDetail`, rows come from the fast listing cards (title, price, URL, image). Brand/rating/condition live on the product page.

#### 💬 Support

Hit a country site or page layout that doesn't parse? Open an issue with the URL you tried — most fixes are quick.

#### 🛠 Additional services

Need a custom field, scheduled price monitoring, or another MercadoLibre country/section? Reach out for a tailored build.

#### 🔎 Explore more scrapers

Pairs well with other marketplace and DTC product scrapers for broader e-commerce coverage.

***

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/mercadolibre-scraper`).

**Purpose:** Scrape MercadoLibre product rows across seven LATAM country sites by keyword, category URL or product URL — one normalized row per product, solving the site's proof-of-work bot gate server-side (no browser).

**Minimal input:**

```json
{
  "searchTerms": ["iphone"],
  "country": "MLM",
  "maxItems": 25
}
```

URL mode (inline): `{ "startUrls": ["https://listado.mercadolibre.com.mx/celulares"], "maxItems": 25 }` — listing, product, or bare-keyword entries are auto-classified.

**Output:** one row per product — type, site, country, productId, title, url, price, currency, discoveryMode, sourceUrl, scrapedAt, primaryImage, images; with `enrichDetail`: brand, condition (New/Used/Refurbished/Damaged), conditionRaw (the site's own wording), available, rating, reviewCount, description, sellerName, attributes (every spec row verbatim, keyed in the site's language), amenities, and for real estate address, coordinates {latitude, longitude}, rooms, bedrooms, bathrooms, totalArea, coveredArea, maintenanceFee; with `maxReviews`: reviews {rating, text, date}.

**Behaviors an agent should know:**

- Always set `maxItems` (default 1000); each product row is billed. Listings paginate (`_Desde_N`) until empty or the cap.
- `country` selects the site: MLM (Mexico, default), MLA, MLB, MCO, MLC, MLU, MPE; prices are in each site's currency.
- `enrichDetail` (default off) is required for brand, condition, rating, reviewCount and full images — adds one request per product.
- `maxReviews` (0–50, default 0) adds up to N recent reviews per product, billed per review grabbed; works with or without `enrichDetail`.
- Residential proxy is required (the default); datacenter IPs are blocked. No seller-dashboard, checkout, or login-gated data.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by MercadoLibre, Inc. or any of its subsidiaries. All trademarks are the property of their respective owners.

The scraper accesses only publicly available product and listing pages — no authenticated endpoints, seller dashboards, or account data. Users are responsible for ensuring their use complies with MercadoLibre's Terms of Service, applicable data-protection law (LGPD, GDPR, CCPA, etc.), and any contractual obligations of their own organisation.

***

### SEO Keywords

mercadolibre scraper, mercado libre scraper, mercadolivre scraper, mercadolibre api, scrape mercadolibre, mercadolibre product scraper, mercadolibre price scraper, mercadolibre mexico scraper, mercadolibre argentina scraper, mercadolibre brasil scraper, mercadolibre colombia scraper, latam ecommerce scraper, marketplace price monitoring, mercadolibre data extraction, apify mercadolibre, product listing scraper, competitor price tracker latam, mercadolibre seller data, ecommerce product scraper, mercadolibre json csv

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords searched on the selected country site (e.g. `iphone`, `notebook gamer`).

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

MercadoLibre search or category listing URLs, direct product URLs (…/p/MLM…), or bare keywords. Each entry is auto-classified.

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

Which MercadoLibre country site to search.

## `enrichDetail` (type: `boolean`):

For each result, fetch its product page to add brand, rating, condition, the full image gallery, the description, the seller name and every spec row the listing states (attributes). For real estate this also fills address, coordinates, rooms, bedrooms, bathrooms, surface areas and expensas. Adds requests, so it's off by default.

## `maxReviews` (type: `integer`):

Also scrape up to this many recent reviews per product (rating, text, date). 0 = off. Adds one request per product.

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

Hard cap on products collected (and billed).

## `maxConcurrency` (type: `integer`):

Parallel jobs. Kept low because each request solves a proof-of-work challenge.

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

Leave this empty. The Actor already routes every request through its own residential proxy, in the right country, at no extra cost to you — setting your own only adds proxy charges to your account. In particular do NOT pick Apify Proxy here: MercadoLibre's captcha wall only accepts a token generated from the same IP that submits it, and Apify Proxy credentials inside an Actor run cannot be reached by the captcha solver, so the Actor will ignore that choice and fall back to its built-in proxy. Use this field only for your own external proxy service.

## Actor input object example

```json
{
  "searchTerms": [
    "iphone"
  ],
  "startUrls": [],
  "country": "MLM",
  "enrichDetail": false,
  "maxReviews": 0,
  "maxItems": 20,
  "maxConcurrency": 4
}
```

# Actor output Schema

## `results` (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 = {
    "searchTerms": [
        "iphone"
    ],
    "startUrls": [],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/mercadolibre-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 = {
    "searchTerms": ["iphone"],
    "startUrls": [],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/mercadolibre-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 '{
  "searchTerms": [
    "iphone"
  ],
  "startUrls": [],
  "maxItems": 20
}' |
apify call memo23/mercadolibre-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/mercadolibre-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/LzKBo6ojZkW9ZgOyS/builds/lHtSu6wXkRgzLuqJ2/openapi.json
