← All guides

πŸ“‘ We check www.thecocktaildb.com (and 75+ other public dev APIs) with a plain GET every 30 minutes β€” see the live status page. As of publishing it's up and answering in under half a second.

TheCocktailDB alternative β€” a cocktail API with full ingredient search and writes

TheCocktailDB is the drinks API behind nearly every cocktail-app tutorial: real recipes with photos, a free test key (1) right in the URL, CORS open, run by the same folks as TheMealDB. It's alive, fast, and β€” rare in this space β€” even publishes an AGENTS.md for AI tools. Genuinely good teaching material.

But cocktail-app tutorials hit walls that are sharper than TheMealDB's (all checked live on September 16, 2026):

The fix that keeps your rendering code: copy real records into a free hosted mock API you fully control β€” same field names (strDrink, strGlass, even strIngredient1…strIngredient15), plus substring search, ingredient search that returns everything, writes that persist, and one consistent {"drinks":[…]} response shape. No signup, no key.

1. Migrate real records in two curls

# 1. pull a batch from TheCocktailDB and wrap it as a db.json
curl "https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita" \
  | python3 -c "import sys,json; print(json.dumps({'drinks': json.load(sys.stdin)['drinks']}))" \
  > db.json

# 2. import it β€” the response includes your project id + admin key
curl -X POST "https://mockbird.mockbird.workers.dev/api/projects/import?name=cocktails" \
  -H 'content-type: application/json' --data-binary @db.json

That hosted 6 margaritas for us, verbatim and with zero warnings: strInstructions in five languages intact, strDrinkThumb photo URLs untouched, and idDrink still the string "11007" so tutorial code doing strict comparisons keeps working. Your ingredient loop over strIngredient1–strIngredient15 runs unchanged.

2. The translation table

TheCocktailDBYour Mockbird project
search.php?s=margarita/drinks?strDrink_like=margarita β€” same case-insensitive substring semantics
lookup.php?i=11007/drinks/1 β€” or filter ?idDrink=11007; a bad id is a real 404, not 200 null
filter.php?c=Ordinary_Drink/drinks?strCategory=Ordinary%20Drink
filter.php?g=Cocktail_glass/drinks?strGlass=Cocktail%20glass
filter.php?a=Alcoholic/drinks?strAlcoholic=Alcoholic
filter.php?i=vodka (one drink!)?q=vodka β€” matches the ingredient in any strIngredient slot and returns every hit
filter's slim 3-field shape?select=strDrink,strDrinkThumb,idDrink
random.php?sortBy=random&limit=1 β€” a different draw every request
100-item listing cap?page=2&limit=10 + X-Total-Count header
multi-ingredient filter (Premium)honest gap: q= is one term; chain exact matches like ?strIngredient1=Tequila only if you know the slot
curl "https://mockbird.mockbird.workers.dev/m/PROJECT_ID/drinks?strDrink_like=blue&select=strDrink"
# β†’ [{"id":2,"strDrink":"Blue Margarita"}]

curl "https://mockbird.mockbird.workers.dev/m/PROJECT_ID/drinks?q=curacao&select=strDrink"
# β†’ finds the curaΓ§ao drink by INGREDIENT β€” every slot searched, every hit returned

3. One response shape β€” the null / "no data found" mess, fixed

Tutorial code reads data.drinks. One query param reproduces that envelope exactly:

curl "https://mockbird.mockbird.workers.dev/m/PROJECT_ID/drinks?mock_envelope=%7B%22drinks%22%3A%22%24data%22%7D&strDrink_like=tommy&select=strDrink"
# β†’ {"drinks":[{"id":3,"strDrink":"Tommy's Margarita"}]}

# no match? you get {"drinks":[]} β€” an ARRAY, every time.
# not null, not the string "no data found". One shape, one code path.

Set it once as the project default (PUT /api/projects/:id/settings {"envelope":…}) and every GET answers in TheCocktailDB's shape β€” the rest of your fetch code doesn't change at all. Details in docs β†’ envelope.

4. The part their API can't do at all: writes

curl -X POST https://mockbird.mockbird.workers.dev/m/PROJECT_ID/drinks \
  -H 'content-type: application/json' \
  -d '{"strDrink":"Test Paloma","strCategory":"Ordinary Drink","strIngredient1":"Tequila"}'
# β†’ 201 {"id":7,…}   β€” and GET /drinks/7 returns it. It persists.

That turns the standard read-only cocktail grid into full CRUD: an add-a-recipe form, an edit page, favourites that survive a refresh. A portfolio piece instead of a fetch demo.

5. Rehearse the bad days

# rate-limited twice, then success β€” exercise your retry logic
curl "https://mockbird.mockbird.workers.dev/m/PROJECT_ID/drinks?mock_seq=429,429,200"

# slow response for your skeleton/loading state
curl "https://mockbird.mockbird.workers.dev/m/PROJECT_ID/drinks?strDrink_like=marg&mock_delay=2000"

More recipes in testing loading & error states.

Where TheCocktailDB still wins

Credit where due: TheCocktailDB's content is the product β€” hundreds of real, crowd-sourced cocktail recipes with photos, categories, glass types, and multilingual instructions, maintained for years and answering our checks in under half a second. We host your copy of some records; we don't have their catalogue, and your import is a snapshot, not a live mirror. If you're learning fetch in dev, their test key is fine, and the one-off Premium fee is a fair deal if you ship a real drinks app on their data β€” it buys the full ingredient filter, multi-ingredient search, and an app-store licence. The honest split: real drink content and photos β†’ TheCocktailDB. Your own records with full search, writes, one consistent response shape, pagination past 100, and failure drills β€” licensed for whatever you ship β†’ your import.

Start now

The two-curl block in section 1, or zero setup at all:

curl https://mockbird.mockbird.workers.dev/m/demo/products?limit=3

Facts checked live on September 16, 2026: search.php?s=zzzznotadrink and lookup.php?i=99999 both answer 200 {"drinks":null} while filter.php?c=NotACategory and filter.php?g=NotAGlass answer 200 {"drinks":"no data found"} (a string); filter.php?i=vodka|gin|rum|tequila each returned exactly 1 drink on the test key, as did popular.php, latest.php, and randomselection.php (all marked "*Premium API only" on api.php); filter.php?c=Cocktail returned exactly 100 items and the docs state Premium subscribers "can also list the full database rather than limited to 100 items"; the docs state the test key 1 is for development or educational use and that a Premium key is required "if releasing publicly on an appstore", with multi-ingredient filtering Premium-only. Every Mockbird command on this page was run against a live project before publishing.

Full API reference in the docs. More guides: TheMealDB alternative Β· FakeStoreAPI alternative Β· DummyJSON alternative Β· Mock API for React Β· Host a JSON file as an API. Create your API β†’

⚑ Skip the terminal: this link opens the dashboard's import panel β€” paste the db.json from section 1 and you're done. No signup.