Perekrestok APIperekrestok.ru ↗
Access Perekrestok.ru product catalog, category tree, prices, and reviews via 5 endpoints. Search products, browse categories, and fetch product details.
What is the Perekrestok API?
The Perekrestok.ru API provides structured access to one of Russia's major supermarket chains across 5 endpoints, covering category navigation, product listings, product details, keyword search, and customer reviews. The get_product_details endpoint returns full product metadata including pricing for a given PLU code, while get_product_reviews exposes paginated shopper feedback for any product on the platform.
curl -X GET 'https://api.parse.bot/scraper/7d6d56d1-a073-4e76-ad76-60c258b724a0/get_categories' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace perekrestok-ru-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
Perekrestok API Client for Parse.bot
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Optional, Any
class ParseClient:
"""Client for interacting with Perekrestok API via Parse.bot"""
def __init__(self, api_key: Optional[str] = None):
self.base_url = "https://api.parse.bot"
self.scraper_id = "f0e630db-a315-4292-b46c-7acf011e1115"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key is required. Set PARSE_API_KEY env variable or pass it directly.")
def _call(self, endpoint: str, method: str = "POST", **params) -> dict[str, Any]:
"""Make API call to Parse.bot
Args:
endpoint: API endpoint name
method: HTTP method (GET or POST)
**params: Query/body parameters
Returns:
API response as dictionary
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params)
elif method.upper() == "POST":
response = requests.post(url, headers=headers, json=params)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
response.raise_for_status()
return response.json()
def get_categories(self, parent_id: Optional[int] = None) -> dict[str, Any]:
"""Get full category tree or children of a specific category
Args:
parent_id: Parent category ID (optional)
Returns:
Category tree data
"""
params = {}
if parent_id is not None:
params["parent_id"] = parent_id
return self._call("get_categories", method="GET", **params)
def get_category_products(
self,
category_id: int,
page: int = 1,
per_page: int = 30
) -> dict[str, Any]:
"""Get paginated list of products in a category
Args:
category_id: Category ID (required)
page: Page number
per_page: Results per page
Returns:
Paginated products data
"""
return self._call(
"get_category_products",
method="POST",
category_id=category_id,
page=page,
per_page=per_page
)
def get_product_details(self, plu: str) -> dict[str, Any]:
"""Get full details for a specific product
Args:
plu: Product PLU code or ID
Returns:
Product details
"""
return self._call("get_product_details", method="GET", plu=plu)
def search_products(
self,
query: str,
page: int = 1
) -> dict[str, Any]:
"""Search products by keyword
Args:
query: Search query
page: Page number
Returns:
Search results
"""
return self._call("search_products", method="GET", query=query, page=page)
def get_product_reviews(
self,
plu: str,
page: int = 1,
per_page: int = 10
) -> dict[str, Any]:
"""Get user reviews for a product
Args:
plu: Product PLU code or ID
page: Page number
per_page: Results per page
Returns:
Product reviews
"""
return self._call(
"get_product_reviews",
method="GET",
plu=plu,
page=page,
per_page=per_page
)
def main():
"""Practical workflow example: Search for products and get detailed information"""
# Initialize client
client = ParseClient()
print("=" * 60)
print("Perekrestok API Demo - Product Search & Details Workflow")
print("=" * 60)
# Step 1: Browse categories
print("\n1. Fetching product categories...")
try:
categories_response = client.get_categories()
if "content" in categories_response and "items" in categories_response["content"]:
items = categories_response["content"]["items"]
print(f" Found {len(items)} categories")
if items:
first_cat = items[0]["category"]
print(f" Example: {first_cat['title']} (ID: {first_cat['id']})")
# Step 2: Get products from first category
category_id = first_cat["id"]
print(f"\n2. Getting products from category '{first_cat['title']}'...")
products_response = client.get_category_products(
category_id=category_id,
page=1,
per_page=5
)
if "content" in products_response and "items" in products_response["content"]:
products = products_response["content"]["items"]
print(f" Retrieved {len(products)} products")
if products:
# Step 3: Get details for each product
print("\n3. Getting detailed information for products...")
for idx, product in enumerate(products[:3], 1):
product_id = str(product.get("id", ""))
product_title = product.get("title", "Unknown")
price = product.get("priceTag", {}).get("price", "N/A")
if product_id:
print(f"\n Product {idx}: {product_title}")
print(f" - ID: {product_id}")
print(f" - Price: {price}")
try:
details = client.get_product_details(plu=product_id)
if "content" in details:
content = details["content"]
weight = content.get("masterData", {}).get("weight", "N/A")
print(f" - Weight: {weight}g" if weight != "N/A" else f" - Weight: {weight}")
# Get reviews for this product
try:
reviews = client.get_product_reviews(plu=product_id, per_page=3)
if "content" in reviews and "items" in reviews["content"]:
review_items = reviews["content"]["items"]
if review_items:
print(f" - Reviews ({len(review_items)} shown):")
for review in review_items[:2]:
author = review.get("author", "Anonymous")
rating = review.get("rating", "N/A")
text = review.get("text", "No text")[:50]
print(f" * {author} ({rating}★): {text}...")
except Exception as e:
print(f" - Reviews: Error fetching ({str(e)[:30]}...)")
except Exception as e:
print(f" - Error fetching details: {str(e)[:50]}...")
except Exception as e:
print(f"Error during workflow: {e}")
# Step 4: Search for a product
print("\n4. Searching for 'milk' products...")
try:
search_response = client.search_products(query="milk", page=1)
if "content" in search_response and "items" in search_response["content"]:
results = search_response["content"]["items"]
print(f" Found {len(results)} results for 'milk'")
if results:
for idx, result in enumerate(results[:3], 1):
title = result.get("title", "Unknown")
product_id = str(result.get("id", ""))
print(f" {idx}. {title} (ID: {product_id})")
except Exception as e:
print(f"Search error: {e}")
print("\n" + "=" * 60)
print("Demo complete!")
print("=" * 60)
if __name__ == "__main__":
main()Get full category tree or children of a specific category
| Param | Type | Description |
|---|---|---|
| parent_id | integer | Parent category ID (optional) |
{
"type": "object",
"fields": {
"content": "object"
},
"sample": {
"content": {
"items": [
{
"category": {
"id": 114,
"title": "Milk"
},
"products": []
}
],
"category": {
"id": 113,
"title": "Milk, Cheese, Eggs"
}
}
}
}About the Perekrestok API
Category and Product Browsing
The get_categories endpoint returns the full category tree or, when a parent_id integer is supplied, only the direct children of that node. This lets you build a hierarchical menu or drill into a specific section of the catalog without fetching the entire tree every time. Once you have a category ID, get_category_products accepts that category_id (required) along with page and per_page parameters to retrieve a paginated product list for that category.
Product Details and Search
get_product_details takes a PLU code or product ID string and returns full details for that item — pricing, descriptions, and product attributes as exposed by the catalog. search_products accepts a query string and an optional page parameter, returning matching products across the catalog with the same structure as category-level listings. Both endpoints operate across the full product range available on perekrestok.ru.
Customer Reviews
get_product_reviews retrieves user-submitted reviews for a specific product, identified by its PLU code. Pagination is supported via page and per_page parameters, making it practical to fetch large review sets incrementally. The response content object contains reviewer feedback as recorded on the product page.
The Perekrestok API is a managed, monitored endpoint for perekrestok.ru — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when perekrestok.ru changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official perekrestok.ru API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a grocery price tracker that monitors price changes on specific PLU codes over time using
get_product_details. - Aggregate product assortment data by category using
get_categoriesandget_category_productsfor competitive analysis. - Index the full Perekrestok catalog for a grocery comparison site by iterating paginated results from
get_category_products. - Analyze customer sentiment on grocery products by scraping review text via
get_product_reviewswith pagination. - Power a product search feature in a meal-planning or shopping app using the
search_productsendpoint. - Map Perekrestok's category hierarchy for catalog normalization projects using
get_categorieswithparent_idtraversal. - Monitor new product introductions within a category by polling
get_category_productsand diffing results.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Perekrestok.ru offer an official public developer API?+
What does `get_product_details` return, and how is a product identified?+
plu parameter, which is the product's PLU code or numeric ID as used in the Perekrestok catalog. It returns a content object containing the product's full details — pricing, description, and product attributes. You can find a product's PLU from category listings or search results.Does the API return store-level availability or stock status by location?+
How does pagination work across the product and review endpoints?+
get_category_products and get_product_reviews both accept page and per_page integer parameters. search_products accepts a page parameter but does not expose a per_page override. If per_page is omitted on category or review endpoints, the API uses a default page size determined by the source.