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.

Shell
pip install requests

From 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

Python
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 immediately

Store 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

Python
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

Python
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.

Python
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.

Get API key

2 locations free. Test keys return sample reviews from every platform.

Get your API key in a minute

Free Spark plan: 2 locations, no card. Test keys return sample data on all 63 platforms, so you can build before connecting a real one.