# Grab Scraper - GrabFood Menus & GrabMart Data (`adamdd/grab-scraper`) Actor

Extract GrabFood restaurants, menus, and GrabMart products across eight Southeast Asian markets. Get merchant IDs, public URLs, ratings, and prices when available. Pay per delivered row plus a start fee.

- **URL**: https://apify.com/adamdd/grab-scraper.md
- **Developed by:** [Adam D](https://apify.com/adamdd) (community)
- **Categories:** E-commerce, Travel, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Grab Scraper

**Turn Grab restaurant and menu information into ready-to-use tables.**

Enter a keyword or a restaurant link. Collect names, ratings, menu items and published prices, then export to Excel for market research and competitor comparisons.

![Enter a keyword or Grab link, collect restaurant and menu data, then export a table](https://api.apify.com/v2/key-value-stores/KYRUZNW5JqoEefoUH/records/grab-overview-en-v1.png)

- **No coding required:** fill in the form in Apify Console.
- **Pay per delivered row:** $2.00 per 1,000 rows on the Free plan, plus a start fee.
- **Control your spend:** set a result limit and a maximum charge per run.

### Three ways to use it

| Your goal | What you can collect | How to start |
| --- | --- | --- |
| **Find restaurants** | Restaurant names, ratings, source links and other public details | Choose a country and enter a keyword |
| **Explore a menu** | Item names, categories and published prices from a specific restaurant | Enter a restaurant URL and enable menu items |
| **Find GrabMart merchants** | Grocery and other retail merchants | Select GrabMart feed |

GrabMart merchant search returns **shops**, not a complete product catalog. Available fields vary by location, merchant and collection mode.

### See what you will get

Restaurants and menu items appear as separate rows. Download the table to filter, sort and compare results.

![Illustrative restaurant and menu tables showing Example Kitchen, a rating, Chicken rice and its price; not live results](https://api.apify.com/v2/key-value-stores/KYRUZNW5JqoEefoUH/records/grab-results-example-en-v1.png)

**The image uses example data, not results from a live run.** Column labels are simplified for readability. Actual output uses the field names below; content retains the source language.

| Data type | Common fields |
| --- | --- |
| Restaurant or merchant | `name`, `merchantId`, `url`, `rating`, `countryCode` |
| Menu item | `name`, `section`, `price`, `currency`, `restaurantName` |

Fields are populated only when Grab provides them. Missing values stay empty.

### Get started in three steps

1. **Enter your target.** Open [Grab Scraper](https://console.apify.com/actors/DSY9Unb5gcWR4eOEl/input) and leave Mode on Auto. For a small first run, choose **Philippines**, enter `pizza` as the **Keyword**, and set **Max results** to `3`.
2. **Start the run.** Check **Maximum cost per run**, click **Start**, and wait for completion.
3. **Download your results.** Open the run's dataset, review the rows, and export as **Excel, CSV or JSON**.

Start with a small collection in your chosen location. The result limit is a cap, not a guaranteed number of results.

**Want menu items?** Enter a specific Restaurant URL and enable Include menu items. Keyword searches alone do not fetch complete menus.

### Pricing

You pay for **each delivered row**, plus a start fee. All prices are in USD.

| Apify plan | Per 1,000 rows | Start fee at default memory |
| --- | --- | --- |
| Free | **$2.00** | $0.005 |
| Bronze | $1.80 | $0.005 |
| Silver | $1.60 | $0.005 |
| Gold / Platinum / Diamond | $1.40 | $0.005 |

"Free" is the name of an Apify membership tier; **this Actor is not free to run**. The start fee above assumes the default 1024 MB memory. Start events are charged once per GB of allocated memory, with a minimum of one event.

**Small-run example:** a default-memory run delivering 3 rows on the Free plan costs:

**3 × $0.002 + $0.005 = $0.011.**

- **1 restaurant + 10 menu items = 11 rows.** Restaurant and menu rows have the same unit price and share the result limit.
- `maxResults` applies per input target. For multiple links, also set a maximum charge to control the total run cost.
- A start fee can apply even when no rows are returned.
- The Free plan currently has publisher-set limits of 200 rows per run and 10 runs of this Actor.

### Coverage and limitations

Market options include **Singapore, Malaysia, Philippines, Thailand, Vietnam, Indonesia, Cambodia and Myanmar**. Selecting a country does not guarantee every mode is available or verified there. Test a small collection in your target location first.

- **Core use cases:** restaurant search, menus from specific restaurants, and GrabMart merchant discovery.
- **Known restrictions:** chain searches and GrabMart directory modes currently have access limitations.
- **Some fields may be empty:** phone numbers, emails, addresses and prices are not guaranteed. Directory entries do not confirm opening status or stock.
- **Public information only:** login-only member prices, private accounts, orders and rides are outside this Actor's scope.
- **Fewer results than expected?** Check the run log and result summary. Source availability, location restrictions and spending limits can reduce the number of delivered rows.

### FAQ

#### What can I use the data for?

Build restaurant lists, compare menus and prices, or support market research. For repeated checks, use Apify Schedules. Each run is charged at the applicable rate.

#### Why is a menu incomplete?

Restaurant and menu rows share the result limit. A limit of 3 may return one restaurant and two menu items. Increase the limit if you need more items, and check your spending settings. Items that are not available from the source cannot be supplied.

#### Can I use this with code or an AI agent?

Yes. The Actor identifier is `adamdd/grab-scraper`. Use the Apify API or a compatible Apify MCP client. A small search input is:

```json
{"keyword": "pizza", "countryCode": "ph", "maxResults": 3}
```

See the **API** tab on this page for integration examples.

#### How do I get help?

Use the **Issues** tab and include the run ID, your input and the expected result. Remove credentials before sharing.

***

Grab Scraper is provided by **adamdd**. It is an independent tool, **not affiliated with or endorsed by Grab**. Use public data in accordance with applicable laws and platform terms.

# Actor input Schema

## `mode` (type: `string`):

Leave on Auto: the mode is picked from the field you fill (Start URLs, Restaurant URL, Merchant ID, Mart item ID, Chain name, Cuisine slug or Keyword). Pick a mode to run feeds that need no target (recommended, discoverCategories, directory, mart_items, mart_merchants).

## `countryCode` (type: `string`):

Grab market country code

## `keyword` (type: `string`):

What to search for, for example pizza or milk tea. With mode Auto a keyword runs a restaurant search; mart mode uses it for groceries; cuisine mode uses it when Cuisine slug is empty.

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

food.grab.com / mart.grab.com links (restaurants, cuisine pages, mart pages). One target per line.

## `restaurantUrl` (type: `string`):

Paste a full GrabFood restaurant link, or a complete GrabMart product link with mode mart_item. Keep the item and merchant identifiers and URL text in the link.

## `merchantId` (type: `string`):

Grab merchant identifier. In Auto mode, this selects restaurant details.

## `itemId` (type: `string`):

GrabMart product identifier for mart_item mode. Also supply itemSlug, or use a complete product link in restaurantUrl.

## `chainName` (type: `string`):

For mode=chain — brand / chain keyword or slug

## `cuisineSlug` (type: `string`):

For mode=cuisine — e.g. pizza, chicken, mart-delivery

## `maxResults` (type: `integer`):

Most rows for each keyword, start URL, restaurant, cuisine, chain, or directory target. Default 70; larger numbers are collected in parts of 70. Restaurants, menu items, branch merchants, categories, promos, and labels all count together. The whole run stops at your maximum total charge. Free Apify plan: up to 200 rows per run and 10 runs of this Actor (limits set by the Actor developer).

## `city` (type: `string`):

Optional delivery city slug (e.g. makati, cebu, chiang-mai, hanoi, bali). Leave empty to use the market's main city. Ignored when latlng is set; restaurant/startUrls URLs from another market use their own market's location.

## `latlng` (type: `string`):

Optional delivery pin as "latitude,longitude" (e.g. 14.5547,121.0244). Overrides city.

## `businessType` (type: `string`):

Filter search/recommended results

## `includeMenuItems` (type: `boolean`):

For restaurant mode and restaurant links in startUrls, add menu items as separate billed rows within maxResults. Listing modes return merchants without menu items.

## `maxMenuItemsPerRestaurant` (type: `integer`):

Per-restaurant cap. Menu items still count within that input's maxResults budget.

## `expandBranches` (type: `boolean`):

Include additional branch merchants when available. Each branch is a separately billed row within maxResults.

## `emitCuisines` (type: `boolean`):

Include available cuisine tags as separate category rows. Each category row is billed and counts toward maxResults.

## `emitPromoLabels` (type: `boolean`):

Include available promotions and labels as separate rows. Each row is billed and counts toward maxResults.

## `merchantSlug` (type: `string`):

URL slug for restaurant or mart merchant detail

## `itemSlug` (type: `string`):

For mode=mart_item — product slug in the item URL path

## `cuisineId` (type: `string`):

Optional cuisine numeric/string id for /cuisines/{slug}/{id}

## `lang` (type: `string`):

Path locale (en/th/vi/id/ms/zh/km depending on market)

## `pageSize` (type: `integer`):

Number of merchants requested per page, from 1 to 32. Continuing with a cursor retains its saved page size.

## `cursor` (type: `object`):

Paste nextCursor from a previous RUN_SUMMARY to continue with the same mode, market, location, and query. Live listings can change, so deduplicate identifiers across runs.

## `sitemapCity` (type: `string`):

Published city slug for directory, mart_items, or mart_merchants, such as singapore. Directory mode without a city includes published cities; GrabMart directory modes can use the delivery city.

## `sitemapShard` (type: `integer`):

Zero-based sitemap file index for directory modes. Continue from the position in RUN_SUMMARY.nextCursor.

## `sitemapOffset` (type: `integer`):

Zero-based entry position within a sitemap file for directory modes. Continue from the position in RUN_SUMMARY.nextCursor.

## `sitemapMaxShards` (type: `integer`):

Maximum sitemap shards read in this run.

## `modifiedSince` (type: `string`):

Optional inclusive sitemap lastmod date (YYYY-MM-DD), not a menu or price-change timestamp. A filtered slice may return zero results.

## `enrichDetails` (type: `boolean`):

In directory mode, check up to maxEnrich merchant pages for public details. Pages without confirmed merchant data remain directoryOnly=true.

## `maxEnrich` (type: `integer`):

Directory mode with enrichDetails: maximum public merchant pages to inspect.

## `useSeedPool` (type: `boolean`):

In restaurant or mart_item mode, select previously discovered URLs when no target identifier or URL is supplied. Empty or expired saved URLs cannot provide a detail target.

## `seedCount` (type: `integer`):

Maximum number of previously discovered URLs to select when useSeedPool is enabled.

## `seedFamily` (type: `string`):

Choose mart_items, mart_merchants, or food_merchants. Leave empty to use the group selected by the detail mode.

## `seedPoolMaxAge` (type: `integer`):

Saved URL collections older than this limit are treated as unavailable. Supply an explicit target if no recent URLs exist.

## `persistSeen` (type: `boolean`):

Remember delivered row identifiers so a later run of the same mode, market, city, and keyword can skip them. Leave off when you want to collect updated values for the same entities.

## `proxyCountry` (type: `string`):

Optional country code for chain requests. Leave empty to use the selected market.

## `workerBaseUrl` (type: `string`):

Leave empty. Used only by the developer for testing.

## Actor input object example

```json
{
  "mode": "auto",
  "countryCode": "ph",
  "keyword": "pizza",
  "maxResults": 3,
  "businessType": "ALL",
  "includeMenuItems": false,
  "maxMenuItemsPerRestaurant": 25,
  "expandBranches": false,
  "emitCuisines": false,
  "emitPromoLabels": false,
  "lang": "en",
  "pageSize": 32,
  "sitemapShard": 0,
  "sitemapOffset": 0,
  "sitemapMaxShards": 1,
  "enrichDetails": false,
  "maxEnrich": 5,
  "useSeedPool": false,
  "seedCount": 3,
  "seedPoolMaxAge": 86400,
  "persistSeen": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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 = {
    "mode": "auto",
    "countryCode": "ph",
    "keyword": "pizza",
    "maxResults": 3,
    "businessType": "ALL",
    "includeMenuItems": false,
    "maxMenuItemsPerRestaurant": 25,
    "expandBranches": false,
    "emitCuisines": false,
    "emitPromoLabels": false,
    "lang": "en",
    "pageSize": 32,
    "maxEnrich": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("adamdd/grab-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 = {
    "mode": "auto",
    "countryCode": "ph",
    "keyword": "pizza",
    "maxResults": 3,
    "businessType": "ALL",
    "includeMenuItems": False,
    "maxMenuItemsPerRestaurant": 25,
    "expandBranches": False,
    "emitCuisines": False,
    "emitPromoLabels": False,
    "lang": "en",
    "pageSize": 32,
    "maxEnrich": 5,
}

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

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

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

```

## CLI example

```bash
echo '{
  "mode": "auto",
  "countryCode": "ph",
  "keyword": "pizza",
  "maxResults": 3,
  "businessType": "ALL",
  "includeMenuItems": false,
  "maxMenuItemsPerRestaurant": 25,
  "expandBranches": false,
  "emitCuisines": false,
  "emitPromoLabels": false,
  "lang": "en",
  "pageSize": 32,
  "maxEnrich": 5
}' |
apify call adamdd/grab-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,adamdd/grab-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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