{"openapi":"3.1.0","info":{"title":"Part Recipes API","version":"1.0.0","description":"Public, read-only access to the Part Recipes collection. All endpoints are unauthenticated; an optional Bearer API key raises rate limits."},"servers":[{"url":"/api/v1"}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer"}},"schemas":{"RecipeCard":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"cuisine":{"type":"string","nullable":true},"difficulty":{"type":"string","enum":["easy","medium","hard"],"nullable":true},"timeTotalMin":{"type":"integer","nullable":true},"dishPhoto":{"type":"string","nullable":true},"bookTitle":{"type":"string","nullable":true},"avgRating":{"type":"number","nullable":true},"cookedCount":{"type":"integer"}}}}},"paths":{"/books":{"get":{"summary":"List books","responses":{"200":{"description":"Array of books"}}}},"/books/{id}":{"get":{"summary":"Get a book","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Resource id"}],"responses":{"200":{"description":"Book"}}}},"/books/{id}/recipes":{"get":{"summary":"List a book's recipes","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Resource id"}],"responses":{"200":{"description":"Recipes"}}}},"/recipes":{"get":{"summary":"List recipes","parameters":[{"name":"cuisine","in":"query","required":false,"schema":{"type":"string"}},{"name":"difficulty","in":"query","required":false,"schema":{"type":"string"}},{"name":"tag","in":"query","required":false,"schema":{"type":"string"}},{"name":"max_time","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Recipes"}}}},"/recipes/{id}":{"get":{"summary":"Get a recipe by id or slug","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"id or slug"}],"responses":{"200":{"description":"Recipe"}}}},"/recipes/search":{"get":{"summary":"Search: pantry match, full-text, or semantic","parameters":[{"name":"ingredients","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated ingredients for pantry match"},{"name":"missing_max","in":"query","required":false,"schema":{"type":"integer"},"description":"Max missing ingredients allowed (pantry mode)"},{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Free-text query (full-text, or semantic with semantic=1)"},{"name":"semantic","in":"query","required":false,"schema":{"type":"string"},"description":"Set to 1 for vector/semantic search"},{"name":"cuisine","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Search results"}}}},"/ingredients":{"get":{"summary":"List ingredients","responses":{"200":{"description":"Ingredients"}}}},"/ingredients/{id}/recipes":{"get":{"summary":"Recipes using an ingredient","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Resource id"}],"responses":{"200":{"description":"Recipes"}}}},"/authors":{"get":{"summary":"List authors","responses":{"200":{"description":"Authors"}}}},"/tags":{"get":{"summary":"List tags","responses":{"200":{"description":"Tags"}}}}}}