Sainsbury's Groceries Category Products API
Pass a category ID and page through its products, keeping each pack’s identifier with its price.
- 1–15 credits per call
- Failed calls are free
- Updated
- sainsburys.category.products.list
{ "count": 30, "has_more": true, "next_page": 2, "page": 1, "page_size": 30, "total": 31, "products": [ { "name": "Bulldog Skincare Original Moisturiser 100ml", "available": true, "brand": null, "gtin": "5060144640024", "image": "https://assets.sainsburys-groceries.co.uk/gol/6585985/image.jpg", "pack_size": "100ml", "retailer_product_id": "6585985", "url": "https://www.sainsburys.co.uk/gol-ui/product/bulldog-skincare-original-moisturiser-100ml", "price": { "amount": 6.6, "currency": "GBP" }, "unit_price": { "amount": 66, "currency": "GBP", "measure_amount": 1, "unit": "per_litre" }, "member_prices": [ { "promotion_id": "10762837", "scheme": "nectar", "price": { "amount": 4.4, "currency": "GBP" } } ], "promotions": [ { "buy_quantity": null, "description": "Save 1/3 with Nectar", "end": "2026-10-12T23:00:00Z", "for_amount": null, "id": "10762837", "member_scheme": "nectar", "start": "2026-09-01T23:00:00Z", "type": "member" } ] }, { "name": "Nivea Men Sensitive Moisturiser 75ml", "available": true, "brand": null, "gtin": "5025970023397", "image": "https://assets.sainsburys-groceries.co.uk/gol/6026520/image.jpg", "pack_size": "75ml", "retailer_product_id": "6026520", "url": "https://www.sainsburys.co.uk/gol-ui/product/nivea-men-sensitive-moisturiser-75ml", "price": { "amount": 8, "currency": "GBP" }, "unit_price": { "amount": 106.67, "currency": "GBP", "measure_amount": 1, "unit": "per_litre" }, "member_prices": [ { "promotion_id": "10763079", "scheme": "nectar", "price": { "amount": 3.8, "currency": "GBP" } } ], "promotions": [ { "buy_quantity": null, "description": "Better than Half Price with Nectar", "end": "2026-10-12T23:00:00Z", "for_amount": null, "id": "10763079", "member_scheme": "nectar", "start": "2026-09-01T23:00:00Z", "type": "member" } ] } ]}
| # | Product | Product ID | Pack | Catalog available | GTIN | Product link | Image |
|---|---|---|---|---|---|---|---|
| 1 | Bulldog Skincare Original Moisturiser 100ml | 6585985 | 100ml | true | 5060144640024 | https://www.sainsburys.co.uk/gol-ui/product/bulldog-skincare-or… | https://assets.sainsburys-groceries.co.uk/gol/6585985/image.jpg |
| 2 | Nivea Men Sensitive Moisturiser 75ml | 6026520 | 75ml | true | 5025970023397 | https://www.sainsburys.co.uk/gol-ui/product/nivea-men-sensitive… | https://assets.sainsburys-groceries.co.uk/gol/6026520/image.jpg |
| 3 | L'Oreal Men Expert Hydra Energetic Anti-Fatigue Moisturiser 50ml | 6299804 | 50ml | true | 3600520297262 | https://www.sainsburys.co.uk/gol-ui/product/l-oreal-men-expert-… | https://assets.sainsburys-groceries.co.uk/gol/6299804/image.jpg |
| 4 | L'Oreal Men Expert Anti Fatigue Hydra Energetic Mens Moisturise… | 8113836 | 50ml | true | 3600524041694 | https://www.sainsburys.co.uk/gol-ui/product/l-oreal-men-expert-… | https://assets.sainsburys-groceries.co.uk/gol/8113836/image.jpg |
| 5 | L'Oreal Men Expert Hydra Energetic Daily Moisturiser 50ml | 7569582 | 50ml | true | 3600522233077 | https://www.sainsburys.co.uk/gol-ui/product/l-oreal-men-expert-… | https://assets.sainsburys-groceries.co.uk/gol/7569582/image.jpg |
| 6 | Clean & Clear Dual Action Moisturiser Face Cream 100ml | 6010343 | 100ml | true | 5000207007159 | https://www.sainsburys.co.uk/gol-ui/product/clean-clear-dual-ac… | https://assets.sainsburys-groceries.co.uk/gol/6010343/image.jpg |
| 7 | Nivea Men After Shave Balm 100ml | 6372650 | 100ml | true | 5025970023274 | https://www.sainsburys.co.uk/gol-ui/product/nivea-men-after-sha… | https://assets.sainsburys-groceries.co.uk/gol/6372650/image.jpg |
| 8 | Nivea Men Creme Moisturiser for Face Body & Hands 150ml | 7746615 | 150ml | true | 4005900111449 | https://www.sainsburys.co.uk/gol-ui/product/nivea-men-creme-moi… | https://assets.sainsburys-groceries.co.uk/gol/7746615/image.jpg |
| 9 | Nivea Men Protect & Care Intensive Face Moisturiser 50ml | 6372639 | 50ml | true | 5025970023359 | https://www.sainsburys.co.uk/gol-ui/product/nivea-men-protect-c… | https://assets.sainsburys-groceries.co.uk/gol/6372639/image.jpg |
| 10 | Nivea Men Sensitive Face Moisturiser SPF 15 75ml | 8184231 | 75ml | true | 4006000027043 | https://www.sainsburys.co.uk/gol-ui/product/nivea-men-sensitive… | https://assets.sainsburys-groceries.co.uk/gol/8184231/image.jpg |
What you send
The input
object of the request, with every field the endpoint accepts.
- Category labels can repeat. Use the category ID, and its parent relationships from the categories endpoint, to place each shelf.
- Keep the default page size of 30; larger pages do not work reliably yet.
- Send the category ID and move the page number on, keeping the page size the same. Each response says whether more pages follow.
| Field | Type | Required | What it does | Example |
|---|---|---|---|---|
| category_id | string | yes | Category identifier. | 1020694 |
| page | integer | no | One-based result page to fetch. From 1 to 1000. Default: 1. |
|
| page_size | integer | no | Number of results per page. From 1 to 90. Default: 30. |
Fields it returns
What each record in the response holds, with the values from the sample above.
| Field | Type | What it is | Example |
|---|---|---|---|
| products[].name | string | Product or category name as returned; use its identifier to join records. | Bulldog Skincare Original Moisturiser 100ml |
| products[].retailer_product_id | string | Sainsbury’s identifier for matching the same pack. | 6585985 |
| products[].pack_size | string | Size expression where supplied; null stays unknown. | 100ml |
| products[].price | object | Regular pack amount, separate from member prices. | 2 fields |
| products[].unit_price | object | Retailer’s published unit amount; do not assume Nectar basis. | 4 fields |
| products[].available | boolean | Public catalog flag, not local stock. | true |
| products[].brand | null | Brand where supplied; lists may omit it. | null |
| products[].gtin | string | Barcode where supplied, retained as text. | 5060144640024 |
| products[].url | string | Official product page link. | https://www.sainsburys.co.uk/gol-ui/product/bulldog-skincare-or… |
| products[].image | string | Product image URL where supplied. | https://assets.sainsburys-groceries.co.uk/gol/6585985/image.jpg |
| products[].member_prices[].price | object | The price Nectar members pay, with its currency. | 2 fields |
| products[].member_prices | array | Nectar member prices for the product, if any. | 1 records |
| products[].member_prices[].promotion_id | string | Sainsbury’s ID for the offer behind this price. | 10762837 |
| products[].member_prices[].scheme | string | Loyalty scheme the price is for, such as Nectar. | nectar |
| products[].price.amount | number | Regular shelf price in pounds, before any Nectar price. | 6.6 |
| products[].price.currency | string | Currency code supplied with the regular price. | GBP |
| products[].promotions | array | Offers running on the product. | 1 records |
| products[].promotions[].buy_quantity | null | Number of items in a multibuy deal, if the offer is one. | null |
| products[].promotions[].description | string | The offer as Sainsbury’s shows it. | Save 1/3 with Nectar |
| products[].promotions[].end | string | When the offer ends, in UTC. | 2026-10-12T23:00:00Z |
| products[].promotions[].for_amount | null | Total price in pounds for a multibuy deal. | null |
| products[].promotions[].id | string | Sainsbury’s ID for the offer. | 10762837 |
| products[].promotions[].member_scheme | string | Loyalty scheme the offer needs, such as Nectar. | nectar |
| products[].promotions[].start | string | When the offer starts, in UTC. | 2026-09-01T23:00:00Z |
| products[].promotions[].type | string | Kind of offer: member, multibuy or price_cut. | member |
| products[].unit_price.amount | integer | Price per unit in pounds, such as per litre. | 66 |
| products[].unit_price.currency | string | Currency of the unit price, such as GBP. | GBP |
| products[].unit_price.measure_amount | integer | Quantity the unit price is for, such as 1 litre. | 1 |
| products[].unit_price.unit | string | Keep the unit with the amount when comparing packs. | per_litre |
| count | integer | Number of products on this page. | 30 |
| has_more | boolean | Whether more pages of results follow. | true |
| next_page | integer | Page number to ask for next, or null on the last page. | 2 |
| page | integer | Page number of these results. | 1 |
| page_size | integer | Most products returned per page. | 30 |
| products | array | Products in the category on this page. | 30 records |
| total | integer | How many products the category holds in all. | 31 |
Call it from your code, or ask your agent
Set UPSCRAPE_API_KEY to your key and copy a working request.
curl --request POST \ --url https://data.upscrape.com/execute \ --header "Authorization: Bearer $UPSCRAPE_API_KEY" \ --header "Content-Type: application/json" \ --header "Prefer: wait=30" \ --data '{ "capability": "sainsburys.category.products.list", "input": { "category_id": "1020694" }}'
import jsonimport osimport requestspayload = json.loads(r'''{ "capability": "sainsburys.category.products.list", "input": { "category_id": "1020694" }}''')response = requests.post( "https://data.upscrape.com/execute", headers={ "Authorization": f"Bearer {os.environ['UPSCRAPE_API_KEY']}", "Content-Type": "application/json", "Prefer": "wait=30", }, json=payload,)response.raise_for_status()print(json.dumps(response.json(), indent=2))
const response = await fetch("https://data.upscrape.com/execute", { method: "POST", headers: { "Authorization": `Bearer ${process.env.UPSCRAPE_API_KEY}`, "Content-Type": "application/json", "Prefer": "wait=30", }, body: JSON.stringify({ "capability": "sainsburys.category.products.list", "input": { "category_id": "1020694" }}),});if (!response.ok) { throw new Error(`Upscrape request failed: ${response.status}`);}console.log(JSON.stringify(await response.json(), null, 2));
https://data.upscrape.com/mcp
Use Upscrape to list the first page of Sainsbury’s category 1020694 with the default page size. Show product IDs and regular prices, and label the report as one page.
More from the Sainsbury's Groceries API
The same data from other platforms
Sainsbury's Groceries Category Products API FAQ
The short answers. The docs have the long ones.
How much does the Sainsbury's Groceries Category Products API cost?
1–15 credits per successful call, shown before it runs. You buy credits once, and paid credits never expire.
What do I send?
Send category_id. The input fields below list every option with its type and limits.
Do I need a Sainsbury's Groceries login?
No. It reads public Sainsbury's Groceries data; nothing runs on your account.
Can my AI agent call it?
Yes, over MCP: the agent finds sainsburys.category.products.list, checks its price and runs it with the same credits as the REST API.
Your first Sainsbury's Groceries call is free.
Up to 100 free credits to start, no card needed.