API reference
Introduction
The AliExpress Reviews API returns AliExpress product reviews as JSON. It is a single REST endpoint over HTTPS; every response, errors included, is JSON.
- Base URL
https://api.aliexpress-reviews.com- Auth
x-api-keyheader- Format
- JSON, UTF-8
Quickstart: create a free key, then try it in the dashboard’s API tester or run:
curl "https://api.aliexpress-reviews.com/v1/reviews/1005006123456789?filter=5&pageSize=20" \
-H "x-api-key: $REVIEWS_API_KEY"Authentication
Create an API key in the dashboard and send it in the x-api-key header of every request. Keys start with rv_.
The key is shown only once, when you create it: we store a hash, not the key. If you lose it, rotate it from the dashboard; the old key stops working within 5 minutes.
Keep the key server-side. Anyone who has it can spend your quota.
GET /v1/reviews/{productId}
Returns one page of reviews of a product, plus a summary of its ratings.
Path parameters
| Name | Type | Description |
|---|---|---|
productId required | string | Numeric AliExpress product id: the number in aliexpress.com/item/<id>.html. |
Query parameters
| Name | Type | Default | Plan | Description |
|---|---|---|---|---|
page | integer | 1 | Free | Page number, 1–1000. |
pageSize | integer | 20 | Free | Reviews per page: up to 20 on Free, up to 100 on Pro and Max. |
filter | string | all | Free | One of the filters below. Some values need a higher plan. |
country | string | US | Pro | Shopper country, ISO 3166-1 alpha-2. Decides which reviews filter=local returns and the local count. |
lang | string | en_US | Pro | Language reviews are translated to. originalContent keeps the buyer’s text. |
Unknown parameters return 400. A parameter your plan doesn’t include returns 403, even if its value is the default.
Example request
curl "https://api.aliexpress-reviews.com/v1/reviews/1005006123456789?filter=5&pageSize=20" \
-H "x-api-key: $REVIEWS_API_KEY"const url = new URL('https://api.aliexpress-reviews.com/v1/reviews/1005006123456789');
url.search = new URLSearchParams({ filter: '5', pageSize: '20' }).toString();
const res = await fetch(url, { headers: { 'x-api-key': process.env.REVIEWS_API_KEY } });
if (!res.ok) throw new Error((await res.json()).error.message);
const { summary, data } = await res.json();import os, requests
res = requests.get(
"https://api.aliexpress-reviews.com/v1/reviews/1005006123456789",
params={"filter": "5", "pageSize": 20},
headers={"x-api-key": os.environ["REVIEWS_API_KEY"]},
)
res.raise_for_status()
body = res.json()Filters
Filters are the same ones AliExpress shows on the product page, and AliExpress applies them. Send one filter per request; they can’t be combined.
| Value | Plan | Returns |
|---|---|---|
filter=all | Free | All reviews (default). |
filter=5 | Free | 5-star reviews only. |
filter=4 | Free | 4-star reviews only. |
filter=3 | Free | 3-star reviews only. |
filter=2 | Free | 2-star reviews only. |
filter=1 | Free | 1-star reviews only. |
filter=additional | Pro | Reviews with additional (follow-up) feedback. |
filter=local | Pro | Reviews from buyers in the country parameter. |
filter=image | Max | Reviews with photos. |
The response’s summary.filterCounts tells you how many reviews each filter would return, so you can hide empty filters in your UI without extra requests.
Languages
With lang (Pro), content and additionalFeedback come translated by AliExpress. originalContent always keeps the buyer’s own words.
| Value | Language |
|---|---|
en_US | English |
es_ES | Spanish |
fr_FR | French |
de_DE | German |
it_IT | Italian |
pt_BR | Portuguese (Brazil) |
nl_NL | Dutch |
pl_PL | Polish |
Response
{
"productId": "1005006123456789",
"filter": "all",
"page": 1,
"pageSize": 20,
"total": 452,
"totalPages": 23,
"summary": {
"averageRating": 4.4,
"totalReviews": 452,
"ratingDistribution": { "5": 323, "4": 54, "3": 33, "2": 12, "1": 30 },
"filterCounts": { "all": 452, "image": 32, "additional": 6, "local": 63 }
},
"data": [
{
"id": "60012345678901234",
"author": "J***n",
"country": "ES",
"rating": 5,
"content": "Very good quality, arrived in 10 days",
"originalContent": "Muy buena calidad, llegó en 10 días",
"additionalFeedback": null,
"date": "2026-08-09",
"sku": "Color:Black",
"helpfulVotes": 3,
"images": ["https://..."],
"thumbnails": ["https://..."]
}
]
}Page fields
| Field | Type | Description |
|---|---|---|
productId | string | The requested product. |
filter | string | Filter applied. |
page, pageSize | integer | Page returned and its requested size. |
total | integer | Reviews matching the filter. |
totalPages | integer | Pages available with this pageSize. |
summary.averageRating | number | null | Average stars of the product, null without reviews. |
summary.totalReviews | integer | All reviews of the product, regardless of the filter. |
summary.ratingDistribution | object | Reviews per star, keys "1"–"5". |
summary.filterCounts | object | Reviews per filter: all, image, additional, local (depends on country). |
data | Review[] | The reviews of this page. |
Review fields
| Field | Type | Description |
|---|---|---|
id | string | AliExpress review id. |
author | string | Buyer name, masked by AliExpress (e.g. J***n). |
country | string | Buyer country, ISO 3166-1 alpha-2. |
rating | integer | Stars, 1–5. |
content | string | Review text translated to lang. |
originalContent | string | Review text as the buyer wrote it. |
additionalFeedback | string | null | Follow-up feedback, if any. |
date | string | Review date, YYYY-MM-DD. |
sku | string | null | Variant the buyer bought (e.g. Color:Black). |
helpfulVotes | integer | Times other shoppers marked it helpful. |
images | string[] | Full-size photo URLs. Max plan only. |
thumbnails | string[] | Thumbnail URLs. Max plan only. |
images and thumbnails are omitted on Free and Pro.
Pagination
Request page=1, 2, … until page reaches totalPages. Each page is one request against your quota, so use the largest pageSize your plan allows.
async function allReviews(productId, filter = 'all') {
const reviews = [];
for (let page = 1; ; page++) {
const url = `https://api.aliexpress-reviews.com/v1/reviews/${productId}?filter=${filter}&page=${page}`;
const res = await fetch(url, { headers: { 'x-api-key': process.env.REVIEWS_API_KEY } });
const body = await res.json();
reviews.push(...body.data);
if (page >= body.totalPages) return reviews;
}
}Rate limits
| Plan | Requests per day | Max pageSize |
|---|---|---|
| Free | 100 | 20 |
| Pro | 1,000 | 100 |
| Max | 10,000 | 100 |
Quotas reset at 00:00 UTC. Every response that counts against the quota (200, 404, 429, 502) carries:
| Header | Description |
|---|---|
x-ratelimit-limit | Your daily quota. |
x-ratelimit-remaining | Requests left today. |
x-ratelimit-reset | Unix time of the next reset. |
Requests rejected with 400/401/403 don’t count. Over the quota you get 429 until the reset. There is also a global limit of 50 requests per second shared by all users.
Caching
Each page (product + parameters) is cached for up to 24 hours, so new reviews can take up to a day to show up. Cached responses still count against your quota.
Errors
Errors use standard HTTP status codes and a JSON body:
{ "error": { "message": "filter=image requires the MAX plan" } }| Status | Meaning | Counts against quota |
|---|---|---|
400 | Invalid or unknown parameter, or a malformed product id. | No |
401 | Missing x-api-key header. | No |
403 | Invalid API key, or a parameter or filter your plan doesn’t include. | No |
404 | AliExpress has no product with that id. | Yes |
429 | Daily quota exceeded, or the global rate limit was hit. | — |
502 | AliExpress failed to answer. Retry later. | Yes |
OpenAPI
The full spec is at /openapi.json (OpenAPI 3.0). Import it into Postman, Insomnia or a client generator.