# Themealdb Recipes Scraper (`zerobreak/themealdb-recipes-scraper`) Actor

TheMealDB Recipes Scraper is a Python tool designed to extract detailed food recipes, ingredient lists, quantities, preparation instructions, meal categories, and regional cuisines from TheMealDB. It exports structured culinary datasets into clean CSV or JSON format.

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

## Pricing

from $2.99 / 1,000 results

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

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

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

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

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

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

# README

### TheMealDB Recipes Scraper — Search Recipes and Extract Ingredients

### Overview

TheMealDB Recipes Scraper collects publicly available recipe information and saves meals as structured dataset records. Search by meal name, first letter, ingredient, cuisine area, category, or meal ID.

Collected information can include cooking instructions, ingredient names, measurements, meal categories, cuisine details, and thumbnail images. Export your dataset in JSON, CSV, or Excel format.

### Features

- **Recipe name search:** Find meals by name, such as chicken or pasta.
- **First-letter search:** Discover recipes whose names begin with a specified letter.
- **Ingredient filtering:** Find meals associated with ingredients such as chicken breast.
- **Cuisine filtering:** Collect recipes by cuisine area, such as Canadian or Indian.
- **Category filtering:** Narrow results to categories such as Seafood or Chicken.
- **Individual recipe lookup:** Retrieve a specific meal using its ID.
- **Full recipe details:** Load cooking instructions and ingredient measurements when enabled.
- **Duplicate removal:** Keep each meal ID only once.
- **Configurable collection limits:** Save up to 1,000 unique meal records per run.
- **Multiple export formats:** Download data in JSON, CSV, or Excel.

### Use Cases

- **Recipe catalogs:** Build searchable collections of meals and cooking instructions.
- **Ingredient research:** Find recipes that use particular ingredients.
- **Cuisine exploration:** Organize recipes by country, cuisine area, or category.
- **Meal planning:** Collect recipe names, ingredients, and measurements for planning meals.
- **Cooking applications:** Prepare structured recipe datasets for application prototypes.
- **Food data analysis:** Compare recipe categories, ingredients, and cuisine types.
- **Scheduled collection:** Refresh recipe datasets periodically to capture current source information.

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `searchQueries` | Array of strings | `["chicken"]` | Meal names to search for. |
| `firstLetters` | Array of strings | `[]` | First letters used to find meals. |
| `ingredients` | Array of strings | `[]` | Main ingredients used to filter recipes. Spaces in ingredient names are converted to underscores. |
| `areas` | Array of strings | `[]` | Cuisine areas to search. |
| `categories` | Array of strings | `[]` | Meal categories to search. |
| `mealIds` | Array of strings | `[]` | Specific meal IDs to retrieve. |
| `fullDetails` | Boolean | `true` | Loads complete recipe details for results that initially contain only a meal name and thumbnail. |
| `maxItems` | Integer | `100` | Maximum number of unique meal records to save. Allowed range: 1–1,000. |
| `requestDelaySecs` | Number | `0.3` | Delay between requests in seconds. Minimum: 0.3 seconds. |
| `timeoutSecs` | Integer | `300` | Overall time limit in seconds for starting new requests. |
| `requestTimeoutSecs` | Integer | `30` | Maximum wait for an individual request, in seconds. |

### Example Input

```json id="k7m3qp"
{
  "searchQueries": ["chicken"],
  "firstLetters": [],
  "ingredients": [],
  "areas": ["Canadian"],
  "categories": [],
  "mealIds": ["52772"],
  "fullDetails": true,
  "maxItems": 100,
  "requestDelaySecs": 0.3,
  "timeoutSecs": 300,
  "requestTimeoutSecs": 30
}
```

This configuration searches for chicken recipes, collects Canadian cuisine results, retrieves meal ID `52772`, and loads full recipe details when available.

### What Data Does This Actor Extract?

Each saved meal becomes one dataset row. When a search or filter result contains only a meal name and thumbnail, enabling `fullDetails` allows the actor to retrieve additional information, including instructions and ingredients.

#### Extracted Data Fields

| Field | Description |
|---|---|
| `idMeal` | Unique meal identifier. |
| `strMeal` | Recipe or meal name. |
| `strMealAlternate` | Alternate meal name, when available. |
| `strCategory` | Meal category, such as Chicken. |
| `strArea` | Cuisine area, such as India. |
| `strCountry` | Country label, when available. |
| `strInstructions` | Cooking instructions. |
| `strMealThumb` | Recipe thumbnail image location. |
| `strTags` | Recipe tags, when available. |
| `strYoutube` | Related cooking video link, when available. |
| `strIngredient1`–`strIngredient20` | Ingredient names. Empty ingredient slots may be null. |
| `strMeasure1`–`strMeasure20` | Measurements corresponding to the ingredient fields. |
| `mode` | Collection method associated with the record, such as search, letter, ingredient, area, category, or lookup. |
| `scraped_at` | UTC timestamp indicating when the record was saved. |

Some fields may be missing or null when the original meal record does not contain that information.

#### Example Output

```json id="m8w2zr"
{
  "idMeal": "52795",
  "strMeal": "Chicken Handi",
  "strCategory": "Chicken",
  "strArea": "India",
  "strCountry": "India",
  "strMealThumb": "RECIPE_THUMBNAIL_URL",
  "strYoutube": "COOKING_VIDEO_URL",
  "strIngredient1": "Chicken",
  "strMeasure1": "1 kg",
  "strInstructions": "Prepare the ingredients and cook according to the recipe instructions.",
  "mode": "search",
  "scraped_at": "2026-10-12T00:00:00+00:00"
}
```

The example demonstrates the dataset structure. Actual recipe details depend on the meal selected and the information available in the source.

### Working with Your Dataset

After collection, you can:

- Export recipes as JSON, CSV, or Excel files.
- Sort meals by name, category, or cuisine area.
- Search ingredient fields to identify recipes using particular ingredients.
- Review cooking instructions and measurements.
- Build recipe catalogs and meal-planning spreadsheets.
- Compare ingredient combinations across different recipes.
- Use meal IDs to organize records and avoid duplicate entries.

### Important Notes

- Multiple input lists can be used to collect different types of recipe results in one run.
- `fullDetails` controls whether additional recipe details are retrieved for filtered results that initially contain limited information.
- Duplicate meal IDs are retained only once.
- The actor stops collecting when `maxItems` is reached.
- Requests are processed sequentially with a delay between requests.
- Temporary request failures may be retried.
- A meal ID that does not return a recipe may produce an error record, while processing continues with remaining inputs.
- If all input lists are empty, the run may finish without collecting any recipe records.
- Recipe availability, ingredients, instructions, and images may change over time.

### FAQ

**Can I search recipes by ingredient?**

Yes. Add one or more ingredient names to `ingredients`. The actor uses these values to find matching meals.

**Can I search by cuisine or meal category?**

Yes. Use `areas` to specify cuisine areas and `categories` to specify meal categories.

**Can I retrieve a specific recipe?**

Yes. Add the desired meal ID to `mealIds`.

**Why are some recipe records missing instructions or ingredients?**

Some initial search and filter results contain only basic information. Set `fullDetails` to `true` to retrieve additional details when available.

**How many recipes can one run collect?**

The default limit is 100 unique meals. You can increase `maxItems` to a maximum of 1,000.

**Are duplicate recipes saved multiple times?**

No. The actor keeps each meal ID only once.

**Can I export recipes to Excel?**

Yes. You can export the collected dataset in JSON, CSV, or Excel format.

**How current is the collected information?**

Recipe information is collected during the run. The `scraped_at` timestamp records when the actor saved the row, not when the recipe was originally published.

### Disclaimer

This is an independent tool and is not affiliated with, endorsed by, sponsored by, or officially associated with TheMealDB or its owners. Users are responsible for ensuring that their collection, storage, redistribution, and use of recipe information comply with applicable laws and the source's terms.

### Is Web Scraping Legal?

Collecting information that is already public is generally legal. Scraping is not the same thing as hacking, and there is no single law that bans it. The limits are the usual ones: do not break into accounts, do not take private or confidential data, and be careful with personal data and copyrighted works. A site's terms can also restrict how you access it. Facts such as a public name, price, or rating are not the same thing as republishing someone's article or photo.

This actor collects information from public pages. It does not log in and it does not bypass access controls.

For a longer explanation, see Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

# Actor input Schema

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

Meal names to search. Each value is sent to the public name search. Leave empty to skip name search.

## `firstLetters` (type: `array`):

Single letters. Each letter lists meals whose name starts with that letter.

## `ingredients` (type: `array`):

Main ingredients used to filter meals, such as chicken breast. Spaces are sent as underscores.

## `areas` (type: `array`):

Cuisine areas used to filter meals, such as Canadian or Japanese.

## `categories` (type: `array`):

Meal categories used to filter meals, such as Seafood or Chicken.

## `mealIds` (type: `array`):

TheMealDB meal ids to look up one by one, such as 52772.

## `fullDetails` (type: `boolean`):

After an ingredient, area, or category filter, look up each meal id so the row includes instructions and ingredients.

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

Maximum number of meal rows to save in one run. The hard cap is 1000.

## `requestDelaySecs` (type: `number`):

Seconds to wait between HTTP calls. The floor is 0.3 seconds.

## `timeoutSecs` (type: `integer`):

Stop starting new requests after this many seconds. Default is 300. Maximum is 3600.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one HTTP response before retrying. Default is 30 seconds.

## `proxyConfiguration` (type: `object`):

Optional proxy for requests. The default sends traffic directly, with Apify Proxy turned off.

## Actor input object example

```json
{
  "searchQueries": [
    "chicken"
  ],
  "firstLetters": [
    "c"
  ],
  "ingredients": [
    "chicken breast"
  ],
  "areas": [
    "Canadian"
  ],
  "categories": [
    "Seafood"
  ],
  "mealIds": [
    "52772"
  ],
  "fullDetails": true,
  "maxItems": 100,
  "requestDelaySecs": 0.3,
  "timeoutSecs": 300,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `headlines` (type: `string`):

Default dataset of Al Jazeera RSS rows.

## `overview` (type: `string`):

Table of headlines, links, short summaries, and dates.

# 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": [
        "chicken"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zerobreak/themealdb-recipes-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": ["chicken"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("zerobreak/themealdb-recipes-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": [
    "chicken"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call zerobreak/themealdb-recipes-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zerobreak/themealdb-recipes-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/kYb7pl7GnXfAB0d7F/builds/9o2MxBJqZ5LA1KgB3/openapi.json
