# Grab All-in-One Api (`romy/grab-api`) Actor

Grab All-in-One API is a unified REST endpoint for querying GrabFood and Grab data — restaurant search, nearby merchants, menu details, reviews, ride pricing, and nearby drivers

- **URL**: https://apify.com/romy/grab-api.md
- **Developed by:** [Romy](https://apify.com/romy) (community)
- **Categories:** Developer tools, Other
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.90 / 1,000 grabfood searches

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

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

### What does Grab All-in-One API do?

**Grab All-in-One API** is a unified REST endpoint for querying GrabFood and Grab data — restaurant search, nearby merchants, menu details, reviews, ride pricing, and nearby drivers — all from a single always-on API powered by [Apify Standby](https://docs.apify.com/platform/actors/development/programming-interface/standby).

No scraping setup required. Call the endpoint, get JSON back instantly.

### Why use Grab All-in-One API?

- **All Grab data in one place** — no need to manage 6 separate actors
- **Always-on** — no cold start, responds in milliseconds
- **Standard REST** — works with any language: curl, Python, JavaScript, Postman
- **Use cases:** restaurant aggregators, delivery price comparison, driver availability monitoring, competitor research, food trend analysis

### Endpoints

| Method | Path | Description | Price |
|--------|------|-------------|-------|
| `GET` | `/grabfood/search` | Search restaurants by keyword + location | $0.005/call |
| `GET` | `/grabfood/nearby` | List all nearby restaurants at a location | $0.005/call |
| `GET` | `/grabfood/detail` | Get full detail for one or more merchant IDs | $0.015/call |
| `GET` | `/grabfood/reviews` | Get customer reviews for a merchant | $0.010/call |
| `POST` | `/grab/ride-price` | Get fare quotes for one or more routes | $0.010/call |
| `GET` | `/grab/drivers` | Get nearby available drivers at a location | $0.010/call |
| `GET` | `/grab/place-search` | Search/autocomplete places by keyword near a location | $0.008/call |
| `GET` | `/grab/reverse-geocode` | Get the nearest address/place for a coordinate | $0.005/call |

### How to use

1. Go to [Apify Store](https://apify.com/romy/grab-api) and click **Try for free**
2. The actor runs in Standby mode — it starts once and stays alive
3. Call the API using your Apify token:

```bash
curl "https://romy--grab-api.apify.actor/grabfood/search?keyword=ayam+goreng&lat_lng=-6.1754,106.8272&max_items=10" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN"
```

### Input (Query Parameters)

All responses follow this format:

```json
{ "success": true, "data": [...], "count": 30, "nextCursor": "30", "hasMore": true }
```

Pass `nextCursor` as `cursor` in the next request to get the next page. When `hasMore` is `false`, you've reached the end. **Each page = 1 API call = 1 charge.**

#### GET `/grabfood/search`

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `keyword` | string | required | Search keyword (e.g. `"ayam goreng"`) |
| `lat_lng` | string | Jakarta center | Coordinates `"lat,lng"` |
| `cursor` | string | `"0"` | Pagination cursor from previous response |

#### GET `/grabfood/nearby`

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `lat_lng` | string | Jakarta center | Coordinates `"lat,lng"` |
| `cursor` | string | `"0"` | Pagination cursor from previous response |

#### GET `/grabfood/detail`

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `merchant_ids` | string | required | Comma-separated IDs, e.g. `"ID-GF-xxx,ID-GF-yyy"` |
| `lat_lng` | string | Jakarta center | Coordinates `"lat,lng"` |

#### GET `/grabfood/reviews`

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `merchant_id` | string | required | Single merchant ID |
| `cursor` | string | `""` | Pagination cursor from previous response |
| `language` | string | `en-US` | Review language |

#### POST `/grab/ride-price`

Body (JSON):

```json
{
  "routes": [
    {
      "origin": { "latitude": -6.1754, "longitude": 106.8272 },
      "destination": { "latitude": -6.2088, "longitude": 106.8123 }
    }
  ]
}
```

#### GET `/grab/drivers`

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `lat` | number | required | Latitude |
| `lng` | number | required | Longitude |
| `service_id` | integer | 97 | Grab service type ID |

#### GET `/grab/place-search`

Search for a place by name/address near a location — useful for turning a place name into the `lat_lng` every other endpoint needs.

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `keyword` | string | required | Place name or address, e.g. `"Monas"` |
| `lat_lng` | string | Jakarta center | Coordinates to search near, `"lat,lng"` |

#### GET `/grab/reverse-geocode`

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `lat_lng` | string | required | Coordinates `"lat,lng"` |

### Output Example

```json
{
  "success": true,
  "count": 2,
  "data": [
    {
      "id": "6-C32KCBBWV3BDTT",
      "address": { "name": "Popeyes Chicken - Skyline", "city": "Jakarta" },
      "estimatedDeliveryTime": 30,
      "merchantBrief": {
        "cuisine": ["Western", "Fried Chicken"],
        "halal": true,
        "rating": 4.7,
        "vote": 1200
      }
    }
  ]
}
```

### Pricing

This Actor uses **Pay Per Event** billing — you only pay for successful API calls.

| Endpoint | Price per call |
|----------|---------------|
| `/grabfood/search` | $0.005 |
| `/grabfood/nearby` | $0.005 |
| `/grabfood/detail` | $0.015 |
| `/grabfood/reviews` | $0.010 |
| `/grab/ride-price` | $0.010 |
| `/grab/drivers` | $0.010 |
| `/grab/place-search` | $0.008 |
| `/grab/reverse-geocode` | $0.005 |

**Example:** 1,000 search calls = $5. Failed requests (4xx/5xx) are not charged. You get $5 free credit on signup.

### Known limitations

- **Auth is a single, hardcoded personal account JWT** (`src/scrapers/grab.ts`), not a device-only/anonymous credential. Every call to every endpoint authenticates as one specific Grab account — if that account gets flagged, rate-limited, or logged out by Grab, the whole API breaks for every caller at once until the token is replaced. This is the same risk category as Google Maps's `ListPromotedPinAds` (documented in `google-maps-all-in-one-api`'s README) — it works today, but there's no fallback if the account goes bad.
- **GrabMart (grocery delivery) isn't exposed**, despite the app having a parallel `grabmart/*` API namespace to GrabFood's (`location-merchants`, `category-tree`, etc.). Every shape tried (`GET` with query params, `POST` with a JSON body matching GrabFood's own pattern) returned `400`/`502` — the real request shape wasn't found in the time spent, and wasn't worth guessing further without a live traffic capture.
- **`/grabfood/search/hints` (autocomplete) and `reviews/v1/merchants/review-summary` (aggregate rating stats) aren't exposed** — both return `200` with empty bodies regardless of parameter name/method tried; the real trigger condition wasn't identified.

### FAQ

**Does this work outside Indonesia?**
GrabFood is available across Southeast Asia — pass the correct `lat_lng` for your target city.

**Is this official?**
No. This is an independent tool using Grab's internal API. Use responsibly and in accordance with Grab's Terms of Service.

**Need a custom integration?**
Contact me at romysaputrasihanandaa@gmail.com or [hire me on Fiverr](https://www.fiverr.com/romyssss).

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

## `api` (type: `string`):

This Actor doesn't write to a dataset — every response is returned directly over HTTP by its Standby web server. See the README / web server OpenAPI schema (webServerSchema) for the full endpoint list and response shapes (GET /grabfood/search, /grabfood/nearby, /grabfood/detail, /grabfood/reviews, /grab/place-search, /grab/reverse-geocode, /grab/drivers, POST /grab/ride-price).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("romy/grab-api").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("romy/grab-api").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 '{}' |
apify call romy/grab-api --silent --output-dataset

```

## MCP server setup

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

```

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/4JISpsO8oLOjbUnl8/builds/ljMNc49BfbfTGdTAo/openapi.json
