Files
2026-07-12 10:17:17 -04:00

1.7 KiB

Recipe Management via API

Beyond batch importing, the Mealie API supports full CRUD for recipes — useful for bulk deletion, tag assignment, or fixing metadata.

Authentication (same as batch import)

import requests
M = "http://127.0.0.1:9925"
token = requests.post(f"{M}/api/auth/token",
    data={"username": "email", "password": "pw", "grant_type": ""},
    headers={"Content-Type": "application/x-www-form-urlencoded"}
).json()["access_token"]
h = {"Authorization": f"Bearer {token}"}

List all recipes

r = requests.get(f"{M}/api/recipes?page=1&perPage=100", headers=h)
data = r.json()  # keys: page, per_page, total, total_pages, items
for recipe in data["items"]:
    print(f"[{recipe['id']}] {recipe['name']}")

Pagination: increment page until page > total_pages.

Delete recipes (single or bulk)

# Single
r = requests.delete(f"{M}/api/recipes/{recipe_id}", headers=h)

# Bulk with keyword filter
for recipe in data["items"]:
    if "pork" in recipe["name"].lower():
        r = requests.delete(f"{M}/api/recipes/{recipe['id']}", headers=h)
        print(f"Deleted: {recipe['name']} -> {r.status_code}")

HTTP 200 = success. No undo — confirm your filter before running.

Find by keyword

Check name, slug, description, and recipeIngredient for matching terms:

import json
txt = json.dumps(recipe).lower()
if "bacon" in txt:
    # recipe mentions bacon somewhere

Notes

  • Recipe IDs are UUIDs (e.g. 52fe7e87-49c2-4cd4-b4f3-82ae7e1b102b), not sequential integers.
  • The list endpoint returns limited fields; fetch individual recipes (GET /api/recipes/{id}) for full ingredient/instruction data.
  • Deletion is instant — no trash/recycle bin in Mealie.