Updated Oct 2026
Mercado Libre reviews API in Python: OAuth, your listings, product reviews
Mercado Libre’s reviews API is seller-side and free, with two quirks that break naive scripts: the OAuth sign-in host depends on the seller’s country, and each refresh token works exactly once. Reviews are per listing, anonymous, and can’t be answered by API. This guide does the flow with requests, following developers.mercadolibre.com, which is also how Prisma’s Mercado Libre connector works (in beta, built from the docs). The marketplace picture (eBay, Etsy, Amazon) is on marketplace seller reviews API.
pip install requestsFrom the Mercado Libre developer portal: an app’s client id and client secret, with your redirect URI registered and PKCE off.
1. Sign the seller in on their country’s host
import os, urllib.parse, requests
API = "https://api.mercadolibre.com"
AUTH_HOSTS = {"ar": "auth.mercadolibre.com.ar", "br": "auth.mercadolivre.com.br", "mx": "auth.mercadolibre.com.mx", "cl": "auth.mercadolibre.cl",
"co": "auth.mercadolibre.com.co", "uy": "auth.mercadolibre.com.uy", "pe": "auth.mercadolibre.com.pe"}
def consent_url(country, state):
return f"https://{AUTH_HOSTS[country]}/authorization?" + urllib.parse.urlencode({"response_type": "code", "client_id": os.environ["ML_CLIENT_ID"], "redirect_uri": os.environ["ML_REDIRECT_URI"], "state": state})
def exchange(code):
r = requests.post(f"{API}/oauth/token", data={"grant_type": "authorization_code", "client_id": os.environ["ML_CLIENT_ID"], "client_secret": os.environ["ML_CLIENT_SECRET"], "code": code, "redirect_uri": os.environ["ML_REDIRECT_URI"]}, timeout=30)
r.raise_for_status(); return r.json() # access_token (6 h), refresh_token (single use), user_id
def refresh(refresh_token):
r = requests.post(f"{API}/oauth/token", data={"grant_type": "refresh_token", "client_id": os.environ["ML_CLIENT_ID"], "client_secret": os.environ["ML_CLIENT_SECRET"], "refresh_token": refresh_token}, timeout=30)
r.raise_for_status(); return r.json() # store the NEW refresh_token immediatelyStore user_id from the token response: it’s the seller id you’ll need. Every refresh returns a new refresh token; save it before doing anything else.
2. Active listings
tok = refresh(os.environ["ML_REFRESH_TOKEN"])
H = {"Authorization": f"Bearer {tok['access_token']}", "Accept": "application/json"}
USER_ID = tok["user_id"]
ids, offset = [], 0
while offset < 1000: # the search pages up to offset 1,000
page = requests.get(f"{API}/users/{USER_ID}/items/search", headers=H, params={"status": "active", "offset": offset, "limit": 50}, timeout=30).json()
ids += page.get("results", [])
offset += 50
if not page.get("results") or offset >= (page.get("paging") or {}).get("total", 0):
break
print(len(ids), "active listings")3. Reviews per listing
def item_reviews(item_id, size=50):
offset = 0
while True:
r = requests.get(f"{API}/reviews/item/{item_id}", headers=H, params={"offset": offset, "limit": size}, timeout=30)
if r.status_code == 400 and "limit" in r.text.lower() and size > 5:
size = 5; continue # the docs don't state the page limit; 50 works on most sites, 5 is the documented default
r.raise_for_status()
body = r.json()
rows = body.get("reviews", [])
yield from rows
total = (body.get("paging") or {}).get("total_pageable") or (body.get("paging") or {}).get("total") or 0
if len(rows) < size or offset + size >= total:
break
offset += size
for item_id in ids[:20]:
for rev in item_reviews(item_id):
print(item_id, rev["id"], rev.get("rate"), rev.get("title"), (rev.get("content") or "")[:80], rev["date_created"], rev.get("status"))Fields: id, date_created, status, title, content and rate (1 to 5). reviewer_id is always 0: Mercado Libre hides the buyer. There is no reply endpoint for product reviews, and reviews aren’t edited, so after a first full read you only need reviews created since the last check. The listing page is GET /items/{id} → permalink.
4. The same job through Prisma
Prisma connects a seller with Mercado Libre’s sign-in on the right country host, keeps the single-use refresh tokens straight, walks the active listings and their reviews, and returns them in the same JSON as eBay, Etsy, Google and 50+ other platforms, with a webhook per new review.
H = {"Authorization": f"Bearer {os.environ['PRISMA_API_KEY']}"}
r = requests.get("https://api.prismareviews.com/v1/reviews", headers=H, params={"platform": "mercadolibre", "limit": 100}, timeout=30)
for rev in r.json()["data"]:
print(rev["rating"], rev["title"], rev["text"], rev["url"])Mercado Libre is read-only in Prisma, like on Mercado Libre, and in beta. Connection: POST /v1/connections with platform: "mercadolibre", the country and a redirect_url; the seller signs in (Connections). A test key returns sample reviews so the code runs now.
FAQ
Why does the Mercado Libre OAuth URL depend on the country?
Each country has its own accounts and auth host: auth.mercadolibre.com.ar, auth.mercadolivre.com.br, auth.mercadolibre.com.mx, .cl, .com.co, .com.uy, .com.pe. The seller signs in on their country’s host; the API itself is api.mercadolibre.com for all of them.
Can I see who wrote a Mercado Libre product review?
No. The reviews API returns reviewer_id as 0 for everyone; reviews come with rate, title, content and date_created but no author. There is also no endpoint to reply to a product review.
How do Mercado Libre refresh tokens work?
Access tokens last 6 hours. Each refresh token works once: the refresh call returns a new access token and a new refresh token, and you must store the new one or the next refresh fails.
Mercado Libre, eBay, Etsy and Google, one key.
2 locations free. Test keys return sample reviews from every platform.