{"openapi":"3.1.0","info":{"title":"Apeldoornsche Vleeseters API","version":"1.0.0","description":"Publieke, read-only REST API voor BBQ-recepten, gear-reviews en nieuws van Apeldoornsche Vleeseters. Geen authenticatie vereist. Zie ook /mcp.json voor een MCP-serverinterface en /llms.txt voor een samenvatting van de site.","contact":{"name":"Apeldoornsche Vleeseters","url":"https://apeldoornschevleeseters.nl/nl/developers","email":"apeldoornschevleeseters@gmail.com"},"license":{"name":"Content gebruik op aanvraag"}},"servers":[{"url":"https://apeldoornschevleeseters.nl","description":"Productie"}],"tags":[{"name":"recipes","description":"BBQ-recepten"},{"name":"reviews","description":"BBQ-gear reviews"},{"name":"news","description":"BBQ-nieuws"},{"name":"engagement","description":"Publieke like- en ratingcijfers per recept"}],"paths":{"/api/v1/recipes":{"get":{"operationId":"listRecipes","summary":"Lijst van BBQ-recepten","description":"Geeft een gepagineerde lijst van BBQ-recepten terug, optioneel gefilterd op categorie.","tags":["recipes"],"parameters":[{"name":"lang","in":"query","description":"Taal voor gelokaliseerde velden.","required":false,"schema":{"type":"string","enum":["nl","en","de","es"],"default":"nl"}},{"name":"limit","in":"query","description":"Maximum aantal resultaten per pagina.","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"offset","in":"query","description":"Aantal resultaten om over te slaan (paginering).","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"category","in":"query","required":false,"description":"Filter op exacte categorienaam (case-insensitive).","schema":{"type":"string"}}],"responses":{"200":{"description":"Gepagineerde lijst van recepten.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","description":"Unieke identifier van het recept, gebruikt in de URL."},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"cookingMethod":{"type":"string","nullable":true,"description":"Bv. \"Direct\", \"Indirect\", \"Low & Slow\"."},"servings":{"type":"integer","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"},"hasMore":{"type":"boolean"}},"required":["limit","offset","total","hasMore"]}},"required":["data","pagination"]}}}}}}},"/api/v1/recipes/{slug}":{"get":{"operationId":"getRecipe","summary":"Eén BBQ-recept ophalen","description":"Geeft metadata en samenvatting van één recept terug, inclusief kerntemperatuur en bereidingstijden.","tags":["recipes"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Recept-slug, zoals teruggegeven door GET /api/v1/recipes.","schema":{"type":"string"}},{"name":"lang","in":"query","description":"Taal voor gelokaliseerde velden.","required":false,"schema":{"type":"string","enum":["nl","en","de","es"],"default":"nl"}}],"responses":{"200":{"description":"Het opgevraagde recept.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"type":"object","properties":{"slug":{"type":"string","description":"Unieke identifier van het recept, gebruikt in de URL."},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"cookingMethod":{"type":"string","nullable":true,"description":"Bv. \"Direct\", \"Indirect\", \"Low & Slow\"."},"servings":{"type":"integer","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]},{"type":"object","properties":{"image":{"type":"string","format":"uri","nullable":true},"bbqTemperature":{"type":"string","nullable":true},"bbqTime":{"type":"string","nullable":true},"prepTimeMinutes":{"type":"integer","nullable":true},"totalTime":{"type":"string","nullable":true},"nutrition":{"type":"object","nullable":true,"additionalProperties":true},"availableLanguages":{"type":"array","items":{"type":"string"}}}}]}},"required":["data"]}}}},"404":{"description":"Geen recept gevonden met deze slug.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-leesbare foutcode, bv. \"not_found\"."},"message":{"type":"string","description":"Mensleesbare uitleg van de fout."},"hint":{"type":"string","description":"Suggestie om de fout op te lossen."}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/reviews":{"get":{"operationId":"listReviews","summary":"Lijst van BBQ-gear reviews","description":"Geeft een gepagineerde lijst van geteste BBQ-gear reviews terug, met score en samenvatting.","tags":["reviews"],"parameters":[{"name":"lang","in":"query","description":"Taal voor gelokaliseerde velden.","required":false,"schema":{"type":"string","enum":["nl","en","de","es"],"default":"nl"}},{"name":"limit","in":"query","description":"Maximum aantal resultaten per pagina.","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"offset","in":"query","description":"Aantal resultaten om over te slaan (paginering).","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Gepagineerde lijst van reviews.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"brand":{"type":"string","nullable":true},"product":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"score":{"type":"number","nullable":true,"description":"Score op 10."},"summary":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["id","title","url"]}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"},"hasMore":{"type":"boolean"}},"required":["limit","offset","total","hasMore"]}},"required":["data","pagination"]}}}}}}},"/api/v1/reviews/{id}":{"get":{"operationId":"getReview","summary":"Eén BBQ-gear review ophalen","description":"Geeft het volledige oordeel (pluspunten, minpunten, eindconclusie) van één review terug.","tags":["reviews"],"parameters":[{"name":"id","in":"path","required":true,"description":"Review-id, zoals teruggegeven door GET /api/v1/reviews.","schema":{"type":"string"}},{"name":"lang","in":"query","description":"Taal voor gelokaliseerde velden.","required":false,"schema":{"type":"string","enum":["nl","en","de","es"],"default":"nl"}}],"responses":{"200":{"description":"De opgevraagde review.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"brand":{"type":"string","nullable":true},"product":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"score":{"type":"number","nullable":true,"description":"Score op 10."},"summary":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["id","title","url"]},{"type":"object","properties":{"image":{"type":"string","format":"uri","nullable":true},"pros":{"type":"array","items":{"type":"string"}},"cons":{"type":"array","items":{"type":"string"}},"verdict":{"type":"string","nullable":true},"publishedAt":{"type":"string","format":"date","nullable":true},"updatedAt":{"type":"string","format":"date","nullable":true}}}]}},"required":["data"]}}}},"404":{"description":"Geen review gevonden met dit id.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-leesbare foutcode, bv. \"not_found\"."},"message":{"type":"string","description":"Mensleesbare uitleg van de fout."},"hint":{"type":"string","description":"Suggestie om de fout op te lossen."}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/news":{"get":{"operationId":"listNews","summary":"Lijst van BBQ-nieuwsberichten","description":"Geeft een gepagineerde lijst van nieuwsberichten terug, nieuwste eerst.","tags":["news"],"parameters":[{"name":"lang","in":"query","description":"Taal voor gelokaliseerde velden.","required":false,"schema":{"type":"string","enum":["nl","en","de","es"],"default":"nl"}},{"name":"limit","in":"query","description":"Maximum aantal resultaten per pagina.","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"offset","in":"query","description":"Aantal resultaten om over te slaan (paginering).","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Gepagineerde lijst van nieuwsberichten.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"},"hasMore":{"type":"boolean"}},"required":["limit","offset","total","hasMore"]}},"required":["data","pagination"]}}}}}}},"/api/v1/news/{slug}":{"get":{"operationId":"getNewsArticle","summary":"Eén nieuwsbericht ophalen","description":"Geeft de volledige samenvatting van één nieuwsbericht terug.","tags":["news"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Nieuwsbericht-slug, zoals teruggegeven door GET /api/v1/news.","schema":{"type":"string"}},{"name":"lang","in":"query","description":"Taal voor gelokaliseerde velden.","required":false,"schema":{"type":"string","enum":["nl","en","de","es"],"default":"nl"}}],"responses":{"200":{"description":"Het opgevraagde nieuwsbericht.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]},{"type":"object","properties":{"image":{"type":"string","format":"uri","nullable":true},"updatedAt":{"type":"string","nullable":true}}}]}},"required":["data"]}}}},"404":{"description":"Geen nieuwsbericht gevonden met deze slug.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-leesbare foutcode, bv. \"not_found\"."},"message":{"type":"string","description":"Mensleesbare uitleg van de fout."},"hint":{"type":"string","description":"Suggestie om de fout op te lossen."}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/likes/{id}":{"get":{"operationId":"getRecipeLikes","summary":"Aantal likes van een recept","description":"Geeft het huidige aantal likes voor een recept terug.","tags":["engagement"],"parameters":[{"name":"id","in":"path","required":true,"description":"Recept-slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"Like-telling voor dit recept.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"likes":{"type":"integer"}},"required":["id","likes"]}}}}}}},"/api/ratings/{id}":{"get":{"operationId":"getRecipeRatings","summary":"Gemiddelde beoordeling van een recept","description":"Geeft de gemiddelde beoordeling (1-5 sterren) en het aantal stemmen voor een recept terug.","tags":["engagement"],"parameters":[{"name":"id","in":"path","required":true,"description":"Recept-slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"Beoordelingsstatistieken voor dit recept.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"averageRating":{"type":"number"},"ratingCount":{"type":"integer"}},"required":["id","averageRating","ratingCount"]}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-leesbare foutcode, bv. \"not_found\"."},"message":{"type":"string","description":"Mensleesbare uitleg van de fout."},"hint":{"type":"string","description":"Suggestie om de fout op te lossen."}},"required":["code","message"]}},"required":["error"]},"Pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"},"hasMore":{"type":"boolean"}},"required":["limit","offset","total","hasMore"]},"RecipeSummary":{"type":"object","properties":{"slug":{"type":"string","description":"Unieke identifier van het recept, gebruikt in de URL."},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"cookingMethod":{"type":"string","nullable":true,"description":"Bv. \"Direct\", \"Indirect\", \"Low & Slow\"."},"servings":{"type":"integer","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]},"RecipeDetail":{"allOf":[{"type":"object","properties":{"slug":{"type":"string","description":"Unieke identifier van het recept, gebruikt in de URL."},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"cookingMethod":{"type":"string","nullable":true,"description":"Bv. \"Direct\", \"Indirect\", \"Low & Slow\"."},"servings":{"type":"integer","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]},{"type":"object","properties":{"image":{"type":"string","format":"uri","nullable":true},"bbqTemperature":{"type":"string","nullable":true},"bbqTime":{"type":"string","nullable":true},"prepTimeMinutes":{"type":"integer","nullable":true},"totalTime":{"type":"string","nullable":true},"nutrition":{"type":"object","nullable":true,"additionalProperties":true},"availableLanguages":{"type":"array","items":{"type":"string"}}}}]},"ReviewSummary":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"brand":{"type":"string","nullable":true},"product":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"score":{"type":"number","nullable":true,"description":"Score op 10."},"summary":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["id","title","url"]},"ReviewDetail":{"allOf":[{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"brand":{"type":"string","nullable":true},"product":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"score":{"type":"number","nullable":true,"description":"Score op 10."},"summary":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["id","title","url"]},{"type":"object","properties":{"image":{"type":"string","format":"uri","nullable":true},"pros":{"type":"array","items":{"type":"string"}},"cons":{"type":"array","items":{"type":"string"}},"verdict":{"type":"string","nullable":true},"publishedAt":{"type":"string","format":"date","nullable":true},"updatedAt":{"type":"string","format":"date","nullable":true}}}]},"NewsSummary":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]},"NewsDetail":{"allOf":[{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"}},"required":["slug","title","url"]},{"type":"object","properties":{"image":{"type":"string","format":"uri","nullable":true},"updatedAt":{"type":"string","nullable":true}}}]}}}}