Com APIadidas.com.sg ↗
Search products, get pricing and size availability, and read reviews from adidas.com.sg via a structured JSON API with 4 endpoints.
What is the Com API?
This API provides structured access to adidas.com.sg across 4 endpoints covering product search, detail pages, stock availability, and customer reviews. The search_products endpoint returns up to 48 products per page with filters for gender, color, sport, and brand, while product_detail exposes full pricing breakdowns, color variations, size arrays, and wash care instructions for any product ID.
curl -X GET 'https://api.parse.bot/scraper/6ea095e3-18de-4d6e-80fc-0f4dc1bee2b1/search_products?limit=5&query=ultraboost' \ -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 adidas-com-sg-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.
"""
Adidas Singapore API - Parse Client
A Python client for searching products, getting details, checking availability, and reading reviews from adidas.com.sg
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Any, Optional
class ParseClient:
"""Client for interacting with the Parse API for Adidas Singapore scraper."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse client.
Args:
api_key: API key for Parse API. If not provided, will use PARSE_API_KEY env var.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "6ea095e3-18de-4d6e-80fc-0f4dc1bee2b1"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key must be provided or set in PARSE_API_KEY environment variable")
def _call(self, endpoint: str, method: str = "POST", **params) -> dict[str, Any]:
"""
Make a request to the Parse API.
Args:
endpoint: The API endpoint name (e.g., 'search_products')
method: HTTP method ('GET' or 'POST')
**params: Parameters to pass to the endpoint
Returns:
Response data as a 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)
else:
response = requests.post(url, headers=headers, json=params)
response.raise_for_status()
return response.json()
def search_products(
self,
query: str,
start: int = 0,
sort: Optional[str] = None,
limit: int = 48,
gender: Optional[str] = None,
division: Optional[str] = None,
brand: Optional[str] = None,
sport: Optional[str] = None,
color: Optional[str] = None
) -> dict[str, Any]:
"""
Search for products by keyword with optional filtering and sorting.
Args:
query: Search keyword (e.g., 'shoes', 'ultraboost')
start: Pagination offset (default 0, increment by 48)
sort: Sort order (price-low-to-high, price-high-to-low, newest-to-oldest, top-sellers)
limit: Max results per request (max 48)
gender: Filter by gender (men, women, unisex, kids)
division: Filter by division (shoes, clothing, accessories)
brand: Filter by brand
sport: Filter by sport
color: Filter by color
Returns:
Dictionary containing products, pagination info, and available filters
"""
params = {"query": query, "start": start, "limit": limit}
if sort:
params["sort"] = sort
if gender:
params["gender"] = gender
if division:
params["division"] = division
if brand:
params["brand"] = brand
if sport:
params["sport"] = sport
if color:
params["color"] = color
return self._call("search_products", method="GET", **params)
def product_detail(self, product_id: str) -> dict[str, Any]:
"""
Get comprehensive product details including description, images, pricing, and sizing.
Args:
product_id: Product ID (e.g., 'B75806')
Returns:
Dictionary containing detailed product information
"""
return self._call("product_detail", method="GET", product_id=product_id)
def product_availability(self, product_id: str) -> dict[str, Any]:
"""
Get real-time stock availability for a product by size.
Args:
product_id: Product ID (e.g., 'B75806')
Returns:
Dictionary containing availability status and variations by size
"""
return self._call("product_availability", method="GET", product_id=product_id)
def product_reviews(
self,
model_id: str,
limit: int = 10,
offset: int = 0,
sort: str = "relevancy"
) -> dict[str, Any]:
"""
Get product reviews by model ID.
Args:
model_id: Model ID (from product_detail's base_model_number)
limit: Number of reviews per page
offset: Pagination offset
sort: Sort order (relevancy, newest, oldest, rating)
Returns:
Dictionary containing reviews and pagination info
"""
return self._call(
"product_reviews",
method="GET",
model_id=model_id,
limit=limit,
offset=offset,
sort=sort
)
def main():
"""Find affordable running shoes, check real-time availability, and analyze customer reviews."""
# Initialize the client
client = ParseClient()
print("\n" + "=" * 80)
print("ADIDAS SINGAPORE - SMART SHOPPING ASSISTANT")
print("=" * 80)
# Step 1: Search for budget-friendly running shoes
print("\n[STEP 1] Searching for affordable running shoes (under SGD $150)...\n")
search_response = client.search_products(
query="running shoes",
sort="price-low-to-high",
limit=6
)
products = search_response.get("data", {}).get("products", [])
pagination = search_response.get("data", {}).get("pagination", {})
print(f"✓ Found {pagination.get('total_results', 0)} total running shoes")
print(f"✓ Displaying {len(products)} results on this page\n")
# Display search results summary
print("SEARCH RESULTS (Sorted by Price):")
print("-" * 80)
affordable_products = []
for idx, product in enumerate(products, 1):
price = product.get("price", 0)
sale_price = product.get("sale_price", price)
# Filter for affordable options
if sale_price <= 150:
affordable_products.append(product)
discount = product.get("sale_percentage", "0%")
rating = product.get("rating", 0)
rating_count = product.get("rating_count", 0)
print(f"{idx}. {product.get('name', 'N/A')}")
print(f" Price: SGD ${sale_price} (was ${price}) | Discount: {discount}")
print(f" Rating: ⭐ {rating}/5 ({rating_count} reviews)")
print(f" Product ID: {product.get('product_id', 'N/A')}\n")
if not affordable_products:
print("No affordable options found in current results. Adjusting search...\n")
affordable_products = products[:3]
# Step 2: Deep dive into top 2 affordable products
print("\n" + "=" * 80)
print("[STEP 2] DETAILED ANALYSIS OF TOP PRODUCTS")
print("=" * 80)
selected_products = affordable_products[:2]
for product_idx, product in enumerate(selected_products, 1):
product_id = product.get("product_id", "N/A")
product_name = product.get("name", "Unknown")
print(f"\n{'─' * 80}")
print(f"PRODUCT {product_idx}: {product_name}")
print(f"{'─' * 80}")
# Fetch detailed product information
print("\n📋 Fetching detailed information...")
try:
details_response = client.product_detail(product_id)
details = details_response.get("data", {})
brand = details.get("brand", "N/A")
gender = details.get("gender", "N/A")
print(f" • Brand: {brand}")
print(f" • Gender: {gender}")
# Display pricing details
pricing = details.get("pricing", {})
current_price = pricing.get("current_price", "N/A")
standard_price = pricing.get("standard_price", "N/A")
print(f" • Current Price: SGD ${current_price} (Standard: SGD ${standard_price})")
# Display product description
description = details.get("description", {})
if isinstance(description, dict):
title = description.get("title", "")
text = description.get("text", "")
if text:
print(f" • Description: {text[:120]}...")
# Show available sizes
sizes = details.get("sizes", [])
if sizes:
size_list = [s.get("size", "N/A") for s in sizes]
print(f" • Available Sizes: {', '.join(size_list[:8])}")
if len(size_list) > 8:
print(f" ... and {len(size_list) - 8} more sizes")
# Check real-time stock availability
print("\n📦 Checking real-time stock availability...")
try:
availability_response = client.product_availability(product_id)
availability_data = availability_response.get("data", {})
status = availability_data.get("availability_status", "UNKNOWN")
variations = availability_data.get("variations", [])
in_stock_count = sum(1 for v in variations if v.get("availability_status") == "IN_STOCK")
out_of_stock_count = sum(1 for v in variations if v.get("availability_status") == "OUT_OF_STOCK")
print(f" • Overall Status: {status}")
print(f" • Stock Summary: {in_stock_count} sizes in stock, {out_of_stock_count} out of stock")
# Show specific in-stock sizes with inventory count
in_stock_items = [v for v in variations if v.get("availability_status") == "IN_STOCK"]
if in_stock_items:
print(f" • In-Stock Sizes (first 5):")
for size_var in in_stock_items[:5]:
size = size_var.get("size", "N/A")
count = size_var.get("availability", 0)
print(f" ✓ Size {size}: {count} units available")
if len(in_stock_items) > 5:
print(f" ... and {len(in_stock_items) - 5} more sizes in stock")
except Exception as e:
if "blocked" in str(e).lower() or "akamai" in str(e).lower():
print(f" ⚠ Stock check temporarily blocked (Akamai protection)")
else:
print(f" ⚠ Could not fetch availability: {str(e)[:60]}")
# Fetch and display customer reviews
model_id = details.get("base_model_number")
if model_id:
print(f"\n⭐ Fetching customer reviews (Model ID: {model_id})...")
try:
reviews_response = client.product_reviews(model_id, limit=3, sort="rating")
reviews_data = reviews_response.get("data", {})
total_reviews = reviews_data.get("total_results", 0)
reviews = reviews_data.get("reviews", [])
print(f" • Total Reviews: {total_reviews}")
if reviews:
print(f" • Top Customer Reviews:")
for review in reviews:
rating = review.get("rating", 0)
stars = "⭐" * rating
title = review.get("title", "No title")
nickname = review.get("user_nickname", "Anonymous")
date = review.get("formatted_date", "N/A")
is_recommended = "✓ Recommended" if review.get("is_recommended") else "✗ Not recommended"
print(f"\n {stars} - \"{title}\" by {nickname} ({date})")
print(f" {is_recommended}")
except Exception as e:
print(f" ⚠ Could not fetch reviews: {str(e)[:60]}")
except Exception as e:
print(f" ✗ Error fetching product details: {str(e)[:80]}")
# Step 3: Summary and recommendations
print(f"\n{'=' * 80}")
print("SHOPPING SUMMARY")
print(f"{'=' * 80}\n")
print("✓ Analysis complete! Here's what we found:\n")
if affordable_products:
best_price = min(affordable_products, key=lambda x: x.get("sale_price", float('inf')))
best_rating = max(affordable_products, key=lambda x: x.get("rating", 0))
print(f"💰 Best Price: {best_price.get('name')} - SGD ${best_price.get('sale_price')}")
print(f"⭐ Best Rating: {best_rating.get('name')} - {best_rating.get('rating')}/5 ({best_rating.get('rating_count')} reviews)")
print(f"\n📌 Recommendations:")
print(f" • Check size availability before adding to cart")
print(f" • Read customer reviews to understand fit and durability")
print(f" • Compare with similar products to ensure best value")
print(f"\n{'=' * 80}\n")
if __name__ == "__main__":
main()Search for products by keyword with optional filtering, sorting, and pagination. Returns up to 48 products per page with available filters and sort options.
| Param | Type | Description |
|---|---|---|
| sort | string | Sort order: price-low-to-high, price-high-to-low, newest-to-oldest, top-sellers |
| brand | string | Filter by brand |
| color | string | Filter by color |
| limit | integer | Max results to return (max 48) |
| queryrequired | string | Search keyword (e.g., 'shoes', 'ultraboost') |
| sport | string | Filter by sport |
| start | integer | Pagination offset (0, 48, 96, ...) |
| gender | string | Filter by gender (e.g., 'men', 'women', 'unisex') |
| division | string | Filter by division (e.g., 'shoes', 'clothing') |
{
"type": "object",
"fields": {
"title": "string search title",
"products": "array of product objects with product_id, model_id, name, price, sale_price, rating, image, link, division, category, color_variations",
"pagination": "object with total_results, page_size, current_start, current_page, total_pages, has_more, next_start",
"sort_options": "object containing sorting rules",
"available_filters": "array of filter objects with name, display_name, and values"
},
"sample": {
"data": {
"title": "Ultraboost",
"products": [
{
"link": "/hyperboost-edge-running-shoes/KK0288.html",
"name": "HYPERBOOST EDGE Running Shoes",
"color": null,
"image": {
"src": "https://assets.adidas.com/images/w_280,h_280,f_auto,q_auto:sensitive/1cb81e76d0334abfa39316e4d9eb77a8_9366/hyperboost-edge-running-shoes.jpg",
"cloudinary": true
},
"price": 289,
"rating": 4.6291,
"category": "shoes",
"division": "Performance",
"model_id": "OQQ28",
"product_id": "KK0288",
"sale_price": 289,
"rating_count": 124,
"is_customizable": false,
"sale_percentage": "0%",
"color_variations": [
"KI1912",
"KI1913",
"KI1911"
]
}
],
"pagination": {
"has_more": true,
"page_size": 48,
"next_start": 48,
"total_pages": 3,
"current_page": 1,
"current_start": 0,
"total_results": 108
},
"sort_options": {
"rules": [
{
"selected": false,
"sortingRuleId": "price-low-to-high"
}
]
},
"available_filters": [
{
"name": "gender",
"values": [
{
"count": 67,
"label": null,
"value": "men"
}
],
"display_name": null
}
]
},
"status": "success"
}
}About the Com API
Product Search and Filtering
The search_products endpoint accepts a required query string and optional filters including gender, color, sport, and brand. Results include up to 48 products per page with a pagination object (total_results, current_page, total_pages, next_start) for offset-based traversal using the start parameter. Each product object in the products array carries product_id, model_id, name, price, sale_price, rating, image, link, division, category, and color_variat. The available_filters array enumerates all active filter options for the current query, and sort_options lists supported orderings: price-low-to-high, price-high-to-low, newest-to-oldest, and top-sellers.
Product Detail and Availability
The product_detail endpoint takes a product_id (e.g., IF3813) and returns a detailed object: pricing breaks down current_price, standard_price, and price type; sizes lists each available size with a sku; images includes typed image URLs; description contains structured text with title, subtitle, text, usps, and wash_care_instructions; and color_variations links to sibling colorways by product_id. The response also exposes base_model_number, which is required as the model_id input for the reviews endpoint.
The product_availability endpoint returns per-size inventory status via a variations array and an availability_status summary for a given product_id. Note that this endpoint may be intermittently blocked by site protection, so downstream applications should handle failed responses gracefully.
Customer Reviews
The product_reviews endpoint operates on model_id rather than product_id — use the base_model_number from product_detail or model_id from search results. Each review object in the reviews array includes id, user_nickname, title, text, rating, formatted_date, submission_time, and is_recommended. Pagination is controlled by limit and offset, with has_more and next_offset returned in the pagination object. Sorting supports relevancy, newest, oldest, and rating.
The Com API is a managed, monitored endpoint for adidas.com.sg — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when adidas.com.sg 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 adidas.com.sg 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 price comparison tool tracking
current_pricevsstandard_priceacross Adidas Singapore product lines. - Aggregate customer review sentiment using
rating,text, andis_recommendedfields fromproduct_reviews. - Monitor real-time size stock levels per SKU using the
product_availabilityendpoint for restock alerting. - Populate a product feed with images, color variations, and gender filters from
search_productsandproduct_detail. - Generate filtered product catalogs by sport or gender for affiliate or content sites using
search_productsfilter params. - Track new arrivals by sorting
search_productswithnewest-to-oldestand storing delta snapshots. - Map colorway availability across sibling products using
color_variationsfromproduct_detail.
| 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 adidas.com.sg have an official developer API?+
Why does `product_reviews` require a model ID instead of a product ID?+
base_model_number field returned by product_detail, or the model_id field in search_products results, as the model_id input to product_reviews.How reliable is the `product_availability` endpoint?+
availability_status summary when accessible, but it may be intermittently blocked by site protection. Applications that depend on availability data should implement retry logic and handle failure states without assuming a null response means out-of-stock.Does the API cover adidas stores or outlet locations in Singapore?+
Can I retrieve products from specific categories or collections directly, without a keyword search?+
search_products endpoint requires a query string; there is no dedicated category-browse or collection endpoint currently. The available_filters in search results do expose division and category values, but browsing by category tree alone is not directly supported. You can fork this API on Parse and revise it to add a category-based listing endpoint.