# Ifood Pharmacy Scraper (`yasmany.casanova/ifood-pharmacy-scraper`) Actor

Extract pharmacy data from iFood Brazil: drugstore listings by location, detailed store information, and full product catalogs with prices, EAN codes, packaging, and unit information. Ideal for price intelligence, market research, and e-commerce data.

- **URL**: https://apify.com/yasmany.casanova/ifood-pharmacy-scraper.md
- **Developed by:** [Yasmany Grijalba Casanova](https://apify.com/yasmany.casanova) (community)
- **Categories:** Automation, E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $35.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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## iFood Pharmacy Scraper

Extract comprehensive pharmacy data from **iFood** — Latin America's leading food delivery platform, with a dedicated drugstore storefront. Get pharmacy listings, detailed store profiles, category trees, and full medication and healthcare product catalogs with prices, EAN-13 barcodes, packaging and units.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue?logo=apify)](https://apify.com)
[![Residential Proxy](https://img.shields.io/badge/Proxy-Residential-orange)](https://apify.com/proxy)
[![Brazil](https://img.shields.io/badge/Region-Brazil-green)](https://www.ifood.com.br)

---

> ℹ️ **Residential Proxy Required**
> This Actor requires a residential proxy for reliable data extraction. You have two options:
>
> 1. **Apify Residential Proxy** — available on Apify paid plans. See [apify.com/pricing](https://apify.com/pricing).
> 2. **Your own residential proxy** — provide it via the `customProxyUrl` input field (works on any Apify plan, including Free).
>
> Runs without a residential proxy will stop immediately with a clear message, so you are not charged for unnecessary compute time.

---

### Table of Contents

- [Quick Start](#quick-start)
- [Features](#features)
- [Use Cases](#use-cases)
- [How It Works](#how-it-works)
- [Input Parameters](#input-parameters)
- [Operation Modes](#operation-modes)
- [Output Examples](#output-examples)
- [Data Fields](#data-fields)
- [Integrations](#integrations)
- [How to Get Coordinates](#how-to-get-coordinates)
- [Important Notes](#important-notes)
- [FAQ](#faq)
- [Support](#support)

---

### Quick Start

Get started in four simple steps:

#### Step 1: Find pharmacies in São Paulo

```json
{
  "mode": "stores",
  "latitude": "-23.6051",
  "longitude": "-46.6367"
}
````

#### Step 2: Get pharmacy details

```json
{
  "mode": "store_info",
  "latitude": "-23.6051",
  "longitude": "-46.6367",
  "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d"
}
```

#### Step 3: List the store's categories

```json
{
  "mode": "categories",
  "latitude": "-23.6051",
  "longitude": "-46.6367",
  "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d"
}
```

#### Step 4: Extract the product catalog for ONE category

```json
{
  "mode": "assortments",
  "latitude": "-23.6051",
  "longitude": "-46.6367",
  "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
  "category_id": "56e4b49b-563a-4b2a-8011-8b883bd36afd"
}
```

> **Tip**: To cover a full catalog, list categories first then dispatch one `assortments` run per `category_id` — runs can be parallelized for speed.

***

### Features

| Feature | Description |
|---------|-------------|
| **100+ Pharmacies per Request** | Cursor-paginated listing — typical locations return 100–200 pharmacies |
| **Complete Store Profiles** | Address, delivery info, rating, price range, minimum order |
| **Full Product Catalogs** | Every SKU with price, EAN-13 barcode, packaging, unit |
| **Discount Detection** | Original price + discount percent when items are on sale |
| **Category Discovery** | Full department/aisle tree (UUIDs ready for `assortments`) |
| **Incremental Dataset Writes** | Products are saved as they are scraped — partial results survive crashes |
| **Structured JSON Output** | Clean, schema-validated data ready for analysis |

***

### Use Cases

<details>
<summary><strong>Pharmaceutical Price Intelligence</strong></summary>

Match medications and healthcare products by **EAN-13 barcode** across major pharmacy chains (Drogaria São Paulo, Panvel, Farma Conde, Pague Menos, Nissei, etc.) to track price differences, promotions, and competitive positioning in real time.

</details>

<details>
<summary><strong>Retail Pharma Market Research</strong></summary>

Map pharmacy density, delivery coverage, and category assortment (Medicamentos, Higiene e Beleza, Saúde e Bem-Estar, Suplementos, Primeiros Socorros) across Brazilian cities and neighborhoods.

</details>

<details>
<summary><strong>Brand & Product Tracking</strong></summary>

Monitor which brands and SKUs pharmacies list, at what tier (generic vs. branded, packaging size), and whether they are on promotion — essential for laboratorios, CPG pharma brands, and distributors tracking market presence.

</details>

<details>
<summary><strong>Healthcare E-Commerce Enrichment</strong></summary>

Enrich your product catalog with real iFood pricing, availability, and imagery — tie it to your own SKUs via the `ean` field. Ideal for marketplaces, pharmacy chains, and telemedicine platforms building recommendation engines.

</details>

<details>
<summary><strong>Competitor Analysis</strong></summary>

Compare pharmacies by pricing, promotion depth, SKU breadth, delivery fee, and delivery time — gain competitive insights on your local market.

</details>

<details>
<summary><strong>Location & Delivery Analysis</strong></summary>

Understand pharmacy footprint and product availability by geographic area — delivery time, fee, and distance per pharmacy, for route planning or underserved-area identification.

</details>

***

### How It Works

```
+------------------+    +------------------+    +------------------+    +------------------+
|     STEP 1       |    |     STEP 2       |    |     STEP 3       |    |     STEP 4       |
|   Stores         |--->|   Store Info     |--->|   Categories     |--->|   Assortments    |
|   (location)     |    |   (profile)      |    |   (tree)         |    |   (one category) |
+------------------+    +------------------+    +------------------+    +------------------+
        |                      |                      |                      |
        v                      v                      v                      v
   100-200                Complete store          Department           All SKUs with
   pharmacies            profile + address       UUIDs                EAN, price, unit
```

#### Step 1: Find Pharmacies

List pharmacies delivering to any Brazilian coordinates:

```json
{
  "mode": "stores",
  "latitude": "-23.6051",
  "longitude": "-46.6367"
}
```

**Returns**: A cursor-paginated list (20 pharmacies per page) with `store_id`, name, rating, delivery fee, delivery time, and distance.

#### Step 2: Get Pharmacy Details

Pick a `store_id` from Step 1 and fetch its full profile:

```json
{
  "mode": "store_info",
  "latitude": "-23.6051",
  "longitude": "-46.6367",
  "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d"
}
```

**Returns**: Full address (street, city, district, state, ZIP), delivery fee in BRL, price range, minimum order, rating, and more.

#### Step 3: List Categories

Discover the store's departments. Each category has a UUID used in Step 4:

```json
{
  "mode": "categories",
  "latitude": "-23.6051",
  "longitude": "-46.6367",
  "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d"
}
```

**Returns**: Array of `{code, name}` pairs — e.g. `Medicamentos`, `Higiene e Beleza`, `Saúde e Bem-Estar`, `Primeiros Socorros`, `Suplementos e Vitaminas`.

#### Step 4: Extract a Category's Products

Extract every SKU of **one** category (paginated, 50 items per page):

```json
{
  "mode": "assortments",
  "latitude": "-23.6051",
  "longitude": "-46.6367",
  "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
  "category_id": "56e4b49b-563a-4b2a-8011-8b883bd36afd"
}
```

**Returns**: Products with `ean`, `price`, `price_original`, `discount_percent`, `packaging`, `unit`, `quantity`, image URL.

> **Pro tip**: Run multiple `assortments` jobs in parallel (one per `category_id`) to extract a full catalog faster.

***

### Input Parameters

#### Required Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `mode` | string | Operation mode: `stores`, `store_info`, `categories`, or `assortments` |
| `latitude` | string | Location latitude (e.g., "-23.6051") |
| `longitude` | string | Location longitude (e.g., "-46.6367") |

#### Mode-Specific Parameters

| Parameter | Type | Required For | Description |
|-----------|------|--------------|-------------|
| `store_id` | string | `store_info`, `categories`, `assortments` | Pharmacy UUID from `stores` mode |
| `category_id` | string | `assortments` | Category UUID from `categories` mode |

#### Optional Parameters

| Parameter | Default | Description |
|-----------|---------|-------------|
| `maxPages` | `200` | Safety cap on paginated requests (stores: 20 pharmacies/page, assortments: 50 products/page) |
| `pageDelay` | `1` | Seconds between paginated requests to avoid rate limits |
| `maxRetries` | `3` | Retry attempts for failed requests |
| `timeout` | `30` | Request timeout in seconds |

#### Proxy Configuration

> **⚠️ Proxy Required** — This Actor requires **Apify Residential Proxy** to work. Make sure your Apify plan includes Residential Proxy access. Proxy usage is billed separately to your Apify account.

| Parameter | Default | Description |
|-----------|---------|-------------|
| `useApifyProxy` | `true` | Enable Apify Proxy (required) |
| `proxyGroups` | `["RESIDENTIAL"]` | Proxy group — RESIDENTIAL is required |
| `proxyCountry` | `BR` | Proxy country code (BR recommended) |
| `customProxyUrl` | — | Your own residential proxy URL (overrides Apify Proxy) |

***

### Operation Modes

| Mode | Description | Required Parameters | Output |
|------|-------------|---------------------|--------|
| `stores` | List pharmacies by location | `latitude`, `longitude` | 100–200 pharmacies per location |
| `store_info` | Get pharmacy details | `latitude`, `longitude`, `store_id` | Complete pharmacy profile |
| `categories` | List a store's departments | `latitude`, `longitude`, `store_id` | Array of `{code, name}` pairs |
| `assortments` | Extract products of ONE category | `latitude`, `longitude`, `store_id`, `category_id` | Full paginated SKU list |

***

### Output Examples

#### Stores Mode

```json
{
  "mode": "stores",
  "data": [
    {
      "name": "DROGARIA SAO PAULO - AFONSO CELSO",
      "segment": "MERCADO",
      "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
      "store_slug": "drogaria-sao-paulo---afonso-celso-vila-mariana",
      "available": "S",
      "distance": 0.24,
      "user_rating": 4.9,
      "fee": 0,
      "time_min_minutes": 0,
      "time_max_minutes": 0,
      "is_ifood_delivery": true,
      "delivery_mode": "DEFAULT",
      "alias": "PHARMACIES"
    }
  ],
  "metadata": {
    "items_count": 161,
    "scraped_at": "2026-04-23T13:00:47.261914+00:00"
  }
}
```

> **Note**: The `stores` home feed returns summary cards that include `distance`, `rating`, `store_id`, and basic delivery hints. For the full delivery fee and exact minutes, call `store_info` with the `store_id` — that's where `delivery_fee: 11.48`, `delivery_time: 10`, etc. come from.

#### Store Info Mode

```json
{
  "mode": "store_info",
  "data": {
    "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
    "name": "Drogaria São Paulo - Afonso Celso",
    "main_category": "Mercado",
    "store_type": "PHARMACY",
    "city": "SAO PAULO",
    "state": "SP",
    "district": "VILA MARIANA",
    "street_name": "R AFONSO CELSO",
    "street_number": "1720",
    "zip_code": "04119062",
    "price_range": "CHEAPEST",
    "delivery_fee": 11.48,
    "type_delivery_fee": "FIXED",
    "delivery_time": 10,
    "minimum_order_value": 30,
    "user_rating": 4.8,
    "user_rating_count": 51
  }
}
```

#### Categories Mode

```json
{
  "mode": "categories",
  "data": {
    "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
    "total_categories": 12,
    "categories": [
      {"code": "56e4b49b-563a-4b2a-8011-8b883bd36afd", "name": "Medicamentos"},
      {"code": "9e4c5d75-5bbf-4d68-87e6-f3bc0a568368", "name": "Higiene e Beleza"},
      {"code": "4d535aee-1d21-4502-a7ee-b5a92dc8e0f1", "name": "Saúde e Bem-Estar"},
      {"code": "dca5ace7-ee70-4c1b-91e5-2ddbc0da6b25", "name": "Primeiros Socorros"},
      {"code": "77249e1f-acbd-4f91-934c-1e46c9db7450", "name": "Suplementos e Vitaminas"}
    ]
  }
}
```

#### Assortments Mode

Each product is pushed to the dataset as its own record (incremental), followed by a single summary record at the end.

**Product record:**

```json
{
  "mode": "assortments",
  "item": {
    "id": "04ba4c15-b563-40e7-92c0-18f35e390437",
    "description": "Clortalidona 50mg Germed Pharma Caixa com 30 Comprimidos",
    "ean": "7896004708867",
    "price": 28.15,
    "price_original": null,
    "has_discount": false,
    "discount_percent": null,
    "availability": "AVAILABLE",
    "enabled": true,
    "unit": null,
    "packaging": null,
    "quantity": null,
    "category_id": "56e4b49b-563a-4b2a-8011-8b883bd36afd",
    "category_name": "Medicamentos",
    "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
    "logo_url": "https://static-images.ifood.com.br/image/upload/..."
  }
}
```

**Summary record (at end of run):**

```json
{
  "mode": "assortments",
  "kind": "summary",
  "data": {
    "store_id": "9ea4a606-58d7-490f-8075-3ecdc13e8d4d",
    "category_id": "56e4b49b-563a-4b2a-8011-8b883bd36afd",
    "category_name": "Medicamentos",
    "total_items": 100,
    "pagination_total_items": 100,
    "pages_fetched": 2,
    "pages_failed": 0
  }
}
```

***

### Data Fields

#### Stores Mode

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Pharmacy name (uppercased) |
| `segment` | string | Category as returned by iFood (currently "MERCADO" even for pharmacies — iFood hasn't specialized this field for the drugstore catalog). Use `alias` or `store_type` in `store_info` to disambiguate. |
| `store_id` | string | Unique pharmacy identifier (UUID) |
| `store_slug` | string | URL slug derived from the store name |
| `available` | string | `"S"` = delivering now, `"N"` = closed/out of range |
| `distance` | number | Distance from the input coordinates (km) |
| `user_rating` | number | Average rating (0–5 stars) |
| `fee` | number | Delivery fee **in cents** (1148 = R$11.48). Returns `0` when the pharmacy is closed / not currently accepting delivery — check `store_info.delivery_fee` for the canonical value. |
| `time_min_minutes` | number | Minimum delivery time (minutes) |
| `time_max_minutes` | number | Maximum delivery time (minutes) |
| `is_ifood_delivery` | boolean | iFood delivery vs. store delivery |
| `delivery_mode` | string | `"DEFAULT"`, `"SCHEDULE"`, `"PICKUP"` |
| `image_url` | string | Store logo URL (absolute, fetchable) |
| `alias` | string | Always `"PHARMACIES"` |

#### Store Info Mode

| Field | Type | Description |
|-------|------|-------------|
| `store_id` | string | Pharmacy UUID |
| `name` | string | Store display name |
| `main_category` | string | Friendly category name (e.g. "Mercado") |
| `store_type` | string | Merchant type code — `"PHARMACY"` for this actor's results |
| `city`, `state`, `district` | string | Location components |
| `street_name`, `street_number` | string | Physical address |
| `zip_code` | string | Brazilian CEP (no dash) |
| `latitude`, `longitude` | string | Store's own coordinates |
| `price_range` | string | `"CHEAPEST"`, `"CHEAP"`, `"MODERATE"`, `"EXPENSIVE"` |
| `delivery_fee` | number | Delivery fee in BRL |
| `type_delivery_fee` | string | `"FIXED"`, `"FREE"`, `"DISTANCE"` |
| `delivery_time` | number | Expected delivery time (minutes) |
| `minimum_order_value` | number | Minimum order amount (BRL) |
| `user_rating` | number | Average rating (0–5) |
| `user_rating_count` | number | Total reviews |
| `available` | boolean | Currently accepting orders |

#### Categories Mode

| Field | Type | Description |
|-------|------|-------------|
| `code` | string | Category UUID — **use as `category_id` in assortments mode** |
| `name` | string | Human-readable category name (e.g. "Medicamentos") |

#### Assortments Mode (per product)

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | iFood's internal product UUID |
| `description` | string | Product name |
| `ean` | string | EAN-13 barcode — key for price-matching |
| `price` | number | Current price in BRL |
| `price_original` | number | null | Pre-discount price (null if no promo) |
| `has_discount` | boolean | `true` when on promotion |
| `discount_percent` | number | null | Percent off (0–100) |
| `availability` | string | `"AVAILABLE"`, `"UNAVAILABLE"`, `"OUT_OF_STOCK"` |
| `enabled` | boolean | Store-side enabled flag |
| `unit` | string | null | `"UN"`, `"ML"`, `"MG"`, `"G"`, etc. — often `null` for medications (check `details` / `additional_info` as a fallback). |
| `packaging` | string | null | `"CAIXA"`, `"FRASCO"`, `"BLISTER"`, etc. — often `null` (see `details`). |
| `quantity` | number | null | Pack size (e.g. 30 for "30 comprimidos") — often `null`. |
| `minimum_quantity` | number | Minimum order quantity |
| `incremental_quantity` | number | Step increment |
| `available_units` | string | Comma-separated unit types (`"UNIT,KG"`) |
| `category_id`, `category_name` | string | Parent category |
| `store_id` | string | Parent store UUID |
| `logo_url` | string | null | Product image URL |
| `external_code` | string | null | Merchant's internal SKU reference |
| `product_tags` | array | null | Taxonomy tags (e.g. age/prescription restrictions). Commonly `null` in pharmacy catalogs. |

> The tables above cover the most useful fields. Every record also includes metadata (`scraped_at`, `items_count`, `proxy_used`, etc.) and a few additional nullable fields (`region`, `currency`, `is_new`, `is_super_restaurant`, `product_aisles`, `scale_min_quantity`, `scale_price`). Run `assortments` once to inspect the full shape — all fields are documented in the structured JSON output.

***

### Integrations

Use the **API** tab on the Actor page to get ready-to-use code examples in **Python**, **JavaScript**, and **cURL**. The examples are auto-generated with the correct parameters for immediate integration.

The dataset ships with pre-configured views for the Apify Console:

| View | Shows | Fields |
|------|-------|--------|
| **Overview** | All records | mode, items\_count, scraped\_at, proxy\_used |
| **Pharmacies** | `stores` mode | name, id, segment, rating, distance, fee, availability |
| **Store Details** | `store_info` mode | name, category, location, delivery fee, rating |
| **Categories** | `categories` mode | code, name |
| **Products** | `assortments` mode | description, EAN, price, discount %, unit, packaging, category |

Each view exports to CSV, JSON, XML, or Excel directly from the console.

***

### How to Get Coordinates

#### Option 1: Google Maps

1. Open [Google Maps](https://maps.google.com)
2. Right-click on any location in Brazil
3. Click the coordinates shown to copy them
4. Use the first number as `latitude` and the second as `longitude`

#### Option 2: Use Common City Coordinates

| City | Latitude | Longitude |
|------|----------|-----------|
| São Paulo (Centro) | -23.5608786 | -46.6570743 |
| Rio de Janeiro | -22.9068467 | -43.1728965 |
| Belo Horizonte | -19.9166813 | -43.9344931 |
| Brasília | -15.7942287 | -47.8821658 |
| Curitiba | -25.4289541 | -49.2671340 |
| Salvador | -12.9714 | -38.5124 |
| Fortaleza | -3.7172 | -38.5433 |
| Recife | -8.0476 | -34.8770 |
| Porto Alegre | -30.0346 | -51.2177 |
| Manaus | -3.1190 | -60.0217 |

***

### Important Notes

| Topic | Details |
|-------|---------|
| **Region** | Brazil only — iFood operates exclusively in Brazil |
| **Proxy** | **Required** — Apify Residential Proxy (or a custom residential proxy via `customProxyUrl`) |
| **Store ID** | Use UUIDs from `stores` mode — not store names or URLs |
| **Category ID** | Use UUIDs from `categories` mode — these are **per-store** |
| **One Category Per Run** | `assortments` extracts one category at a time — parallelize runs for a full catalog |
| **Incremental Writes** | Each product is pushed to the dataset as soon as it is processed |
| **Coordinates** | Required for all modes — must be Brazilian |

***

### FAQ

<details>
<summary><strong>Why am I getting no results?</strong></summary>

- Make sure **Residential Proxy** is enabled (`useApifyProxy: true`, `proxyGroups: ["RESIDENTIAL"]`) or a `customProxyUrl` is set
- Verify your coordinates are within Brazil
- Check that the location has iFood pharmacy coverage (not all neighborhoods do)
- Try coordinates from a major city (São Paulo, Rio de Janeiro)

</details>

<details>
<summary><strong>Why does my <code>assortments</code> run return 0 products?</strong></summary>

- The coordinates are likely **outside the store's delivery radius** — try coordinates closer to the store's physical address
- The `category_id` must come from a `categories` run **for the same store** — category UUIDs are not shared across stores
- The category may genuinely be empty in that store

</details>

<details>
<summary><strong>Why is my store_id invalid?</strong></summary>

- Store IDs are UUIDs in the format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
- Use the exact ID from `stores` mode output
- Do not include the store name or URL

</details>

<details>
<summary><strong>Why is <code>store_info</code> returning HTTP 500?</strong></summary>

iFood returns 500 when the input coordinates are outside the store's delivery radius. Use coordinates close to the store's physical address (from a previous `stores` run).

</details>

<details>
<summary><strong>How do I extract a full catalog?</strong></summary>

1. Run `categories` once to list every department (typically ~12 categories per pharmacy — Medicamentos, Higiene e Beleza, Saúde e Bem-Estar, etc.)
2. For each returned `code`, dispatch one `assortments` run with that `category_id`
3. Runs can execute in parallel — products are written incrementally so partial results are safe

</details>

<details>
<summary><strong>Does this actor extract prescription-only medication?</strong></summary>

This actor returns whatever the iFood pharmacy storefront exposes publicly. Prescription-controlled medications (e.g. antibiotics, psychotropics) that require uploading a receipt are typically **not** listed in the catalog — they appear only in a separate prescription flow on iFood's app. Over-the-counter medication, supplements, and personal care products **are** listed and returned by this actor.

</details>

<details>
<summary><strong>What is the EAN field used for?</strong></summary>

`ean` is the EAN-13 barcode — the universal product identifier. Use it to join iFood products with your own SKU database or match the same product across different pharmacies for price comparison.

</details>

<details>
<summary><strong>Why are <code>unit</code> and <code>packaging</code> sometimes null?</strong></summary>

iFood exposes these as structured fields but most pharmacies leave them empty, keeping the info in the free-text `details` / `additional_info` fields instead. In practice, expect strings like `"Caixa 30cpr"`, `"Frasco 100ml"`, or `"Blister c/12"` in `details` — parse those as your fallback for pack size and packaging type.

</details>

<details>
<summary><strong>How often is the data updated?</strong></summary>

Data is extracted live from iFood on each run — prices, availability, and promotions reflect the state at execution time.

</details>

<details>
<summary><strong>Can I scrape pharmacies outside Brazil?</strong></summary>

No. iFood operates exclusively in Brazil and this actor is configured for the Brazilian market.

</details>

***

### Support

Having issues? Here is how to get help:

1. **Check the FAQ** above for common solutions
2. **Review your input** parameters to ensure they match the required format
3. **Test with the default São Paulo coordinates** to verify the actor is working
4. **Contact support** through [Apify](https://apify.com) for additional assistance

# Actor input Schema

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

Type of data to extract. Typical workflow: stores → categories → assortments (one run per category). Run store\_info to validate a store before extracting its catalog.

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

Location latitude in Brazil. Use Google Maps to find coordinates: right-click any location and copy the first number.

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

Location longitude in Brazil. Use Google Maps to find coordinates: right-click any location and copy the second number.

## `store_id` (type: `string`):

Pharmacy UUID. Required for store\_info, categories, and assortments modes. Get this ID from stores mode first.

## `category_id` (type: `string`):

REQUIRED for assortments mode. A category UUID returned by 'categories' mode. Each run extracts ONE category — dispatch parallel runs to cover the full catalog.

## `maxPages` (type: `integer`):

Safety cap on pages fetched in paginated modes. In 'assortments' each page has 50 products (default 200 = up to 10,000). In 'stores' each page has 20 pharmacies.

## `pageDelay` (type: `integer`):

Delay between paginated requests to avoid rate limiting.

## `useApifyProxy` (type: `boolean`):

Enable Apify Residential Proxy for reliable data extraction. Requires an Apify paid plan. Free-plan users can provide their own residential proxy via 'customProxyUrl' below.

## `proxyGroups` (type: `array`):

Must be set to \['RESIDENTIAL'] for this Actor.

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

Country code for proxy (ISO 3166-1 alpha-2). BR is recommended.

## `customProxyUrl` (type: `string`):

Provide your own residential proxy instead of using Apify Proxy. Format: http://user:pass@host:port. If set, this overrides the Apify Proxy settings above.

## `maxRetries` (type: `integer`):

Maximum retry attempts for failed requests.

## `timeout` (type: `integer`):

Request timeout in seconds.

## Actor input object example

```json
{
  "mode": "stores",
  "latitude": "-23.5608786",
  "longitude": "-46.6570743",
  "store_id": "ada76d64-b645-4c5f-af08-be98e5b68f10",
  "category_id": "85ddf3de-93ab-4542-bfb4-a31f14061d0f",
  "maxPages": 200,
  "pageDelay": 1,
  "useApifyProxy": true,
  "proxyGroups": [
    "RESIDENTIAL"
  ],
  "proxyCountry": "BR",
  "customProxyUrl": "http://user:pass@proxy.example.com:8000",
  "maxRetries": 3,
  "timeout": 30
}
```

# Actor output Schema

## `pharmacies` (type: `string`):

Extracted pharmacy data — stores list, store info, or product catalog depending on the mode used

## `storesView` (type: `string`):

View of pharmacy list data (stores mode)

## `storeInfoView` (type: `string`):

View of detailed pharmacy information (store\_info mode)

## `categoriesView` (type: `string`):

View of store categories (categories mode). Use these codes to run assortments for each category.

## `assortmentsView` (type: `string`):

View of product catalog with prices, EAN, and packaging (assortments mode)

# 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": "stores",
    "latitude": "-23.5608786",
    "longitude": "-46.6570743",
    "maxPages": 200,
    "pageDelay": 1,
    "useApifyProxy": true,
    "proxyGroups": [
        "RESIDENTIAL"
    ],
    "proxyCountry": "BR",
    "maxRetries": 3,
    "timeout": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("yasmany.casanova/ifood-pharmacy-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": "stores",
    "latitude": "-23.5608786",
    "longitude": "-46.6570743",
    "maxPages": 200,
    "pageDelay": 1,
    "useApifyProxy": True,
    "proxyGroups": ["RESIDENTIAL"],
    "proxyCountry": "BR",
    "maxRetries": 3,
    "timeout": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("yasmany.casanova/ifood-pharmacy-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 '{
  "mode": "stores",
  "latitude": "-23.5608786",
  "longitude": "-46.6570743",
  "maxPages": 200,
  "pageDelay": 1,
  "useApifyProxy": true,
  "proxyGroups": [
    "RESIDENTIAL"
  ],
  "proxyCountry": "BR",
  "maxRetries": 3,
  "timeout": 30
}' |
apify call yasmany.casanova/ifood-pharmacy-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ifood Pharmacy Scraper",
        "description": "Extract pharmacy data from iFood Brazil: drugstore listings by location, detailed store information, and full product catalogs with prices, EAN codes, packaging, and unit information. Ideal for price intelligence, market research, and e-commerce data.",
        "version": "1.0",
        "x-build-id": "dGC2exCtE29dLwqj6"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/yasmany.casanova~ifood-pharmacy-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-yasmany.casanova-ifood-pharmacy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/yasmany.casanova~ifood-pharmacy-scraper/runs": {
            "post": {
                "operationId": "runs-sync-yasmany.casanova-ifood-pharmacy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/yasmany.casanova~ifood-pharmacy-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-yasmany.casanova-ifood-pharmacy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode",
                    "latitude",
                    "longitude"
                ],
                "properties": {
                    "mode": {
                        "title": "Operation Mode",
                        "enum": [
                            "stores",
                            "store_info",
                            "categories",
                            "assortments"
                        ],
                        "type": "string",
                        "description": "Type of data to extract. Typical workflow: stores → categories → assortments (one run per category). Run store_info to validate a store before extracting its catalog.",
                        "default": "stores"
                    },
                    "latitude": {
                        "title": "Latitude",
                        "type": "string",
                        "description": "Location latitude in Brazil. Use Google Maps to find coordinates: right-click any location and copy the first number.",
                        "default": "-23.5608786"
                    },
                    "longitude": {
                        "title": "Longitude",
                        "type": "string",
                        "description": "Location longitude in Brazil. Use Google Maps to find coordinates: right-click any location and copy the second number.",
                        "default": "-46.6570743"
                    },
                    "store_id": {
                        "title": "Store ID",
                        "type": "string",
                        "description": "Pharmacy UUID. Required for store_info, categories, and assortments modes. Get this ID from stores mode first."
                    },
                    "category_id": {
                        "title": "Category ID",
                        "type": "string",
                        "description": "REQUIRED for assortments mode. A category UUID returned by 'categories' mode. Each run extracts ONE category — dispatch parallel runs to cover the full catalog."
                    },
                    "maxPages": {
                        "title": "Max Pages",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Safety cap on pages fetched in paginated modes. In 'assortments' each page has 50 products (default 200 = up to 10,000). In 'stores' each page has 20 pharmacies.",
                        "default": 200
                    },
                    "pageDelay": {
                        "title": "Delay Between Pages (seconds)",
                        "minimum": 0,
                        "maximum": 30,
                        "type": "integer",
                        "description": "Delay between paginated requests to avoid rate limiting.",
                        "default": 1
                    },
                    "useApifyProxy": {
                        "title": "Use Apify Residential Proxy",
                        "type": "boolean",
                        "description": "Enable Apify Residential Proxy for reliable data extraction. Requires an Apify paid plan. Free-plan users can provide their own residential proxy via 'customProxyUrl' below.",
                        "default": true
                    },
                    "proxyGroups": {
                        "title": "Proxy Groups",
                        "type": "array",
                        "description": "Must be set to ['RESIDENTIAL'] for this Actor.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "RESIDENTIAL"
                        ]
                    },
                    "proxyCountry": {
                        "title": "Proxy Country",
                        "pattern": "^[A-Z]{2}$",
                        "type": "string",
                        "description": "Country code for proxy (ISO 3166-1 alpha-2). BR is recommended.",
                        "default": "BR"
                    },
                    "customProxyUrl": {
                        "title": "Custom Residential Proxy URL (optional)",
                        "type": "string",
                        "description": "Provide your own residential proxy instead of using Apify Proxy. Format: http://user:pass@host:port. If set, this overrides the Apify Proxy settings above."
                    },
                    "maxRetries": {
                        "title": "Max Retries",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Maximum retry attempts for failed requests.",
                        "default": 3
                    },
                    "timeout": {
                        "title": "Timeout (seconds)",
                        "minimum": 10,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Request timeout in seconds.",
                        "default": 30
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
