You have extracted 40,000 cards from Mercado Libre, calculated the average price across Argentina, and submitted a report. The issue is that these are not prices for Argentina. These are prices for postal code 1430 — the default zone that the platform assigns to anyone who hasn't specified a delivery location.
Mercado Libre operates in 18 countries across Latin America, with the group's revenue for 2025 reaching $28.9 billion and employing 123,670 people. For e-commerce analytics, this is the primary source of data in the region and simultaneously the most underestimated trap: the platform provides different prices, varying delivery options, and different winners of the buy box depending on where the request originated and which delivery zone the session sees. Let's break down what exactly is broken and how to collect data correctly.
What has changed in 2026: API is effectively closed
A couple of years ago, "parsing Mercado Libre" was resolved through a public API: GET api.mercadolibre.com/sites/MLA/search?q=iphone returned results without authorization. Today, this is no longer the case.
A check on September 12, 2026, from a regular server IP, without a token:
/sites— HTTP 403, body{"code":"PA_UNAUTHORIZED_RESULT_FROM_POLICIES","blocked_by":"PolicyAgent","message":"At least one policy returned UNAUTHORIZED."}/sites/MLA/search?q=iphone&limit=1— HTTP 403,{"message":"forbidden","error":"forbidden"}/items/{id}— HTTP 403, samePolicyAgent
Moreover, it's not just about the absence of a token. Sellers and integrators in public complaints describe the same situation with a valid access token: /users/me and orders respond normally, while catalog and rating endpoints return blocked_by: PolicyAgent. The access policy for the API is tightening selectively, by endpoints, and the documentation is not keeping up.
At the same time, the platform has two technical deadlines for those who still rely on the official API:
- from August 30, 2026 applications must be separated: a separate application for Mercado Libre, and a separate one for Mercado Pago. This is checked via
GET applications/$APP_ID— if the scopes still include rights likeurn:mp:..., the application needs to be re-registered, otherwise, it loses access to the Mercado Libre API; - passing the access token in query parameters has been deemed unsafe: such requests will be rejected with a 301 response. The token must be sent only in the
Authorization: Bearerheader.
The practical conclusion is simple: the official API in 2026 is a channel for sellers working with their accounts, not a tool for market analytics. If the task is to monitor competitors and prices across the region, you are working with the public storefront. What exactly to choose for a specific task was discussed in the material official API, ready dataset, or your own parser.
Seven storefronts instead of one site
Mercado Libre is not a single catalog filtered by country, but a set of independent platforms with their own domains, currencies, and product offerings. In the API, they are referred to as site_id:
- MLA — Argentina (mercadolibre.com.ar, ARS)
- MLB — Brazil (mercadolivre.com.br, BRL)
- MLM — Mexico (mercadolibre.com.mx, MXN)
- MLC — Chile, MCO — Colombia, MLU — Uruguay, MPE — Peru, MLV — Venezuela
The same item in MLA and MLB represents two different cards, two different sellers, and two different logistics schemes. Comparing them "head-on" is pointless: normalization by currency and delivery conditions is necessary. Speaking of currency — the platform itself provides formatting rules in HTML: for Argentina, it is "currency_id":"ARS", "decimal_separator":",", "thousands_separator":".", "time_zone":"GMT-03:00". Parsers that cut prices using regular expressions based on periods make mistakes a thousand times on Latin American storefronts.
The main point: price and delivery are calculated from the recipient's zone
Here is a fragment embedded directly in the HTML of the results page listado.mercadolibre.com.ar when queried without an address:
"location_info":{"zipcode":"1430","inferred_zipcode":false,"default_zipcode":true,"user_zone":"X19"}
This reads as follows: index 1430, it is not derived from your IP (inferred_zipcode: false), it is default (default_zipcode: true). Meanwhile, the header displays "Enviar a Capital Federal" — meaning the platform silently decided that you are in the Buenos Aires metropolitan area, and everything is calculated specifically for it.
And it calculates a lot. In the same HTML, there are delivery banners tied to the zone: same_day_free_shipping with the text "Llega gratis hoy", icon vpp_full_icon — "Enviado por FULL" (product from the platform's warehouse). On one results page for the query "iphone," there were 96 mentions of free shipping. The buy_box block with "Otra opción de compra" also depends on the zone: which seller wins the card is determined in part by who can deliver cheaper and faster to a specific index.
The bottom line: a parser that has never specified a delivery zone collects not "the market of Argentina," but a slice from one city. For a report on the country with million-strong cities a thousand kilometers from the capital, this is a defect that does not manifest itself — the numbers look plausible, but they simply do not answer the right question.
Barrier at the entrance: /gz/account-verification
The second surprise awaits at the transport level. A request to listado.mercadolibre.com.ar/iphone does not return results immediately: it receives HTTP 302 to /gz/account-verification?go=...&tid=... — its own device verification page. This is not Cloudflare and not DataDome: the barrier code contains neither reCAPTCHA, nor Turnstile, nor markers of third-party anti-bots, but rather a dozen calls to device mechanics. The page weighs about 41 KB, is built on JavaScript, and shows nothing without it.
The behavior during verification turned out to be indicative. The first request from a clean server IP passed the barrier: the actual results came back at 2,425,906 bytes — 50 blocks of ui-search-layout and 120 price nodes andes-money-amount__fraction, all rendered on the server. Subsequent requests from the same address hit /gz/account-verification and did not proceed further. The Brazilian and Mexican storefronts did not allow access from this IP at all.
This is typical "reputation" mechanics: the address receives a small credit of trust, spends it over a couple of requests, and then shuts down. No single test proves anything — what matters is that there is no stable access from the data center pool, and behavior varies from country to country.
Another detail from the response headers: the platform sets _d2id (device identifier with a one-year lifespan, also duplicated in x-request-device-id) and _mldataSessionId with Max-Age=1800. Thirty minutes is the natural session length, which should be matched with IP retention.
What does robots.txt say
Before building the collection, it's worth reading the platform's rules. In the robots.txt of both storefronts (Argentinian and Brazilian), the upper block is identical and quite clear:
- full prohibition (
Disallow: /) for AI crawlers: Amazonbot, GPTBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, Perplexity-User; - allowed for social media preview bots: FacebookExternalHit, FacebookBot, Twitterbot, LinkedInBot;
- for Bingbot —
Crawl-delay: 5and a long list of closed sections:/gz/cart/,/gz/checkout/,/perfil/vendedor/,/perfil/comprador/,/navigation/,/noindex/, and others.
From this, two practical things follow. First: the cart, checkout, and user profiles are explicitly closed — there is no need to access them either technically or legally. Second: Crawl-delay: 5 for search bots is a fair guideline for the pace the platform expects from automation. Five seconds per request from one address is a reasonable starting point, not a number pulled from thin air.
How to collect correctly: order of actions
- Fix the collection matrix. Not "Mercado Libre," but a list of pairs "country × delivery zone." For Argentina, this includes Capital Federal, Córdoba, Rosario, Mendoza; for Brazil — São Paulo, Rio, Belo Horizonte, Recife. A price without specifying a zone makes no sense, and this decision is made before the first line of code.
- Obtain a residential IP from the desired country. Server addresses on the Brazilian and Mexican storefronts did not pass the barrier at all, while on the Argentinian one, they expired after the first request. A local residential address resolves both access and reliability issues: the platform initially shows you what it would show to a local buyer.
- Maintain the IP for the entire session. The session cookie lasts 30 minutes — rotation on each request resets it and the selected zone, and you again receive the default index. A sticky session lasting 10–30 minutes for one zone, then change. How to choose the window length was discussed in the guide on sticky sessions.
- Use a browser engine, not a bare HTTP client. The page
/gz/account-verificationis entirely built on JavaScript: without executing scripts, you will remain stuck at the barrier. Use Playwright or a similar tool that maintains state between steps. - Explicitly set the delivery zone. The link leads to
/addresses/v3/navigation/hub; after setting the address, the state lives in the session cookie. Run this procedure once per session, not for each card. - Make
location_infoa checksum. On each saved page, check that thezipcodematches the target, and thatdefault_zipcodehas becomefalse. If the flag remainstrue— do not write the row to the data store, it was collected for the wrong zone. This single check eliminates the majority of silent defects. - Retrieve prices from server-side HTML. Prices and delivery banners are already rendered on the server — there is no need to chase internal JSON endpoints. Store the
zipcode,user_zone,currency_id, and timestamp alongside the price: without them, the number cannot be verified. - Keep the pace. The platform's guideline is five seconds between requests from one address. If speed is needed — expand the pool of addresses, not the frequency from one IP: it is the spike from one address that triggers the barrier.
Pitfalls that will be discovered too late
Silent defects of the default zone. The most expensive mistake does not fall with an exception. Data is collected, a report is built, a pricing decision is made — and only after a quarter does it become clear that all analytics for Brazil describes one district of São Paulo.
Page weight. One results page weighs 2.4 MB. A thousand pages per day across four countries and four zones amounts to tens of gigabytes of traffic per month. On a residential plan with payment per gigabyte, this is a major expense, so it makes sense to immediately disable image and font loading in the browser engine: prices are in the HTML, images for the parser are pure waste.
Comparing countries without normalization. ARS, BRL, MXN, and different digit grouping separators. Normalize to a single currency based on the exchange rate on the collection date and store the original price and currency separately; otherwise, it will be impossible to recalculate retroactively.
Relying on the official API. If integration is still on the API, keep in mind the requirement for separate applications from August 30, 2026, and the move of the token from query to header. A silent loss of access to the API looks exactly like a bug in your code.
What proxies are needed for this task
Residential — a working option for collecting prices and delivery. You need an address from the exact country whose storefront you are scraping, and preferably from the region whose delivery zone you are checking: this way, the data is both obtained and remains reliable. Residential proxies with session retention meet both requirements at once.
Mobile — where the barrier is particularly stubborn. Latin America is a region with a high share of mobile traffic, and an address from a mobile operator looks completely ordinary to the platform. Justified for narrow but critical slices, not for mass extraction.
Data center — for reconnaissance and service tasks: to read robots.txt, capture page structure, check domain availability. For regular price collection, as the checks showed, the resource is insufficient.
In brief
Mercado Libre in 2026 does not provide data anonymously. The official API has been closed by PolicyAgent policies, the storefront greets with its own device verification, and the main figure — price with delivery — is calculated from the recipient's zone, which the platform assigns by default if not specified. A correct parser here differs from an incorrect one not by clever circumvention, but by discipline: country, zone, currency, and location_info next to each row. Everything else is a matter of where your requests are coming from.
