# Instagram Recipe Extractor - Reels to Recipes, Any Language (`neonroobz/instagram-recipes`) Actor

Turn Instagram cooking reels into structured recipes: ingredients with quantities, equipment and steps, from what is said and what is shown on screen, in any language, with English versions and schema.org JSON-LD. $15 per 1,000 recipes; reels with no recipe and failures are free.

- **URL**: https://apify.com/neonroobz/instagram-recipes.md
- **Developed by:** [nnrbzz](https://apify.com/neonroobz) (community)
- **Categories:** Social media, AI, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$15.00 / 1,000 recipes

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?

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

## Instagram Recipe Extractor - Reels to Recipes, Any Language

Turn **Instagram cooking reels into structured recipes**: the dish, **ingredients with quantities and units**, equipment, steps, time and servings, read from **what is said and what is shown on screen**, in any language. Recipes stay in their own language, with **English versions** alongside, and can come as **schema.org Recipe JSON-LD** for a recipe site. Paste reel links or creator handles and click Start: **$15 per 1,000 recipes**. Reels with no recipe are free.

### What does it do?

- **Reads the whole reel.** The audio is transcribed in the language spoken, and the frames are read for on-screen text (ingredient lists, quantities, titles). Many recipe reels show the recipe and never say it; those are read too.
- **Extracts only what the reel says.** Quantities and units are kept as given ("190" stays "190", "a bit" stays "a bit"); nothing is converted or guessed. Missing values are `null`.
- **Any language.** Portuguese, Hindi, German, Japanese, French, Spanish and English were in our tests. The recipe stays in its own language, and `title_en`, `ingredients_en` and `steps_en` give the English.
- **Charged only for a recipe.** A reel with no recipe, a silent reel with no text, a private reel or a failure is a free row.
- **schema.org-friendly.** Turn on `recipeJsonLd` for a ready `Recipe` object per reel (`recipeIngredient`, `recipeInstructions`, `tool`, `totalTime`, `recipeYield`).

### Use cases

- **Recipe sites and apps:** import creators' recipes as structured data, with a link back to the reel.
- **Meal planning and shopping lists:** ingredients with quantities, ready to sum.
- **Food brands and marketers:** see which ingredients and dishes creators in a market are cooking.
- **Researchers:** cooking trends across languages, with the source reel for every recipe.
- **AI agents:** a stable row per reel, with `recipe_status` saying what was found.

### What data do you get?

| Field | What it is |
|---|---|
| `recipe` | `title`, `language`, `ingredients` \[{`item`, `quantity`, `unit`}], `equipment`, `steps`, `time_minutes`, `servings`, and `title_en`, `ingredients_en`, `steps_en` when the recipe isn't in English |
| `recipe_status` | `ok` (a recipe, charged), `none` (no recipe), `skipped` (nothing to read), `failed` |
| `is_recipe` | whether the reel holds a recipe at all |
| `has_speech`, `has_on_screen_text` | what the recipe was read from |
| `recipe_jsonld` | the recipe as schema.org `Recipe` JSON-LD (with `recipeJsonLd` on) |
| `transcript`, `language`, `on_screen_text` | the sources, as read |
| `shortcode`, `url`, `creator`, `caption`, `duration_s` | the reel |
| `charged_event` | `recipe` when charged, else `null` |

### How to extract recipes from Instagram reels

1. Paste reel or post links into **Reel and post links**, or creator usernames into **Creator handles**.
2. Leave **English versions** on to get the English next to the original; turn on **schema.org JSON-LD** if you publish recipes.
3. Click **Start**. Each reel becomes one row; download them as JSON, CSV or Excel, or read them through the API.

### How much does it cost to extract recipes?

| Price | Per 1,000 | Each | Charged when |
|---|---|---|---|
| Recipe | **$15 per 1,000 recipes** | $0.015 | the reel holds a recipe with at least one ingredient or step |
| No recipe, silent reels with no text, failures, private reels | **free** | $0 | never |

The transcript and the on-screen text are included: they are not charged on their own. English versions and JSON-LD cost nothing extra.

**Apify's reel scraper is billed to your account too.** To read Instagram, this actor calls Apify's own [Instagram Reel Scraper](https://apify.com/apify/instagram-reel-scraper) under your account, at its own price: about **$2.60 per 1,000 reels** on Apify's free plan (less on paid plans), for every reel read, recipe or not.

**Examples (our price, plus the scraper's ~$2.60 per 1,000 reels):**

- 6 recent reels from each of 10 cooking creators, 40 of them recipes: $0.60 + about $0.16.
- 1,000 reels from recipe hashtags, about 600 of them recipes: $9 + about $2.60.

### Input

```json
{
  "reelUrls": ["https://www.instagram.com/reel/De1_g_puK0E/"],
  "handles": [],
  "maxReelsPerHandle": 6,
  "englishVersions": true,
  "recipeJsonLd": false
}
```

- `reelUrls`: reel and post links (`/reel/`, `/reels/`, `/p/`, `/tv/`). A reel given twice is read and charged once.
- `handles`: usernames (`name`, `@name`) or profile links; each gives its `maxReelsPerHandle` most recent reels (default 6, at most 100), pinned reels skipped.
- `englishVersions` (default `true`): English versions of a recipe that isn't in English.
- `recipeJsonLd` (default `false`): add `recipe_jsonld`.
- An empty input runs the example reel, a cookie recipe.

### Output

```json
{
  "shortcode": "De1_g_puK0E",
  "url": "https://www.instagram.com/reel/De1_g_puK0E/",
  "creator": "…",
  "status": "ok",
  "language": "en",
  "transcript": "So hey you guys, hey. So today we're making chocolate chip cookies…",
  "on_screen_status": "found",
  "on_screen_text": "…",
  "recipe": {
    "title": "Chocolate chip cookies",
    "language": "en",
    "ingredients": [{ "item": "brown sugar", "quantity": null, "unit": null }, { "item": "cinnamon", "quantity": "a little", "unit": null }],
    "equipment": [],
    "steps": ["Mix brown sugar, white sugar, butter, egg and vanilla.", "Scoop and bake."],
    "time_minutes": null,
    "servings": null,
    "title_en": null,
    "ingredients_en": null,
    "steps_en": null
  },
  "recipe_status": "ok",
  "is_recipe": true,
  "has_speech": true,
  "has_on_screen_text": true,
  "recipe_jsonld": null,
  "charged_event": "recipe"
}
```

- **`status`** is the audio's: `ok` (speech transcribed), `no_speech` or `error`. A silent reel with its recipe on screen has `status: "no_speech"` and `recipe_status: "ok"`, and is charged as a recipe.
- **`recipe`** is `null` when the reel holds no recipe. A reel that names only equipment, or only a dish, comes back with `recipe_status: "none"`, free.
- With `recipeJsonLd` on, `recipe_jsonld` is a schema.org `Recipe` in the recipe's own language (`inLanguage`), with the reel as `url` and the creator as `author`.

### How accurate is it (measured)

In our tests of **120 recipe-hashtag reels in 7 languages, Oct 2026**: fidelity **9.5/10**, completeness **8.3/10**; about **2–3 small slips per 10 recipes**, such as a loosely translated ingredient or an implied piece of equipment — **check quantities before publishing**.

- **Fidelity:** nothing in the recipe that the reel doesn't say or show. **Completeness:** every ingredient, quantity and step in the reel is in the recipe.
- The slips we saw: *pimentón* translated as "bell pepper" rather than paprika; an oven listed when the reel only said "200 degrees"; an ingredient split in two; a vague quantity turned into a number.

### Error codes

Every row with an error code is free (unless its recipe was read from on-screen text: see `no_speech`).

| `error_code` | Meaning |
|---|---|
| `no_speech` | No speech in the audio. On-screen text is still read, and a recipe found there is charged. |
| `private` | The reel or profile is private, age-restricted or needs a login. |
| `unavailable` | Deleted, not found, or a handle with no public reels. |
| `no_audio` | The post has no audio: a photo or carousel post, or a video file with no sound. On-screen text is still read when there is a video. |
| `download_failed` | The audio and video files didn't download after 3 attempts each. |
| `transcription_failed` | Both speech-to-text models failed after their retries. |
| `invalid_input` | Not an Instagram reel or post link, or not a handle. |
| `internal_error` | An unexpected error on our side. Please open an issue. |

`recipe_status: "failed"` (with `recipe_error`) means the recipe model failed on that reel: the row is free.

### FAQ

#### How much does it cost?

$15 per 1,000 recipes ($0.015 each), charged only when a recipe with at least one ingredient or step is found. Reels with no recipe, silent reels with no text, failures and private reels are free. Apify's reel scraper, which this actor calls under your account, adds about $2.60 per 1,000 reels on the free plan.

#### Does it work when the recipe is only on screen?

Yes. On-screen text is always read, so a silent reel that shows its ingredient list still gives a recipe.

#### Will it invent quantities?

It is told never to, and quantities come back as the reel gives them, or `null`. In our tests it made about 2–3 small slips per 10 recipes, so check quantities before publishing.

#### Which language do I get?

The recipe's own. With `englishVersions` on (the default), a recipe in another language also has `title_en`, `ingredients_en` and `steps_en`.

#### Can I use it with the API or an MCP server?

Yes. `POST` your input to `https://api.apify.com/v2/acts/neonroobz~instagram-recipes/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, or add `https://mcp.apify.com?tools=neonroobz/instagram-recipes` to an MCP client and ask, for example, "get the recipes from the last 6 reels of @creator".

#### Is it legal?

This actor reads only public reels, as a logged-out viewer would see them, and stores no personal data beyond the public creator handle. Recipes in reels are the creators' work: link back to the reel and check how you may reuse them. Instagram's terms restrict automated collection. If you're unsure, ask a lawyer.

#### What about my spending limit?

A reel starts only when its recipe price still fits under the limit you set, so you are never charged past it. Reels not reached are listed under `not_processed` in the run summary (the `OUTPUT` record).

#### Is anything stored?

No. Nothing is kept between runs.

### How we measured

- **Test sets:** three sets of 40 public reels, picked mechanically in Oct 2026 from recipe hashtags: English, and Portuguese, Hindi, German, Japanese, French and Spanish recipe tags.
- **Judging:** two text judges from different model families (google/gemini-2.5-flash and xiaomi/mimo-v2.5) read the same transcript and on-screen text the extractor saw, and scored each recipe for fidelity and completeness, blind. The figures above are from the last set: 23 reels the judges called recipes.
- **Caveats:** model judges, recipe hashtags only. After the tests, five rules were added to the extraction prompt to target the slips above (vague quantities kept in words, equipment only when named or shown, alternatives kept as one ingredient, temperatures and times kept in their step, an uncertain translation kept in the original word). With `englishVersions` off, a shorter prompt is used, which was not part of the tests.

### Limits

- **Public reels only.** Private, age-restricted and login-only reels come back as free `private` rows.
- **Only what the reel gives.** Many reels leave out quantities or steps; those come back as `null` or missing, never filled in.
- **Models make mistakes:** about 2–3 small slips per 10 recipes in our tests. Check quantities before publishing.
- **The caption is not read.** The recipe comes from the audio and the on-screen text only.
- **schema.org JSON-LD** is built from what the reel gives: a recipe with no named dish has no `name`, which some search engines require.

### Feedback

A recipe came back wrong, or something broke? Open an issue in the **Issues** tab with the reel link. We aim to fix a break within a day of finding it.

### Changelog

- **1.0 (24 Oct 2026):** first release.

# Actor input Schema

## `reelUrls` (type: `array`):

instagram.com/reel/..., /reels/..., /p/... or /tv/... links. A reel given twice is fetched and charged once.

## `handles` (type: `array`):

Usernames (name or @name) or profile links of cooking creators. Each gives its most recent reels, up to maxReelsPerHandle; pinned reels are skipped.

## `maxReelsPerHandle` (type: `integer`):

Most recent reels taken from each handle. Default 6, maximum 100.

## `englishVersions` (type: `boolean`):

For a recipe not in English, also give title_en, ingredients_en and steps_en. The recipe itself always stays in its own language. Same price.

## `recipeJsonLd` (type: `boolean`):

Also give each recipe as schema.org Recipe JSON-LD (recipe_jsonld), ready for a recipe site. Same price.

## Actor input object example

```json
{
  "reelUrls": [
    "https://www.instagram.com/reel/De1_g_puK0E/"
  ],
  "handles": [],
  "maxReelsPerHandle": 6,
  "englishVersions": true,
  "recipeJsonLd": false
}
```

# Actor output Schema

## `recipes` (type: `string`):

Recipes: one row per reel, including free rows for reels with no recipe, silent reels and failures, each with recipe_status.

## `summary` (type: `string`):

Run summary: recipes found, counts by status and error code, models used, events charged, model and vision cost.

# 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 = {
    "reelUrls": [
        "https://www.instagram.com/reel/De1_g_puK0E/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neonroobz/instagram-recipes").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 = { "reelUrls": ["https://www.instagram.com/reel/De1_g_puK0E/"] }

# Run the Actor and wait for it to finish
run = client.actor("neonroobz/instagram-recipes").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 '{
  "reelUrls": [
    "https://www.instagram.com/reel/De1_g_puK0E/"
  ]
}' |
apify call neonroobz/instagram-recipes --silent --output-dataset

```

## MCP server setup

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

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/mF2BMxb3kiAxdvlpU/builds/BPV19VMW8Sn6UJdET/openapi.json
