# Swiggy Scraper (`scrapedo/swiggy-scraper`) Actor

Scrape Swiggy dish prices, restaurants and full menus (price, variants, veg, rating, delivery time, FSSAI licence) for any delivery location in India. Free trial, no per-result fee. Powered by Scrape.do.

- **URL**: https://apify.com/scrapedo/swiggy-scraper.md
- **Developed by:** [scrapedo](https://apify.com/scrapedo) (community)
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

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

## Swiggy Scraper

Scrape food data from [Swiggy](https://www.swiggy.com), India's food delivery app, **for any delivery location**:

- **Dish prices:** search a dish (biryani, pizza, dosa) and get every matching dish from the restaurants that deliver there, with **price, variant prices, veg flag, bestseller flag, rating** and the restaurant's rating and delivery time.
- **Restaurants:** search results or the restaurants Swiggy shows nearby, with **rating, rating count, cost for two, delivery time, distance, cuisines** and whether the listing is an ad.
- **Full menus:** paste restaurant URLs and get **every dish on the menu**, plus the restaurant's **FSSAI licence** and full address.

**Free to try:** run it without any setup and get up to 50 rows per run. Add your free Scrape.do API token to remove the limit.

### Why most Swiggy scrapers fail

1. **AWS WAF.** Swiggy answers scripts with HTTP 202 and an empty body (an `x-amzn-waf-action: challenge` header) or with a 403 page. This actor fetches Swiggy's data through the [Scrape.do](https://scrape.do/?utm_source=apify\&utm_medium=actor\&utm_campaign=swiggy-scraper) web scraping API from India.
2. **The page has no data.** A restaurant page is an empty shell; the menu arrives later from a JSON API. The actor reads Swiggy's own JSON endpoints for search, the home page and menus, so there is no browser and no HTML parsing.
3. **Location decides everything.** Which restaurants deliver, how far they are and how long delivery takes depend on the address. In our test the same "biryani" search returned 50 restaurants in Bengaluru and 50 in Mumbai, none in common. Pick a city or enter exact coordinates.
4. **Prices are in paise and menus repeat.** Swiggy sends ₹420 as `42000`, and the "Recommended" section repeats dishes from other sections (168 dish cards, 148 dishes at one Starbucks). The actor converts prices to rupees and keeps each dish once.

### What data you get

Every row has a `type`: `dish` (search result), `restaurant` (search or nearby) or `menuItem` (full menu).

| Field | Description |
|---|---|
| `dishName`, `category`, `priceInr`, `variants` | Dish name, menu section, price in rupees, and every size/option with its price |
| `isVeg`, `inStock`, `bestseller`, `dishRating`, `dishRatingCount` | Veg flag, availability, Swiggy's bestseller ribbon, dish rating |
| `restaurantName`, `restaurantId`, `area`, `cuisines` | The restaurant |
| `rating`, `ratingCount` / `restaurantRating` | Restaurant rating (restaurant rows / dish rows) |
| `costForTwoInr`, `deliveryTimeMin`, `distanceKm`, `serviceable`, `isOpen` | For this delivery location |
| `promoted`, `restaurantPromoted` | True when Swiggy shows the restaurant as a paid placement |
| `fssaiLicense`, `address` | On menu rows: the restaurant's FSSAI licence number and full address |
| `restaurantUrl`, `image`, `query`, `latitude`, `longitude`, `scrapedAt` | Links, the search query, the location used and the time |

### How to use it

1. **Dish prices:** add **Search queries** (`biryani`, `paneer tikka`) and keep **Search results** on *Dishes*.
2. **Restaurants:** switch **Search results** to *Restaurants*, or turn on **Nearby restaurants**.
3. **Menus:** paste **Restaurant URLs** (`https://www.swiggy.com/city/bangalore/starbucks-coffee-ashok-nagar-rest124178`). Find them by opening a restaurant on swiggy.com.
4. **Location:** choose a **City**, or enter **Latitude** and **Longitude** for an exact address.

#### Input example

```json
{
    "searchQueries": ["biryani", "pizza"],
    "searchFor": "dishes",
    "restaurantUrls": ["https://www.swiggy.com/city/bangalore/starbucks-coffee-ashok-nagar-rest124178"],
    "city": "mumbai",
    "maxItems": 1000,
    "scrapeDoToken": "YOUR_SCRAPEDO_TOKEN"
}
```

#### Output example

A dish row (fictional restaurant, illustrative values):

```json
{
    "type": "dish",
    "query": "biryani",
    "dishName": "Paneer Dum Biryani",
    "category": "Biryani",
    "priceInr": 249,
    "variants": [{ "variant": "Half", "priceInr": 249 }, { "variant": "Full", "priceInr": 389 }],
    "isVeg": true,
    "inStock": true,
    "bestseller": true,
    "dishRating": 4.4,
    "dishRatingCount": 210,
    "restaurantName": "Example Biryani House",
    "restaurantRating": 4.3,
    "deliveryTimeMin": 28,
    "restaurantPromoted": false,
    "restaurantUrl": "https://www.swiggy.com/city/bangalore/example-biryani-house-koramangala-rest5001",
    "latitude": 19.076,
    "longitude": 72.8777,
    "scrapedAt": "2026-11-05T05:00:00.000Z"
}
```

Download the results as JSON, CSV, Excel or HTML from the run's **Output** tab, or pull them through the Apify API.

### Pricing and your Scrape.do token

There is no per-result fee for this actor; Apify only bills its normal platform usage. Swiggy's data is fetched through the Scrape.do web scraping API:

1. **Free trial, no token:** leave the **Scrape.do API token** field empty and you get up to 50 rows per run.
2. **Your own Scrape.do token:** no row limit. Each request is 1 Scrape.do credit: one per search query (all results), one for the nearby list, one per restaurant menu. Ten menus and two searches cost 12 credits. [Create a free Scrape.do account](https://scrape.do/?utm_source=apify\&utm_medium=actor\&utm_campaign=swiggy-scraper) for 1,000 free credits a month.

### Good to know

- **Location matters.** Every row records the latitude and longitude it was scraped for. A menu still loads for a far-away location, with `serviceable: false`.
- **Search returns sides too.** A "biryani" search also returns raita and pappadam from the same restaurants; filter on `dishName` if you only want the dish.
- **Prefer Python?** The same logic is an open-source package: `pip install swiggy-scraper` ([GitHub](https://github.com/bugrahansss/swiggy-scraper)).

### FAQ

**Is scraping Swiggy legal?** The actor calls the JSON endpoints Swiggy's own web pages use for search, the home page and menus. Swiggy's robots.txt allows these paths and disallows account, cart, checkout, order tracking and payment pages, which the actor never touches. Restaurant and menu data is not personal data. Read Swiggy's terms of use for your use case and keep request rates modest. This is not legal advice.

**Something broke or a field is missing?** Open an issue in the Issues tab and we will look at it.

# Actor input Schema

## `searchQueries` (type: `array`):

Dishes or restaurants to search for, e.g. biryani, pizza, dosa. Each query is one request and returns every result Swiggy shows for it (about 50 restaurants for dishes, about 100 for restaurants).

## `searchFor` (type: `string`):

Dishes: every matching dish with price, veg flag, rating and variants, plus its restaurant. Restaurants: matching restaurants with rating, cost for two and delivery time.

## `restaurantUrls` (type: `array`):

Swiggy restaurant pages, e.g. https://www.swiggy.com/city/bangalore/starbucks-coffee-ashok-nagar-rest124178. Each one returns the full menu, one row per dish, with the restaurant's FSSAI licence and address. One request per restaurant.

## `nearbyRestaurants` (type: `boolean`):

Also save the restaurants Swiggy shows on its home page for this location (about 25). One request.

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

Used when latitude and longitude are empty.

## `latitude` (type: `string`):

Optional. Exact delivery latitude, e.g. 12.9352. Overrides the city.

## `longitude` (type: `string`):

Optional. Exact delivery longitude, e.g. 77.6245. Overrides the city.

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

Stop after this many rows in total. Set 0 for no limit. Without your own Scrape.do token the free trial returns up to 50 rows per run.

## `scrapeDoToken` (type: `string`):

Optional. Find it in your Scrape.do dashboard. Leave empty for the free trial (up to 50 rows per run).

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

How many menus are fetched at the same time when you use your own token. Keep it at or below your Scrape.do plan's concurrency.

## Actor input object example

```json
{
  "searchQueries": [
    "biryani"
  ],
  "searchFor": "dishes",
  "nearbyRestaurants": false,
  "city": "bengaluru",
  "maxItems": 20,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

No description

## `allFields` (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 = {
    "searchQueries": [
        "biryani"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapedo/swiggy-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 = {
    "searchQueries": ["biryani"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapedo/swiggy-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 '{
  "searchQueries": [
    "biryani"
  ],
  "maxItems": 20
}' |
apify call scrapedo/swiggy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapedo/swiggy-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/4n71eZJM7pMAoHIdJ/builds/x6dVRf63tivxDI1HP/openapi.json
