# FairPrice Scraper - Singapore Grocery Prices & Products (`scrapesage/fairprice-scraper`) Actor

Scrape NTUC FairPrice (Singapore) grocery products: price, list price & discount, multi-buy promotions, Nutri-Grade, brand, barcode, country of origin, dietary (Halal), supplier, category, images, ratings & stock. Search by keyword or URL, filter, and monitor price drops. No browser.

- **URL**: https://apify.com/scrapesage/fairprice-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 product scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## FairPrice Scraper — Singapore Grocery Prices & Products

Scrape **NTUC FairPrice** (Singapore's #1 grocer) for live grocery **prices, promotions and product data** — straight from FairPrice's own storefront. Search by keyword or URL, filter by discount / Nutri-Grade / stock, and turn on **monitor mode** to track price drops day-to-day. No login, no API key, no browser.

### Why this FairPrice scraper?

- **Straight from the source.** Reads FairPrice's own public storefront API — fast, stable, and complete. No flaky page-scraping, no anti-bot roulette.
- **Rich, analysis-ready records.** Every product comes with current price, list price & discount, multi-buy promotions, Nutri-Grade, brand, barcode, country of origin, dietary tags (Halal), supplier/distributor, category, images, ratings and stock.
- **Built for price tracking.** Monitor mode remembers products between runs and returns only what's **new or changed** — with `previousPrice` and `priceDelta` — so you can watch price drops without diffing anything yourself.
- **Cheap to run, simple to scale.** Keyword search paginates to ~1,000 products per term; pay only per product written.

### Use cases

- **Price intelligence & competitor monitoring** — track grocery prices and promotions over time for pricing, FMCG and retail-analytics teams.
- **Deal & promotion tracking** — surface everything currently discounted or on multi-buy offer.
- **Catalogue & PIM enrichment** — pull names, brands, barcodes, images, Nutri-Grade and country of origin for product databases.
- **Sourcing & supplier leads** — capture the distributor behind each SKU (FairPrice "seller name") for B2B outreach.
- **Health & dietary research** — filter by Nutri-Grade or Halal/dietary attributes across a category.

### How to use

1. Click **Try for free**.
2. Add one or more **Search terms** (e.g. `milk`, `kit kat`, `olive oil`) — or paste FairPrice product / search / category **Start URLs**.
3. (Optional) Filter with **On promotion only**, **Minimum discount %**, **Nutri-Grade**, or **In stock only**.
4. Set **Max products** and click **Save & Start**.
5. Export results as JSON, CSV, Excel, or pull them via API.

### Input

| Field | Type | Description |
|---|---|---|
| `searchTerms` | array | Keywords to search (product names, brands or categories). Each is paginated up to the limits. |
| `startUrls` | array | FairPrice product, search or category URLs. Category/search URLs become a keyword search. |
| `productIds` | array | Specific FairPrice product IDs to fetch directly — ideal for monitoring a fixed basket. |
| `onOfferOnly` | boolean | Keep only products with a current discount or multi-buy promotion. |
| `minDiscountPercent` | integer | Keep only products discounted at least this % off the list price. |
| `nutriGrades` | array | Keep only products with these Nutri-Grade ratings (A/B/C/D). |
| `inStockOnly` | boolean | Skip out-of-stock products. |
| `maxItems` | integer | Maximum products across all searches (default 100). |
| `maxItemsPerSearch` | integer | Optional per-term cap so one keyword doesn't use the whole budget. |
| `monitorMode` | boolean | Output only new / price-changed products (adds `previousPrice` & `priceDelta`). |
| `monitorStoreName` | string | Named store used to remember products between runs (one per tracked basket). |
| `proxyConfiguration` | object | Proxy settings. The default Apify datacenter proxy is fast and reliable here. |

#### Example input

```json
{
  "searchTerms": ["milk", "instant noodles", "olive oil"],
  "onOfferOnly": true,
  "minDiscountPercent": 10,
  "maxItems": 500,
  "monitorMode": true,
  "monitorStoreName": "weekly-basket"
}
```

### Output

Each product is one dataset record. Example (trimmed):

```json
{
  "platform": "fairprice.com.sg",
  "productId": "1614709",
  "barcode": "8850329145980",
  "name": "Meiji Low Fat High Protein Milk - Green Tea",
  "brand": "Meiji",
  "price": 4.95,
  "listPrice": 4.95,
  "currency": "SGD",
  "discountPercent": null,
  "isOnOffer": true,
  "promotions": ["Any 6 for $21.50"],
  "displayUnit": "350ml",
  "nutriGrade": "B",
  "countryOfOrigin": "Thailand",
  "dietaryAttributes": ["Halal"],
  "isHalal": true,
  "supplier": "CROWN PACIFIC BEVERAGE PTE LTD",
  "category": "Flavoured Milk",
  "images": ["https://media.nedigital.sg/.../13282299_XL1.jpg"],
  "inStock": true,
  "rating": 4.41,
  "reviewCount": 32,
  "productUrl": "https://www.fairprice.com.sg/product/meiji-low-fat-high-protein-milk-green-tea-350ml-13282299"
}
```

Two ready-made dataset **views** are included: **Products** (pricing & key attributes) and **Nutrition & sourcing** (Nutri-Grade, origin, dietary, supplier).

> Note: **Nutri-Grade** is a Singapore Health Promotion Board label that applies to **prepacked beverages only** — it is populated for drinks (milk, juice, soft drinks) and is genuinely absent for non-beverages (oils, snacks, household goods). Discount fields appear only when a product is currently on offer.

### Monitoring mode & scheduling

Turn on **monitorMode** to remember the products already returned and emit **only** the ones that are new or whose price/stock/promotion changed since the last run (with `previousPrice` and `priceDelta`). It's the cleanest way to track price drops across a basket or category.

It is **fully compatible** with [Apify Schedules](https://docs.apify.com/platform/schedules) — they do different jobs: the schedule decides *when* the run fires (e.g. every morning), and monitoring mode decides *what* is returned (only the deltas). Point each tracked basket at its own `monitorStoreName` to keep histories separate.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily to track grocery prices and promotions; perfect for alerts and pricing dashboards.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (price alert, Slack message, sheet update) the moment a run finishes.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/fairprice-scraper').call({
    searchTerms: ['milk', 'eggs', 'rice'],
    onOfferOnly: true,
    maxItems: 500,
    monitorMode: true,
    monitorStoreName: 'weekly-basket',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} FairPrice products`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push price changes straight into Sheets, Slack or a database.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored product drops in price.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "track the price of these 20 grocery items at FairPrice every day and alert me on any drop over 10%" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **Singapore data stack**:

- **[99.co Property Scraper](https://apify.com/scrapesage/99-co-property-scraper)** — Singapore property listings & agent leads.
- **[EdgeProp.sg Scraper](https://apify.com/scrapesage/edgeprop-singapore-scraper)** — Singapore property & agent leads.
- **[SGCarMart Used Car Scraper](https://apify.com/scrapesage/sgcarmart-used-car-scraper)** — Singapore used-car prices, COE/OMV/ARF & dealer leads.
- **[MyCareersFuture Scraper](https://apify.com/scrapesage/mycareersfuture-scraper)** — Singapore jobs, salaries & employer leads.
- **[JobStreet Singapore Scraper](https://apify.com/scrapesage/jobstreet-singapore-scraper)** — Singapore jobs, salaries & company leads.
- **[Singapore Company Scraper](https://apify.com/scrapesage/singapore-company-scraper)** — UEN, registry & business leads.
- **[StreetDirectory Scraper](https://apify.com/scrapesage/streetdirectory-business-scraper)** — Singapore business directory leads.
- **[Foodpanda Scraper](https://apify.com/scrapesage/foodpanda-scraper)** — restaurants, menus & prices across APAC.

### Tips

- **Track a fixed basket**: list the exact `productIds` you care about and turn on `monitorMode` for a clean daily price-change feed.
- **Find deals fast**: set `onOfferOnly` (and optionally `minDiscountPercent`) to surface only discounted and multi-buy items.
- **Healthier picks**: filter `nutriGrades` to `["A","B"]` for beverages, or watch `dietaryAttributes`/`isHalal` across a category.
- **Cost control**: use `maxItemsPerSearch` so one broad keyword doesn't consume your whole `maxItems` budget.
- **Proxies**: the default Apify (datacenter) proxy works well and keeps costs low — FairPrice's API has no anti-bot. Switch to Residential only if you ever hit rate limits on very large runs.

### FAQ

**Is this affiliated with NTUC FairPrice?** No. This is an independent tool that collects publicly available product information from FairPrice's website.

**Do I need an API key or login?** No. The actor uses FairPrice's own public storefront endpoints — no account, key or browser needed.

**Why is `nutriGrade` empty for some products?** Singapore's Nutri-Grade applies to prepacked **beverages** only. Non-drink products (oils, snacks, household, personal care) genuinely have no Nutri-Grade.

**Can I get more than 1,000 products for one keyword?** FairPrice caps search pagination at ~1,000 results per term. Use more specific keywords, categories, or product IDs to cover more of the catalogue.

**Does monitoring mode conflict with Apify schedules?** No — schedules decide *when* a run fires; monitor mode decides *what* is returned (only new/changed products). They work together.

### Need help?

Open an issue on the actor's **Issues** tab with your input and what you expected — happy to help.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search on FairPrice (product names, brands, or categories). Each term is paginated up to the limits below. Example: \["milk", "kit kat", "olive oil"].

## `startUrls` (type: `array`):

FairPrice URLs to scrape — product pages (https://www.fairprice.com.sg/product/...), search result pages, or category pages. Category/search URLs are turned into a keyword search.

## `productIds` (type: `array`):

Specific FairPrice product IDs to fetch directly (useful for monitoring a fixed basket of SKUs).

## `onOfferOnly` (type: `boolean`):

Only output products that currently have a discount or multi-buy promotion.

## `minDiscountPercent` (type: `integer`):

Only output products discounted by at least this percentage off the list price (leave empty for no minimum).

## `nutriGrades` (type: `array`):

Only keep products with these Nutri-Grade ratings (A, B, C or D). Leave empty for all.

## `inStockOnly` (type: `boolean`):

Skip products that are currently out of stock.

## `maxItems` (type: `integer`):

Maximum number of products to write to the dataset across all searches.

## `maxItemsPerSearch` (type: `integer`):

Optional per-term cap so one broad keyword doesn't use the whole budget. Leave empty to share the global limit.

## `monitorMode` (type: `boolean`):

Remember products across runs and output only NEW products or ones whose price/stock/promotion changed (adds previousPrice & priceDelta). Ideal for daily price tracking. Works independently of Apify Scheduler.

## `monitorStoreName` (type: `string`):

Named key-value store used to remember products between runs. Use a different name per tracked basket.

## `maxConcurrency` (type: `integer`):

Maximum parallel requests to the FairPrice API.

## `proxyConfiguration` (type: `object`):

Proxy settings. The FairPrice API has no anti-bot, so the default Apify datacenter proxy is fast and reliable.

## Actor input object example

```json
{
  "searchTerms": [
    "milk",
    "instant noodles"
  ],
  "startUrls": [],
  "productIds": [],
  "onOfferOnly": false,
  "nutriGrades": [],
  "inStockOnly": false,
  "maxItems": 100,
  "monitorMode": false,
  "monitorStoreName": "fairprice-monitor",
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped FairPrice products in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "milk",
        "instant noodles"
    ],
    "startUrls": [],
    "productIds": [],
    "nutriGrades": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/fairprice-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": [
        "milk",
        "instant noodles",
    ],
    "startUrls": [],
    "productIds": [],
    "nutriGrades": [],
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/fairprice-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "milk",
    "instant noodles"
  ],
  "startUrls": [],
  "productIds": [],
  "nutriGrades": []
}' |
apify call scrapesage/fairprice-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/fairprice-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/n6Ew8VzOta8pYOp2X/builds/v56aIUn8G9p51snxe/openapi.json
