# Mercado Libre (Mercado Livre) Scraper - Prices & Sold Counts (`lanternlab318/mercadolibre`) Actor

Search Mercado Libre / Mercado Livre by keyword in Argentina, Brazil, Mexico, Colombia or Chile, or paste product URLs. Get item ID, title, price, original price, sold count, rating, official store, shipping and link, with optional product-page details. No login, no cookies.

- **URL**: https://apify.com/lanternlab318/mercadolibre.md
- **Developed by:** [Lantern Lab](https://apify.com/lanternlab318) (community)
- **Categories:** E-commerce, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 products

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?

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 Libre (Mercado Livre) Scraper - Prices & Sold Counts

Search Mercado Libre by keyword in **Argentina, Brazil (Mercado Livre), Mexico, Colombia or Chile**, or paste product URLs, and get the public listings back: item ID, title, price and currency, original price and discount, sold quantity, rating, official store, shipping and link. Turn on product-page details to add the condition, the number of ratings, the seller ID and stock status for every product. No login, no cookies, no account of your own.

**Price:** USD 1.60 per 1,000 products (`product` event), plus USD 0.04 per run start at the default 2,048 MB memory (`apify-actor-start`, USD 0.02 per GB of run memory). Product-page details are optional and cost USD 10 per 1,000 detail pages read (`product-details` event); a row from a product URL always includes its product page, so it costs both (USD 11.60 per 1,000). A product whose page could not be read is not charged for details. Empty searches, status rows, unreadable URLs and the run summary are free.

### Input example

```json
{
  "searchQueries": ["zapatillas running", "silla gamer"],
  "country": "AR",
  "maxProducts": 100,
  "includeDetails": false,
  "productUrls": ["https://www.mercadolivre.com.br/tenis-casual-masculino-break-start-adidas-liso/p/MLB38653421"]
}
```

### Output example

One row per product, `recordType: "product"`:

```json
{
  "recordType": "product",
  "itemId": "MLA1886777584",
  "productId": "MLA39398460",
  "title": "Silla Gamer Ergonómica The Game House D395 con Respaldo Reclinable y Altura Ajustable, Gris",
  "price": 167490,
  "currency": "ARS",
  "originalPrice": 322097.88,
  "discountPercent": 48,
  "condition": null,
  "soldQuantity": 1000,
  "rating": 4.7,
  "reviewCount": 2666,
  "sellerName": "The Game House",
  "officialStore": true,
  "shipping": "Llega gratis el lunes",
  "freeShipping": true,
  "isAd": true,
  "url": "https://www.mercadolibre.com.ar/silla-gamer-ergonomica-the-game-house-d395-con-respaldo-reclinable-y-altura-ajustable-gris/p/MLA39398460",
  "country": "AR",
  "siteId": "MLA",
  "source": "search",
  "query": "silla gamer",
  "rank": 1,
  "page": 1,
  "detailsStatus": "not_requested",
  "partial": false,
  "collectedAt": "2026-10-23T16:15:02.114Z"
}
```

### Limits

- Five country sites: AR, BR, MX, CO, CL. Each search term is searched on one site per run; product URLs are read on the site their address belongs to.
- Mercado Libre serves at most 2,000 results for one search. It also matches loosely, so even an odd search term usually returns related products rather than nothing.
- `soldQuantity` is the rounded figure the page shows (for example `+1000 vendidos` is `1000`), not an exact count.
- Without product-page details, `condition` is filled only for listings the site labels as used or refurbished, and `reviewCount` only for catalogue products; both are filled for every product with details on.
- A seller is named only when it is an official store. Other sellers' names are not collected.
- Short links without a product name in them (`…/MLA-123-_JM`) are often answered with Mercado Libre's sign-in page, and so is a listing that no longer exists; such a URL is reported `partial` with `partialReason: "login_wall"` rather than as missing. Use the product's full address.
- No reviews text, questions, seller reputation or price history. No scheduling built in; use Apify schedules.

### What it does

- Searches each term separately on the chosen site, follows the result pages until `maxProducts` products are collected or the results end, and labels every row with the term, its rank and its results page.
- Deduplicates across the whole run: sponsored slots repeat products already on the page, and terms overlap. Each product is written once and charged once.
- With `includeDetails`, opens each product's own page and fills the condition, number of ratings, seller ID and stock status. A product whose page could not be read is still returned with its search fields and a `detailsStatus` saying why.
- Never follows an advertising click link: sponsored products link to the product's own page, so reading them does not register a paid ad click for the seller.
- Says what happened per input. A search that returned nothing is an empty result; a search cut short by a limit or by Mercado Libre refusing the page is marked `partial: true` with the reason. A product URL that no longer exists is recorded as `not_found`. These are different records and are never confused.
- Caps itself: `maxUpstreamRequests` is a hard ceiling on pages opened for the whole run, derived from your input when you leave it empty, so a run is never unbounded.

### Input

| Field | Default | Meaning |
| --- | --- | --- |
| `searchQueries` | — | One search term per line, in the site's language: `zapatillas running`, `fone bluetooth`, `pão de queijo`. |
| `country` | `AR` | The site searched: `AR`, `BR`, `MX`, `CO` or `CL`. |
| `maxProducts` | `50` | Upper bound on products per search term, in Mercado Libre's ranking order. At most 2,000. |
| `includeDetails` | `false` | Also open every product's own page. Slower, and charged as a separate product-details event. |
| `productUrls` | — | Product pages to read directly: `articulo.…/MLA-…`, `…/p/MLA…` or `…/up/MLAU…`. Always read with details. |
| `maxUpstreamRequests` | derived | Hard ceiling on pages opened for the whole run, retries included. |
| `proxyConfiguration` | Apify residential | Mercado Libre sends datacenter IPs and visitors from other countries to its sign-in page. The exit country is set to each site's own country automatically. |

Give at least one search term or one product URL.

### Output

#### Product rows (`recordType: "product"`, charged)

| Field | Meaning |
| --- | --- |
| `itemId` | The listing's ID (`MLA…`, `MLB…`, …). The dedupe key. |
| `productId` | The catalogue product ID when the listing belongs to one, else `null`. |
| `title` | The listing title as shown. |
| `price`, `currency` | The price shown, in the site's currency (`ARS`, `BRL`, `MXN`, `COP`, `CLP`). |
| `originalPrice`, `discountPercent` | The struck-through price and the discount, when the page shows one. |
| `condition` | `new`, `used` or `refurbished`; see Limits. |
| `soldQuantity` | The rounded sold figure the page shows. |
| `rating`, `reviewCount` | Average stars and number of ratings, when shown. |
| `sellerName`, `officialStore` | The official store's name, and whether the seller is one. |
| `sellerId` | The seller's numeric ID (with details). |
| `shipping`, `freeShipping` | The shipping line as shown, and `true` when it says free. |
| `inStock` | Stock status (with details). |
| `categoryId` | Mercado Libre's category ID. |
| `isAd` | `true` for a sponsored result. |
| `url`, `imageUrl` | The product's own page and its main picture. |
| `country`, `siteId` | The site the row comes from. |
| `source`, `query`, `inputUrl`, `rank`, `page` | Which input produced the row and where it ranked. |
| `detailsStatus` | `collected`, `not_requested`, or why the product page was not read: `login_wall`, `blocked`, `not_found`, `no_product_page`, `upstream_request_cap`. |
| `partial`, `partialReason` | Always `false` / `null` on a product row: the row exists because the product was collected. |
| `collectedAt` | When this run read the product. Mercado Libre shows no publish date for a listing. |

#### Status rows (free)

- `recordType: "query_status"`, one per search term: `productsReturned`, `duplicatesSkipped`, `pagesRead`, `resultsAvailable` (the total the site reported), `resultsLimitReached`, `detailsCollected`, `partial`, `partialReason`, `statusText`.
- `recordType: "url_status"`, one per product URL: `outcome` (`collected`, `duplicate`, `not_found`, `invalid_url`, `partial`), `itemId`, `partial`, `partialReason`, `statusText`.
- `partialReason` is one of `upstream_request_cap`, `charge_limit_reached`, `login_wall`, `blocked` (the bot check, a CAPTCHA wall or the network kept failing), `not_collected`.

#### Run summary

The last row of the dataset, also stored as `RUN_SUMMARY` in the run's key-value store: products collected and charged, details charged, duplicates skipped, empty searches, URL outcomes, partial inputs by reason, pages opened by purpose against the ceiling, and why the run stopped, if it stopped early.

A run that collected nothing because Mercado Libre refused every page fails; a run that legitimately found nothing succeeds with zero product rows.

### How it reads the site

Mercado Libre's public API is closed to anonymous callers, and its pages check visitors with a script that a plain HTTP client cannot run. This Actor opens the pages in a real headless browser from a residential IP in the site's own country, lets the site's own check run once per session, and then reads each page's fully rendered HTML with images, styles and scripts blocked. It reads only what any visitor sees without signing in.

# Actor input Schema

## `searchQueries` (type: `array`):

One search term per line, written as you would type it in the site's search box, in the site's own language: "zapatillas running", "fone bluetooth", "pão de queijo". Every term is searched separately on the country site below and its results are labelled with it. A product that matches several of your terms is returned once and charged once.

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

Which Mercado Libre site the search terms are searched on. Each country is a separate site with its own listings, prices and currency. Product URLs are always read on the site their own address belongs to.

## `maxProducts` (type: `integer`):

Upper bound on the products one search term may produce, counted in the order Mercado Libre ranks them. Mercado Libre itself serves at most 2,000 results for one search, so a value above that does not reach more.

## `includeDetails` (type: `boolean`):

The search listing already gives the title, price, currency, original price, rating, sold quantity, official store and shipping label. With this on, every product's own page is opened as well, which adds the condition (new / used / refurbished) for every product, the number of ratings, the seller ID and stock status. It is one extra page per product, so it is slower and charged as a separate product-details event.

## `productUrls` (type: `array`):

Optional. Product pages to read directly: a seller's listing (articulo.mercadolibre.com.ar/MLA-…), a catalogue product (…/p/MLA…) or a user product (…/up/MLAU…), on any of the five sites. Paste the product's own address as your browser shows it; links copied from an ad (click1.…) are refused because following them would register a paid ad click. Each URL row always includes the product-page details.

## `maxUpstreamRequests` (type: `integer`):

Hard ceiling on the pages this run opens on Mercado Libre: search pages, product pages, session warm-up pages and retries together. At the ceiling collection stops - the inputs not reached are written with partialReason "upstream_request_cap" and the run then ends normally. Leave empty and the Actor works a ceiling out from your input, so a run is never unbounded.

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

The proxy the pages are opened through. Mercado Libre sends datacenter IPs and visitors from other countries to its sign-in page, so the default is Apify residential proxy, and the exit country is always set to each site's own country automatically.

## Actor input object example

```json
{
  "searchQueries": [
    "zapatillas running"
  ],
  "country": "AR",
  "maxProducts": 50,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "searchQueries": [
        "zapatillas running"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lanternlab318/mercadolibre").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 = {
    "searchQueries": ["zapatillas running"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("lanternlab318/mercadolibre").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 '{
  "searchQueries": [
    "zapatillas running"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call lanternlab318/mercadolibre --silent --output-dataset

```

## MCP server setup

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

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/1j4jBcWF8IYt9meH8/builds/lFvbUrbMmsmojbuwe/openapi.json
