API

Authentication

All endpoints require a Bearer token in the Authorization header:

Authorization: Bearer <API_TOKEN>

Endpoints

POST /api/upload

Add a recipe or tip. The type is auto-detected from the request body: if it contains ingredients or directions it's a recipe; if it contains items it's a tip.

Returns 201 with the new record's type and id on success.

GET /api/recipes

Returns all recipes as a JSON array.

GET /api/recipes/<id>

Returns a single recipe by id.

GET /api/tips

Returns all tips as a JSON array.

GET /api/tips/<id>

Returns a single tip by id.

GET /api/export

Export the full database as JSON. Returns an object with recipes and tips arrays.

Schemas

Recipe

{
  "title": "Crispy Chicken Thighs",
  "category": "chicken",
  "prep_time": 5,
  "cook_time": 25,
  "portion_count": "4 servings",
  "ingredients": [
    {"name": "chicken thighs", "amount": "4"},
    {"name": "salt", "amount": "1 tsp"}
  ],
  "directions": [
    "Pat chicken dry and season.",
    "Place skin-side down in a cold skillet."
  ],
  "notes": "Start skin-side down for crispiest skin.",
  "source_conversation": "Chicken_experiments_2026-02-09",
  "created_at": "2026-02-09 14:30:00",
  "source_type": "ai",
  "highlight": true
}

title (required) — descriptive name for the recipe

category (required) — chicken, seafood, sushi, dessert, coffee, sauce, breakfast, side, drink, beef, pork, pasta

ingredients (required) — array of objects with name and amount

directions (required) — array of step strings

prep_time / cook_time — integers in minutes

portion_count — string (e.g., "4 servings", "24 cookies")

notes — additional context or tips

source_conversation — identifier for the originating conversation (stored but not displayed on the site)

created_at — datetime string, defaults to current time if not provided

source_type — origin of the recipe: ai, personal, cookbook, or online (defaults to "ai")

highlight — boolean, featured on landing page and sorted to top of lists (defaults to false)

Tip

{
  "title": "Hoisin Sauce Substitutes",
  "category": "substitution",
  "items": [
    {"name": "Soy sauce + peanut butter + honey", "details": "Mix equal parts"},
    {"name": "Teriyaki sauce", "details": "Similar sweetness"}
  ],
  "notes": "Match the thick, sweet consistency of hoisin.",
  "source_conversation": "Chicken_experiments_2026-02-09",
  "created_at": "2026-02-09 14:30:00",
  "source_type": "ai",
  "highlight": true
}

title (required) — descriptive name for the tip

category (required) — pairing, storage, substitution, technique, tip

items (required) — array of objects with name and details

notes — additional context

source_conversation — identifier for the originating conversation (stored but not displayed on the site)

created_at — datetime string, defaults to current time if not provided

source_type — origin of the tip: ai, personal, cookbook, or online (defaults to "ai")

highlight — boolean, featured on landing page and sorted to top of lists (defaults to false)

Example

curl -X POST http://localhost:5000/api/upload \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-token" \
  -d '{
    "title": "Crispy Chicken Thighs",
    "category": "chicken",
    "ingredients": [{"name": "chicken thighs", "amount": "4"}],
    "directions": ["Pat dry.", "Season.", "Cook."]
  }'