---
title: "Spoonacular alternatives: what to use instead (2026) — Tiny Plates"
description: "Spoonacular alternatives compared: Edamam, TheMealDB, API Ninjas, FatSecret and Tiny Plates. Prices, caching rules and a migration guide with code."
url: "https://www.tinyplates.dev/blog/spoonacular-alternatives"
---

# Spoonacular alternatives: what to use instead, and what it costs

Why people leave Spoonacular, what to use instead, and how to move your recipe calls over.

17 October 2026

Spoonacular is often the first recipe API people find. It's big, it's well documented and the free key takes a minute to get. Then, a few weeks in, the questions start. Why did that request cost three points? Why am I out of quota at lunchtime? Wait, I have to delete my cache after an hour?

If that sounds familiar, this post is for you. We'll be fair about what Spoonacular does well, go through the alternatives, and then show how to move your recipe calls over. Full disclosure: we run one of those alternatives, Tiny Plates. We'll say so when something else is the better fit.

Everything about Spoonacular below comes from its [pricing page](https://spoonacular.com/food-api/pricing) and [terms](https://spoonacular.com/food-api/terms), checked in October 2026.

## Why people look elsewhere

**Points are hard to predict.** Spoonacular doesn't count requests. It counts points. A recipe search costs 1 point plus 0.01 for each result, and some options add more. That's fair in a way, since bigger answers cost more. But it makes budgeting tricky. One screen in your app might cost one point or five, depending on what it asks for.

**The free plan is small.** It's 50 points a day, at 1 request per second, with a backlink to Spoonacular required. When the points run out, you get a 402 error until the next day. That's enough to try things. It's tight for a demo that more than a few people use.

**The cost grows fast.** Paid plans are $29 a month for 1,500 points a day, $79 for 4,500 and $149 for 10,000\. Enterprise starts at $300\. Extra points cost between $0.002 and $0.005 each, depending on the plan. For a small app that's fine. For a side project with no income, it can sting.

**The caching rules.** This is the one that surprises people most. The terms allow caching for at most one hour, and only with written permission. You can keep the recipe id, title and image URL forever, and nothing else. If you stop using the API, you're meant to delete everything you ever got from it. So you can't build a favourites screen that works offline, or slowly grow your own recipe library. Every view is a fresh call.

**Attribution.** You need to credit the original recipe source with a link. That's normal for recipe data, and most APIs ask for something similar. Just plan for it in your design.

To be fair, Spoonacular covers a lot of ground. One key gets you recipes, 600K+ grocery products, 115K+ restaurant menu items, meal planning, wine pairings, price estimates and health scores. Nothing else does all of that in one place.

The paid plans come with an uptime promise: 99% on the $29 and $79 plans and 99.9% on the $149 plan. It also has an MCP server for agents. If you need grocery products or menus, or you need a signed uptime promise today, stay with Spoonacular. Switching would mean stitching three APIs together.

## The alternatives

We wrote a longer rundown in [the best recipe APIs in 2026](https://www.tinyplates.dev/blog/best-recipe-apis). Here's the short version, from the angle of someone leaving Spoonacular.

**Edamam** is the pick if you need size. Over 2 million web recipes and very good nutrition data. There's no free plan for Recipe Search, and it starts at $9 a month for 10,000 calls. The catch: on the $9 and $99 plans, the cooking steps aren't in the response. You link out to the source. Caching is just as tight, limited to the recipe id and name, plus a few nutrition numbers on the higher plans.

**TheMealDB** is the pick for learning and demos. No sign-up, a free test key and simple JSON. It's small, with 793 meals when we checked, and ingredients are plain text. Going public needs a one-off $10 supporter upgrade.

**API Ninjas** has a recipe endpoint with over 125,000 recipes and structured ingredients. The free plan is 3,000 calls a month, but it's for evaluation only. Commercial use needs a paid plan.

**FatSecret Platform** is the pick if nutrition is the main event. Its free Basic tier allows 5,000 calls a day with US data and attribution. Recipes are part of a bigger food and nutrition database.

**Tiny Plates** is ours. It's free, with 50 requests a day and 300 a week per account. No credit card, no backlink for the API itself, and we raise the limit on request. One call is one request, whatever it returns. You may cache the recipes your users open, with no one-hour rule. You just can't copy the whole index.

It goes deep on the recipe. Every ingredient has quantity, unit, name and preparation in separate fields, with an ingredient id shared across English, Spanish and Swedish recipes. Every recipe says which of 16 allergens it contains. You also get scaling, metric and imperial conversion, substitutions, cooking from the fridge and one [shopping list](https://www.tinyplates.dev/blog/one-shopping-list-for-a-week-of-recipes) for a whole week.

What it doesn't have: grocery products, restaurant menus, wine pairings, price estimates or an uptime promise. And thousands of recipes, not millions. If you need those things, it's not your answer yet. We put the full side-by-side on [Tiny Plates vs Spoonacular](https://www.tinyplates.dev/compare/spoonacular).

## Moving your recipe calls over

The good news is that the main calls map one to one.

| What you're doing       | Spoonacular                                             | Tiny Plates                          |
| ----------------------- | ------------------------------------------------------- | ------------------------------------ |
| Search recipes          | GET /recipes/complexSearch?query=pasta                  | GET /search?query=pasta              |
| Leave out an allergen   | &intolerances=dairy                                     | &without=milk                        |
| Cook from what you have | GET /recipes/findByIngredients?ingredients=chicken,rice | GET /pantry?ingredients=chicken,rice |
| Get one recipe          | GET /recipes/{id}/information                           | GET /recipes/{id}                    |
| Shopping list           | Meal planner shopping list                              | GET /shopping-list?recipes=id1,id2   |

Want a recipe for six instead of four? Add `?servings=6` to the recipe call and every amount is rewritten. With Tiny Plates you send the key as a header: `Authorization: Bearer rd_your_api_key`. The allergen names are different, so `dairy` becomes `milk`, `egg` becomes `eggs` and `peanut` becomes `peanuts`. The full list is at `/vocabularies`. If you send a name we don't know, you get a clear error instead of a silent miss.

One difference to know about. On a free account, search doesn't take cuisine, diet or time filters. Each result does carry `cuisines`, `dietary` flags and `times`, so you can filter on those yourself after the search.

The recipe fields map like this:

| Spoonacular                              | Tiny Plates                                         |
| ---------------------------------------- | --------------------------------------------------- |
| id (a number)                            | id (a string)                                       |
| title                                    | title                                               |
| image                                    | media, the item with role: "hero"                   |
| servings                                 | servings.quantity                                   |
| readyInMinutes                           | times.total.seconds, divided by 60                  |
| sourceUrl                                | url                                                 |
| extendedIngredients\[\].name             | ingredients\[\].name                                |
| extendedIngredients\[\].amount and .unit | ingredients\[\].quantity.value and .unit            |
| extendedIngredients\[\].original         | ingredients\[\].original (or display)               |
| analyzedInstructions\[0\].steps\[\].step | instructions\[\].text                               |
| cuisines                                 | cuisines                                            |
| dishTypes                                | courses                                             |
| vegetarian, vegan, glutenFree, dairyFree | dietary.vegetarian, .vegan, .glutenFree, .dairyFree |

Times are in seconds, not minutes. A dietary flag can be missing, which means we don't know. `false` means a known no. And `display` is the line we'd show a cook. It's tidied up, and it follows scaling and unit conversion. `original` is exactly what the source wrote.

If your UI already reads Spoonacular's shape, the quickest move is a small adapter. Fetch from Tiny Plates, then hand your components the fields they expect:

```js
const API = 'https://api.tinyplates.dev'
const headers = { Authorization: `Bearer ${process.env.TINY_PLATES_KEY}` }

export async function getRecipe(id, servings) {
  const query = servings ? `?servings=${servings}` : ''
  const response = await fetch(`${API}/recipes/${id}${query}`, { headers })

  if (!response.ok) {
    throw new Error(`Tiny Plates answered ${response.status}`)
  }

  const { recipe } = await response.json()

  return toSpoonacularShape(recipe)
}

function toSpoonacularShape(recipe) {
  const hero = recipe.media.find((item) => item.role === 'hero')
  const totalSeconds = recipe.times.total?.seconds

  return {
    id: recipe.id,
    title: recipe.title,
    image: hero?.url,
    servings: recipe.servings?.quantity,
    readyInMinutes: totalSeconds ? Math.round(totalSeconds / 60) : undefined,
    sourceUrl: recipe.url,
    cuisines: recipe.cuisines,
    dishTypes: recipe.courses,
    vegetarian: recipe.dietary?.vegetarian ?? false,
    vegan: recipe.dietary?.vegan ?? false,
    glutenFree: recipe.dietary?.glutenFree ?? false,
    dairyFree: recipe.dietary?.dairyFree ?? false,
    extendedIngredients: recipe.ingredients.map((line) => ({
      name: line.name,
      amount: line.quantity?.value,
      unit: line.quantity?.unit ?? '',
      original: line.display
    })),
    analyzedInstructions: [
      {
        name: '',
        steps: recipe.instructions.map((step) => ({
          number: step.step,
          step: step.text
        }))
      }
    ]
  }
}

```

Note the `?? false` on the diet flags. That keeps Spoonacular's yes-or-no shape, but it turns "we don't know" into "no". It's a safe default for a badge. If you'd rather show "unknown", leave the value as it is.

Once that works, you can drop the adapter bit by bit. The richer fields are worth it. `preparation` gives you "finely chopped" on its own. `ingredientId` lets you match the same ingredient across recipes. And `allergens` gives you a plain true or false for each of 16 allergens. Here's what that adds up to in a [weekly meal planner](https://www.tinyplates.dev/blog/build-a-weekly-meal-planner-with-react):

Live, on the real API

## What's for dinner this week?

Easy lunches, weeknight dinners that don't fuss, and something to linger over at the weekend.

Your week goes here, Monday to Sunday, lunch and dinner. Don't fancy something? Swap it for another.

What about the data you already stored? Under Spoonacular's terms you can keep the recipe ids, titles and image URLs. Those ids won't match ours, so search by title to find a similar recipe. The rest of the cache has to go anyway when you stop using the API.

You don't have to move everything at once, either. Lots of apps keep Spoonacular for grocery products and use another API for recipes. That's a perfectly good setup.

If you want to try it, [grab a free key](https://www.tinyplates.dev/sign-up) and point one screen at it. You'll know within an afternoon if it fits.
