sainsburys APIsainsburys.co.uk ↗
Search Sainsbury's grocery products, browse the category tree, fetch product details with health ratings, and retrieve trending searches via a single API.
What is the sainsburys API?
The Sainsbury's API covers 6 endpoints that expose the full grocery catalogue at sainsburys.co.uk — including keyword search via search_products, hierarchical category browsing, and per-product detail pages with health classification scores, brand attributes, and review data. Results are paginated and return a consistent product shape with fields like product_uid, retail_price, and is_available.
curl -X GET 'https://api.parse.bot/scraper/2fb6ed22-2e3f-4192-9b3c-c522aa46ce05/search_products?page=1&query=milk&page_size=20' \ -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 sainsburys-co-uk-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.
"""Walkthrough: Sainsburys grocery SDK — bounded, re-runnable; every call capped."""
from parse_apis.sainsburys_grocery_api import Sainsburys, CategoryId, ProductNotFound
client = Sainsburys()
# Search for products — limit= caps total items fetched
for product in client.products.search(query="bread", page_size=20, limit=3):
print(product.name, product.retail_price.price, product.is_available)
# Drill into one product's full details by SKU
first = client.products.search(query="milk", limit=1).first()
if first:
detail = client.products.get(sku=first.product_uid)
print(detail.name, detail.brand, detail.short_description)
if detail.reviews:
print(detail.reviews.total, detail.reviews.average_rating)
# Browse products by category using the enum
for item in client.products.by_category(category_id=CategoryId._12431, limit=3):
print(item.name, item.retail_price.price)
for cat in item.categories:
print(cat.id, cat.name)
break
# List top-level categories and explore the full hierarchy tree
for category in client.categories.list(limit=5):
print(category.name, category.slug)
tree = client.categories.tree()
print(tree.name, tree.slug, len(tree.children))
# Get trending search terms
trends = client.trendingtermses.get()
for term in trends.terms[:5]:
print(term)
# Typed error handling
try:
client.products.get(sku="9999999999")
except ProductNotFound as exc:
print(f"Product not found: {exc}")
print("exercised: products.search / products.get / products.by_category / categories.list / categories.tree / trendingtermses.get")
Full-text search over the grocery catalog. Returns paginated product listings with pricing, availability, reviews, and category data. Sorted by favourites first. Each product includes a product_uid usable for get_product_details.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination. |
| queryrequired | string | Search keyword (e.g. 'milk', 'bread', 'chocolate'). |
| page_size | integer | Number of results per page (max 60). |
{
"type": "object",
"fields": {
"total": "integer total number of matching products",
"products": "array of product objects"
},
"sample": {
"data": {
"total": 865,
"products": [
{
"name": "Semi Skimmed Milk 2.27L (4 pint)",
"image": "https://assets.sainsburys-groceries.co.uk/gol/357937/image.jpg",
"reviews": {
"total": 1968,
"average_rating": 4.595
},
"full_url": "https://www.sainsburys.co.uk/gol-ui/product/semi-skimmed-milk-2-27l-4-pint",
"categories": [
{
"id": "12431",
"name": "Fresh milk"
}
],
"unit_price": {
"price": 0.73,
"measure": "ltr",
"measure_amount": 1
},
"product_uid": "357937",
"is_available": true,
"retail_price": {
"price": 1.65,
"measure": ""
}
}
]
},
"status": "success"
}
}About the sainsburys API
Search and Category Browsing
The search_products endpoint accepts a required query string (e.g. 'milk', 'gluten free pasta') and optional page and page_size parameters (up to 60 results per page). It returns a total count and an array of product objects sorted by favourites, each carrying a product_uid you can pass directly into get_product_details. For category-based browsing, get_products_by_category takes a numeric category_id string — found either in a product's categories array or in the category tree after the c: prefix in slugs — and returns the same product shape with full pagination support.
Category Hierarchy
Two endpoints expose the category taxonomy. get_category_list returns a flat list of top-level department categories with name and slug fields, useful for building navigation or seeding a crawl. get_category_tree returns the full nested hierarchy as a single root node where each node carries s (slug), n (name), and c (children array). The slug values in the tree contain the numeric IDs used by get_products_by_category.
Product Detail and Trending Data
get_product_details accepts either a sku (e.g. '357937') or a URL-style slug (e.g. 'sainsburys-british-filtered-semi-skimmed-milk-2l') — at least one is required. The response extends the search product shape with short_description, health_classification (including health_rating_score_value), brand extracted from attributes, and HFSS restriction information not present in list endpoints. get_trending_searches returns an ordered terms array of popular search keywords directly usable as input to search_products.
The sainsburys API is a managed, monitored endpoint for sainsburys.co.uk — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when sainsburys.co.uk 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 sainsburys.co.uk 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
retail_pricechanges across product categories usingget_products_by_category. - Analyse nutritional and health data at scale by extracting
health_classification.health_rating_score_valuefromget_product_details. - Populate an autocomplete or search suggestion widget using the ordered list from
get_trending_searches. - Map the full Sainsbury's department taxonomy for a grocery comparison site using
get_category_tree. - Identify HFSS-restricted products in a given category for compliance or dietary research tooling.
- Cross-reference brand presence across categories by combining
brandfields fromget_product_detailswith category browsing. - Track availability (
is_available) and review sentiment (reviews.average_rating) over time for a set of SKUs.
| 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 Sainsbury's provide an official developer API?+
What does get_product_details return that search results don't include?+
get_product_details adds short_description, health_classification with a health_rating_score_value, a brand field extracted from product attributes, and HFSS restriction data. The list endpoints (search_products, get_products_by_category) return pricing, availability, reviews, and category tags but omit those extended fields.How do I find the category_id needed for get_products_by_category?+
categories array on any product object returned by search_products or get_product_details, or from the slug values in the get_category_tree response, where the numeric ID follows the c: prefix in a slug.Does the API cover Sainsbury's non-grocery inventory such as clothing, Tu, or Argos products?+
Is there a way to filter search results by dietary attribute or brand directly in the API?+
search_products endpoint does not currently expose attribute-level filters such as dietary flags or brand constraints as distinct parameters — filtering is by keyword only. The brand field is available on individual product records from get_product_details. You can fork the API on Parse and revise it to add filter parameters if finer-grained querying is needed.