# Glovo Scraper (`solidcode/glovo-scraper`) Actor

\[💰 $2.0 / 1K] Extract Glovo store listings and menu data across restaurants, groceries, pharmacy & beauty, and shops in 1,316 cities across 24 countries. Scrape any city by name or paste store links to get ratings, review volume, base delivery fees, promotions, availability, and menu prices.

- **URL**: https://apify.com/solidcode/glovo-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 17 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Glovo Scraper

Pull store listings and full menus from Glovo across the 1,316 cities in 24 countries Glovo's own city directory lists — restaurants, grocery stores, pharmacies, and retail shops, with ratings, base delivery fees, local currency, live promotions, availability, and per-item prices. Built for food-delivery market analysts, q-commerce competitive-intelligence teams, and restaurant-supply lead generators who need fresh Glovo catalog and pricing data without collecting it merchant by merchant.

### Why This Scraper?

- **All 1,316 Glovo cities in 24 countries** — the city you type is matched against Glovo's own delivery-city directory, so Nairobi, Zagreb, Tbilisi, and Casablanca work exactly like Madrid. Coverage runs from Spain (353 cities), Italy (290), and Poland (206) through Morocco, Kenya, Nigeria, Georgia, and Kazakhstan.
- **Wrong city name? The run tells you the right one.** Type a spelling Glovo doesn't use and you get the closest cities Glovo really delivers to, by name, instead of a silent empty file.
- **4 store verticals in one run** — restaurants, groceries, pharmacy & beauty, and shops, from a single city + vertical picker. A single "All verticals" run on Warsaw returned 150 stores spread across all four in 22 seconds.
- **Complete menus with a price on every line** — a Valencia run pulled 337 menu rows from 3 restaurants (68, 91, and 178 items), each with numeric price, formatted display price, currency, product ID, menu section, and image URL, joined to its parent store.
- **Delivery economics in the local currency** — a real, varying base delivery fee and currency code on 100% of measured store rows: 40 distinct fee values across EUR, PLN, UAH, and RON in one 453-store sample.
- **Typed promotions, not just a "deal" flag** — four promotion kinds (percentage discount, basket discount, two-for-one, flat product price) each with benefit and description, on roughly a third of stores, plus Glovo's top-rated badge.
- **8 interface languages, independent of the city** — English, Spanish, Portuguese, Italian, French, Polish, Ukrainian, and Romanian. Language picks the wording, not the country, so you can read Nairobi's listings in French or Lisbon's in English.
- **A Max Results ceiling, 20,000 rows by default** — a broad sweep with menus switched on cannot quietly turn into a hundred-thousand-row bill. The run stops at your number and says it stopped there.
- **A finishing summary that admits what it missed** — if the run ended early because of your result limit, your store limit, or Glovo showing only one page per category, the last message names which one and what to change. It says "Done!" only when nothing held it back.

### Use Cases

**Market Research**

- Map every restaurant, grocer, pharmacy, and shop operating in a Glovo city
- Compare base delivery fees and local pricing across an entire vertical
- Track which merchants carry Glovo's top-rated badge in a market

**Competitive Intelligence**

- Watch a named competitor's full menu and prices with direct store links
- Benchmark a chain's offering across multiple cities and countries
- Measure how many stores in a vertical are running an active promotion

**Price Monitoring**

- Track item-level prices over time for a basket of grocery products
- Compare the same dish or product across competing stores in one city
- Detect discount campaigns starting and ending between runs

**Menu & Catalog Aggregation**

- Build a unified product feed across dozens of stores in a vertical
- Power a price-comparison or aggregator site with structured catalog rows
- Localize the same catalog into 8 languages for multi-market listings

**Lead Generation for Restaurant Suppliers**

- Build outreach lists of restaurants by cuisine tag and city
- Prioritize prospects by rating, review volume, and promotion activity
- Enrich a target list with store links, base fees, and open/closed status

### Getting Started

#### Discover a Vertical in One City

The simplest run — all restaurants in Barcelona, store listings only:

```json
{
    "city": "Barcelona",
    "storeCategory": "food",
    "maxStores": 50
}
```

#### A Localized Sweep in Another Country

Every grocery store in Bucharest, with Romanian names and RON prices:

```json
{
    "city": "Bucharest",
    "storeCategory": "groceries",
    "language": "ro",
    "maxStores": 50
}
```

#### Specific Stores With Full Menus

Paste exact store links and pull every product for each:

```json
{
    "storeUrls": [
        "https://glovoapp.com/en/es/barcelona/stores/vicio-barcelona"
    ],
    "includeProducts": true,
    "maxStores": 10
}
```

#### Full Menu Sweep With a Cost Ceiling

Scrape restaurants in Lisbon with every menu item, capped at 5,000 rows:

```json
{
    "city": "Lisboa",
    "storeCategory": "food",
    "includeProducts": true,
    "maxStores": 20,
    "maxResults": 5000,
    "language": "pt"
}
```

### Input Reference

The values below are what the Apify UI prefills. A run that names neither a city nor a store link is declined with a short message rather than quietly sweeping some default city.

#### What to Scrape

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `city` | string | `"Barcelona"` | The Glovo city to scrape, by name. Use the name Glovo itself uses: for some cities that is the local spelling (`Lisboa`, `Warszawa`), for others the English one (`Bucharest`). Working examples: Barcelona, Madrid, Lisboa, Warszawa, Bucharest. If the name isn't found, the run names the closest cities Glovo does deliver to. |
| `storeCategory` | string | `"all"` | Which kind of stores to collect: All verticals, Food & Restaurants, Groceries, Pharmacy & Beauty, or Shops. "All verticals" covers everything Glovo offers in the city. |
| `categoryFilters` | string\[] | `[]` | Optionally narrow a vertical to specific cuisines or sub-types, one per line. Each filter pulls its own set of stores, so filters are the way to reach past the one-page-per-vertical limit. |
| `storeUrls` | string\[] | `[]` | Paste specific Glovo store links to scrape exactly those stores, one per line. Products are always collected for these. Leave empty to discover stores from the city and vertical above. |

#### Options

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `includeProducts` | boolean | `false` | Also collect the full product or menu list for each store. This adds a lot of rows: roughly **70–180 per restaurant** and up to about **3,000 for a large supermarket**, on top of one row per store. Restaurants and normal shops return their whole menu. Very large grocery and quick-commerce stores are **sampled** — the top aisles to a safe depth, stopping at roughly 3,000 products per store — so a hypermarket's catalog may be partial. |
| `maxStores` | integer | `50` | How many stores to keep. Each vertical returns up to about **50 stores** (Glovo's public listing limit), so one vertical can't exceed ~50 no matter what you set. To collect more, choose **All verticals** (each vertical adds its own ~50, about 200 in total) or add several **Sub-type Filters**. This also caps pasted **Store Links**: paste more links than this number and only the first ones are collected, so raise it for a long list. Setting `0` lifts the store cap; **Max Results** still bounds the run. |
| `maxResults` | integer | `20000` | Total rows a single run will deliver, store rows and product rows counted together. It exists so a broad run can't quietly become a very large one. The run stops cleanly at this number and tells you it did, so you always know whether you got everything. Raise it if you genuinely need more. |
| `language` | string | `"en"` | Wording for store and product names and descriptions: English, Spanish, Portuguese, Italian, French, Polish, Ukrainian, or Romanian. Independent of the city — any language works with any Glovo country. |

### Output

Every row carries a `recordType` field — `store` or `product` — so you can filter the dataset cleanly. Product rows are present only when **Include products** is enabled or when store links are supplied.

#### Store (`recordType: "store"`)

```json
{
    "recordType": "store",
    "title": "VIPS",
    "slug": "vips-madrid1",
    "url": "https://glovoapp.com/en/es/madrid/stores/vips-madrid1",
    "rating": 97,
    "votes": "96",
    "deliveryFeeBase": 3.5,
    "currency": "EUR",
    "availability": "OPEN",
    "promotions": [
        { "type": "PERCENTAGE_DISCOUNT", "benefit": "-30%", "description": "some items" }
    ],
    "tag": "American",
    "isTopRated": false,
    "isNew": false,
    "category": "food_1",
    "city": "Madrid"
}
```

##### Core Fields

| Field | Type | Description |
|-------|------|-------------|
| `recordType` | string | Always `"store"` |
| `title` | string | Store display name |
| `slug` | string | URL-friendly store identifier |
| `url` | string | Full Glovo store page link |
| `tag` | string | Cuisine or store-type tag (e.g. Burgers, Sushi, Supermarket) |
| `category` | string | The vertical the store was found under |
| `city` | string | City the store belongs to |

##### Reputation & Offers

| Field | Type | Description |
|-------|------|-------------|
| `rating` | number | Rating percentage (e.g. `97`). Empty for stores Glovo hasn't rated yet — about 1 in 6 rows in a mixed 453-store sample, and none at all in busy restaurant verticals like Madrid and Milan. |
| `votes` | string | Review volume. Often an exact count (`"96"`, `"322"`), but Glovo publishes a band instead for its busiest merchants (`"500+"`, `"1k+"`, `"9k+"`) — close to half the rows in a big-city restaurant vertical. Treat it as text, not a number to sort on. |
| `promotions` | object\[] | Active promotions, each `{ type, benefit, description }`. Types seen: `PERCENTAGE_DISCOUNT`, `BASKET_PERCENTAGE`, `TWO_FOR_ONE`, `FLAT_PRODUCT`. Empty when the store has no live deal. |
| `isTopRated` | boolean | Glovo's top-rated badge |
| `isNew` | boolean | Glovo's new-store badge — genuinely rare. `true` on just 8 of 1,841 store entries measured across 14 cities, 12 countries and 4 verticals (~0.4%), and nearer 0.1% in mature markets like Madrid, where Glovo ranks established merchants first. A screen of `false` values is normal, not a broken field. |

##### Delivery & Status

| Field | Type | Description |
|-------|------|-------------|
| `deliveryFeeBase` | number | The store's base delivery fee, in the currency below |
| `currency` | string | Currency code for the fee and for this store's product prices (EUR, PLN, UAH, RON, …) |
| `availability` | string | Glovo's live status for the store, e.g. `OPEN` or `SCHEDULEABLE` (order now, deliver later) |

#### Product (`recordType: "product"`)

```json
{
    "recordType": "product",
    "storeSlug": "mcdonalds-val2",
    "storeName": "McDonald's®",
    "name": "McMenú® Big Mac®",
    "description": "Carne, pepinillos, lechuga, cebolla y queso fundido",
    "price": 9.74,
    "currency": "EUR",
    "priceDisplay": "9,74 €",
    "productId": "41935023102",
    "categoryName": "Top sellers",
    "imageUrl": "https://d2o20fuzws2yo1.cloudfront.net/TPO-1480BB_GMA-V1_M26.png",
    "city": "Valencia"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `recordType` | string | Always `"product"` |
| `storeSlug` | string | Parent store identifier (join key to its store row) |
| `storeName` | string | Parent store display name |
| `name` | string | Product or menu item name |
| `description` | string | Product description, where the merchant wrote one |
| `price` | number | Numeric price |
| `currency` | string | Currency code (EUR, PLN, UAH, RON, …) |
| `priceDisplay` | string | Formatted price as shown to shoppers (e.g. `"9,74 €"`) |
| `productId` | string | Glovo product identifier |
| `categoryName` | string | Menu section the product sits in |
| `imageUrl` | string | Direct product image link |
| `city` | string | City context |

### Tips for Best Results

- **Spell the city the way Glovo does.** Glovo files each city under one name, and it is local for some (`Lisboa`, `Warszawa`) and English for others (`Bucharest`). Get it wrong and the run comes back with the closest real delivery cities by name, so a mistake costs you one quick correction rather than an empty dataset.
- **Maximize coverage with breadth, not a bigger `maxStores`.** One vertical returns up to about 50 stores — Glovo's public listing limit — so raising `maxStores` past 50 on a single vertical adds nothing. Choose **All verticals** (roughly 200 stores) or add several cuisine / sub-type filters, each of which pulls its own set.
- **Read the final message before trusting the row count.** It says "Done!" only when nothing cut the run short. Otherwise it names the reason — your result limit, your store limit, or Glovo's one-page listing — and, where Glovo publishes it, how many stores the city actually has.
- **Use `maxResults` as your budget dial.** Every store row and product row counts toward it. With menus on, a restaurant adds roughly 70–180 rows and a large supermarket up to about 3,000, so set the ceiling to the number of rows you're willing to pay for and let the run stop itself.
- **Leave products off for a store census.** A city-wide store list is cheap and fast; turn menus on only for the shortlist of merchants you actually want item-level data on.
- **Treat `votes` as text and `rating` as optional.** Popular stores report review volume as a band (`"1k+"`), and stores Glovo hasn't rated yet return neither field. Filter on rating rather than assuming every row has one, and sort on `rating`, not `votes`.
- **Pick the language for the reader, not the country.** Language and city are independent, so you can pull Kenyan or Georgian listings in English for an internal report, or in the local language for customer-facing copy.
- **Filter by `recordType` downstream.** Split the dataset into a clean store table and a product table, then join products back to stores on `storeSlug`.

### Pricing

**From $2.00 per 1,000 results** — pay-per-result only, with no compute charges. Apify's loyalty discount tiers lower the rate as you go: Gold subscribers pay the headline $2.00 per 1,000. Tiered rates take effect 12 September 2026; until then every account pays the Gold rate.

| Results | No discount | Bronze | Silver | Gold |
|---------|-------------|--------|--------|------|
| 100 | $0.235 | $0.225 | $0.215 | $0.200 |
| 1,000 | $2.35 | $2.25 | $2.15 | $2.00 |
| 10,000 | $23.50 | $22.50 | $21.50 | $20.00 |
| 100,000 | $235.00 | $225.00 | $215.00 | $200.00 |

A "result" is any row in the output dataset — a store or a product. Turning on full menu and catalog extraction adds product rows (many per store), so use `maxStores`, `maxResults`, and the products toggle to keep your result count where you want it.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom workflows on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor is designed for legitimate market research, competitive intelligence, price monitoring, and lead generation. You are responsible for complying with applicable laws and Glovo's terms of service, including making reasonable-rate requests and respecting how the data may be used. Do not use extracted data for spam, harassment, or any illegal purpose.

# Actor input Schema

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

The Glovo city to scrape, by name. Use the name Glovo itself uses for it: for some cities that is the local spelling (Lisboa, not Lisbon), for others the English one (Bucharest, not Bucuresti). Working examples: Barcelona, Madrid, Lisboa, Warszawa, Bucharest. If the city is not found we tell you the closest match Glovo delivers to, so you can correct it in one go. Leave the store links empty to discover stores in this city.

## `storeCategory` (type: `string`):

Which kind of stores to collect in the chosen city. 'All verticals' covers everything Glovo offers there.

## `categoryFilters` (type: `array`):

Optionally narrow a vertical to specific cuisines or sub-types, one per line (e.g. 'burgers', 'pizza', 'sushi'). Leave empty to scrape the whole vertical.

## `storeUrls` (type: `array`):

Paste specific Glovo store links to scrape exactly those stores, one per line (e.g. a 'glovoapp.com/.../stores/...' link). Products are always collected for these. Leave empty to discover stores from the city and vertical above.

## `includeProducts` (type: `boolean`):

Also collect the full product or menu list for each store. This adds a lot more results and takes longer: a restaurant typically adds 70-180 rows and a large supermarket up to 3,000, on top of one row per store. Restaurants and normal stores return their whole menu in full. Very large grocery and quick-commerce stores are sampled instead of fully listed: we walk their top aisles to a safe depth and stop at roughly 3,000 products per store, so a big hypermarket's catalog may be partial. The Max Results limit below caps the run as a whole.

## `maxStores` (type: `integer`):

How many stores to keep from this run. Each store vertical (Food, Groceries, etc.) returns up to about 50 stores — that is Glovo's public listing limit, so a single vertical can never give you more than ~50 no matter what you set here. To get broader coverage, choose 'All verticals' (each vertical adds its own ~50) or add several Sub-type Filters (each filter pulls its own set of stores). This also applies to Store Links: if you paste more links than this number, only the first ones are collected, so raise it (or set it to 0) when you paste a long list. Setting this to 0 lifts our store cap — that is about 200 stores across all four verticals, and the Max Results limit below still bounds the run. Tip: start with 20-50 to test. If you turn on products, each store adds its own rows on top: roughly 70-180 for a restaurant and up to 3,000 for a large supermarket, so 0 plus products can reach tens of thousands of results.

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

Safety limit on the total number of results a single run will deliver, counting store rows and product rows together. It exists so that a broad run cannot quietly become a very large one: with products switched on, 'All verticals' with no store cap can otherwise produce well over a hundred thousand rows. The run stops cleanly when it reaches this number and tells you that it did, so you always know whether you got everything. Raise it if you genuinely need more.

## `language` (type: `string`):

Language for store and product names and descriptions. Independent of the city: any language works with any Glovo country.

## Actor input object example

```json
{
  "city": "Barcelona",
  "storeCategory": "all",
  "categoryFilters": [],
  "storeUrls": [],
  "maxStores": 50,
  "maxResults": 20000,
  "language": "en"
}
```

# Actor output Schema

## `stores` (type: `string`):

Table of stores with rating, votes, base delivery fee, currency, availability, promotions, and badges.

## `products` (type: `string`):

Product / menu item rows with name, description, price, and parent store (only present when 'Include products' is enabled or store links are supplied).

# 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 = {
    "city": "Barcelona",
    "storeCategory": "all",
    "categoryFilters": [],
    "storeUrls": [],
    "includeProducts": false,
    "maxStores": 50,
    "maxResults": 20000,
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/glovo-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 = {
    "city": "Barcelona",
    "storeCategory": "all",
    "categoryFilters": [],
    "storeUrls": [],
    "includeProducts": False,
    "maxStores": 50,
    "maxResults": 20000,
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/glovo-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 '{
  "city": "Barcelona",
  "storeCategory": "all",
  "categoryFilters": [],
  "storeUrls": [],
  "includeProducts": false,
  "maxStores": 50,
  "maxResults": 20000,
  "language": "en"
}' |
apify call solidcode/glovo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solidcode/glovo-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/BSAuvjd3O1z0gLULN/builds/2KegPlc7vund9MCNm/openapi.json
