DEV Community

Charbel Daccache
Charbel Daccache

Posted on

How to Extract a Recipe from a TikTok or Instagram Video as JSON (with Python)

To extract a recipe from a TikTok, Instagram Reel or YouTube video, combine the caption, the spoken words and any recipe page the creator links to, then have an AI model turn them into structured ingredients and steps. This guide shows how to do that with one API call and get back clean recipe JSON: ingredients split into quantity, unit and item, numbered steps, times and servings.

This is part 3 of "How my fun projects turned into APIs". Each post takes one side project, explains how it works, and ends with something you can call from your own code. Part 1 covered finding TikTok creator emails, and part 2 covered video transcripts.

Table of contents

  1. Why saving recipes from videos is so annoying
  2. How the recipe extractor works
  3. How to extract a recipe from a video in 4 steps
  4. How to extract recipes with Python
  5. How to extract recipes with JavaScript
  6. What the recipe JSON looks like
  7. How much it costs
  8. FAQ

Why saving recipes from videos is so annoying

Short cooking videos are where a lot of people find recipes now. Saving one is still a mess:

  1. The caption says "recipe in the comments" or "comment RECIPE and I'll DM you".
  2. The amounts are only spoken, quickly, once.
  3. Sometimes the full recipe is on the creator's blog, behind a link in the caption.
  4. You end up pausing the video and typing it out by hand.

Every recipe and meal-planning app wants a "save from TikTok" button, and every one of them has to solve this.

The project that started it

In part 2 I built a transcript tool for a small study comparing TikTok recipes with the classic versions of the same dishes. The transcripts gave me the words, but a wall of text isn't a recipe. To compare dishes, I needed ingredients as data: "2 cups flour, sifted" as quantity 2, unit cup, item flour, note sifted.

So I fed the transcript and caption to an AI model and asked for structured JSON. The first version worked, and also made things up. When a creator said "a bit of salt", the model would sometimes write "1 tsp salt" as if it were a fact.

That led to the two rules the tool still follows. First, if the creator links a written recipe, read that page and use its exact amounts. Second, every ingredient must be backed by a quote from the source, and anything the source never states is flagged as inferred with low confidence.

By the end of the study I had a pipeline that turned any cooking video into reliable recipe JSON. That's exactly what recipe apps need, so I made it a public API.

How the recipe extractor works

The tool is an Apify Actor called Recipe Extractor. It works with TikTok videos, Instagram Reels, YouTube videos and Shorts, and regular recipe websites.

1. It collects every signal

For each URL it gathers the caption, the platform's own subtitles (TikTok speech-to-text, YouTube captions), any recipe page linked in the caption, and the video's cover image.

2. Exact recipes win

Many creators link the full written recipe. When they do, Recipe Extractor follows the link and reads the site's schema.org recipe data, so amounts are exact rather than guessed from speech. Those rows come back with method: "jsonld".

3. An AI model merges the rest

When there is no written recipe, an AI model (DeepSeek V4 Flash by default, Claude optional) merges the signals into one recipe. Each ingredient gets a confidence score and the source it came from, so your app can trust the exact amounts and send guesses to a quick human check.

4. You only pay for real recipes

Videos that aren't recipes, "comment RECIPE" videos with no recipe in them, and failed URLs are returned with a clear status and are free.

How to extract a recipe from a video in 4 steps

  1. Create a free Apify account. The free plan's credit covers your first recipes.
  2. Open Recipe Extractor and click Try for free.
  3. Paste this input (switch the input editor to JSON):
{
  "urls": [
    "https://www.tiktok.com/@recipes/video/7447547249720053000",
    "https://www.instagram.com/reel/Dd-VQPnRz0t/",
    "https://youtube.com/shorts/PM4lHUNQSvY"
  ],
  "units": "metric",
  "includeNutrition": true
}
Enter fullscreen mode Exit fullscreen mode
  1. Click Start. Each URL becomes one row, usually within 10 to 30 seconds. Export the results as JSON, CSV or Excel, or read them through the API.

How to extract recipes with Python

Install the client with pip install apify-client, then:

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("scrape-lads/recipe-extractor").call(run_input={
    "urls": ["https://www.instagram.com/reel/Dd-VQPnRz0t/"],
    "units": "metric",
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["status"] != "success":
        print(row["inputUrl"], row["status"])
        continue
    recipe = row["recipe"]
    print(recipe["title"], "-", recipe["servings"], "servings")
    for ing in recipe["ingredients"]:
        print(" ", ing["quantity"], ing["unit"], ing["item"], f"({ing['confidence']})")
Enter fullscreen mode Exit fullscreen mode

Your API token is in Apify Console under Settings → API & Integrations.

How to extract recipes with JavaScript

Install the client with npm install apify-client, then:

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('scrape-lads/recipe-extractor').call({
  urls: ['https://youtube.com/shorts/PM4lHUNQSvY'],
  units: 'us',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) {
  if (row.status !== 'success') continue;
  console.log(row.recipe.title);
  row.recipe.steps.forEach((s) => console.log(`${s.n}. ${s.text}`));
}
Enter fullscreen mode Exit fullscreen mode

What the recipe JSON looks like

One row per URL. A shortened real result for an Instagram Reel whose creator linked their blog:

{
  "inputUrl": "https://www.instagram.com/reel/Dd-VQPnRz0t/",
  "status": "success",
  "recipe": {
    "title": "Spaghetti Squash Lasagna",
    "servings": 4,
    "times": { "prepMin": 10, "cookMin": 60, "totalMin": 70 },
    "ingredients": [
      {
        "raw": "1 pound lean ground beef",
        "quantity": 1,
        "unit": "lb",
        "item": "lean ground beef",
        "converted": { "quantity": 454, "unit": "g" },
        "confidence": 0.99,
        "source": "linked_recipe_page"
      }
    ],
    "steps": [
      { "n": 1, "text": "Preheat the oven to 400ºF.", "timestampSec": null }
    ],
    "cuisine": "Italian",
    "dietary": ["gluten-free"],
    "nutrition": { "estimated": false, "calories": 513, "proteinG": 34 }
  },
  "source": {
    "platform": "instagram",
    "author": "feelgoodfoodie",
    "linkedRecipeUrl": "https://feelgoodfoodie.net/recipe/spaghetti-squash-lasagna-boats/"
  },
  "overallConfidence": 0.99,
  "method": "jsonld"
}
Enter fullscreen mode Exit fullscreen mode
Field What it is
recipe.ingredients[] quantity, quantityMax (ranges), unit, item, note, optional, converted, confidence, source
recipe.steps[] Numbered steps, with timestampSec showing where each happens in the video
recipe.times, recipe.servings Prep, cook and total minutes; servings as a number
recipe.tags, cuisine, dietary For filtering and search
recipe.nutrition Per serving; estimated: true when computed from ingredients
status success, incomplete, not_a_recipe or failed
method jsonld (exact written recipe) or llm (merged by the model)

Options worth knowing

  • units: original, metric or us, for grocery lists without your own conversion code.
  • translateTo: write the recipe in another language, for example English.
  • includeNutrition: per-serving calories and macros.
  • followRecipeLinks: read the written recipe linked from the caption (on by default, and worth keeping on).

How much it costs

  • $0.03 per successful recipe ($30 per 1,000)
  • $0.002 per run
  • Failed URLs, non-recipe videos and incomplete recipes are free
  • Higher Apify plans get volume discounts down to $0.018 per recipe
Example Cost
1 TikTok recipe $0.032
100 Instagram Reels, 60 of them full recipes $1.80
1,000 YouTube recipe videos about $30

FAQ

How do I save a recipe from TikTok?

Paste the TikTok link into the extractor. It reads the caption, TikTok's subtitles and any linked recipe page, and returns the recipe as structured JSON you can store in your app or a spreadsheet.

Can it get recipes from Instagram Reels?

Yes. Instagram publishes no subtitles, so Reels are read from the caption, linked recipe pages and the cover image. Reels whose recipe is only spoken come back as incomplete and are free.

What happens with "comment RECIPE" videos?

If the recipe isn't in the video's content, there's nothing to extract. The row comes back as incomplete, says so, and isn't charged.

Does it invent ingredient amounts?

Each ingredient must be backed by a quote from the source. Anything the source never states is flagged as inferred with low confidence, so your app can show it to the user for a quick check.

Is there an official API for recipes from TikTok or Instagram?

No. No platform offers an API that returns a recipe from a video. Their APIs give captions or metadata at best, and only to approved apps.

Does it download the videos?

No. It reads the public caption, public subtitles, linked pages and the cover image. It doesn't download or redistribute video.

Try it

Next in the series: after three side projects, I wanted to know what to build next, so I went looking for people asking for tools on Reddit. Part 4 is the Reddit scraper that came out of that.

Top comments (0)