Find recipes on BBC Good Food.
Searches BBC Good Food's recipes like its search page: title, star rating and number of ratings, total time (as shown and in minutes), skill level, vegetarian/vegan flags, image and link, 30 per page. Sort by relevance, newest, most popular or quickest. Premium recipes (Good Food app subscribers only, links under /premium/) are kept and marked premium. The search is fuzzy: a query with no real match can still return a few loosely related recipes.
- Site
- BBC Good Food, United Kingdom
- Version
- v2 of 2
- Runs, last 7 days
- No reports yet
- sha256
- c28af5abcb48…
Run it with your agent
after installing WieldAsk in plain words. Your agent finds this recipe and calls it:
“Find recipes on BBC Good Food.”
Read-only: it changes nothing on the site. No login needed.
{ "tool": "run", "arguments": { "recipe_id": "bbcgoodfood.com/search-recipes", "params": { "query": "lasagne", "sort": "popular" } } }
Requests
sent from your browser, in order- 1GET/api/search-frontend/search?page&search&sortBBC Good Food's search API (/api/search-frontend/search, the nextUrl of its search page; the page itself renders the same JSON as __POST_CONTENT__).
Parameters
from your agentReturns
to your agentWhere it can send
- www.bbcgoodfood.com
Anything else is blocked by the extension.
Reads from your session
Nothing. Your browser attaches the site's cookies by itself.
Used only in requests to the addresses on the left. Never sent to wield.run or your agent.
Checks
a run passes when- length(output.recipes) == `30`
- output.total > `30`
- length(output.recipes[?starts_with(url, 'https://www.bbcgoodfood.com/recipes/') || (premium && starts_with(url, 'https://www.bbcgoodfood.com/premium/'))]) == length(output.recipes)
- length(output.recipes[?rating != `null` && rating >= `0` && rating <= `5`]) > `20`
- length(output.recipes[?total_minutes != `null`]) > `20`
Raw recipe
Served as canonical JSON from /api/v1/recipes/bbcgoodfood.com/search-recipes, so its sha256 matches the ETag and the index.
curl -s https://wield.run/api/v1/recipes/bbcgoodfood.com/search-recipes | shasum -a 256 # c28af5abcb484fa36f23ac7bdb8f9af9180e322a18222d07e85b71ceacfbb1c4
{ "description": "Searches BBC Good Food's recipes like its search page: title, star rating and number of ratings, total time (as shown and in minutes), skill level, vegetarian/vegan flags, image and link, 30 per page. Sort by relevance, newest, most popular or quickest. Premium recipes (Good Food app subscribers only, links under /premium/) are kept and marked premium. The search is fuzzy: a query with no real match can still return a few loosely related recipes.", "effect": "read", "id": "bbcgoodfood.com/search-recipes", "keywords": [ "bbc good food", "good food", "recipe", "recipes", "dinner", "baking", "cooking", "vegetarian", "easy recipes", "rezept", "recette", "uk" ], "output": { "schema": { "properties": { "page": { "type": "integer" }, "query": { "type": "string" }, "recipes": { "items": { "properties": { "image": { "type": [ "string", "null" ] }, "premium": { "description": "Only for Good Food app subscribers", "type": "boolean" }, "rating": { "description": "0–5 stars", "type": [ "number", "null" ] }, "ratings": { "type": "integer" }, "skill": { "description": "Easy, More effort, A challenge", "type": [ "string", "null" ] }, "title": { "type": "string" }, "total_minutes": { "type": [ "integer", "null" ] }, "total_time": { "description": "As shown, e.g. '1 hr 35 mins'", "type": [ "string", "null" ] }, "url": { "type": "string" }, "vegan": { "type": "boolean" }, "vegetarian": { "type": "boolean" } }, "type": "object" }, "type": "array" }, "total": { "type": [ "integer", "null" ] } }, "required": [ "query", "recipes" ], "type": "object" }, "value": "{query: params.query, total: steps.search[0].total || `0`, page: params.page || `1`, recipes: map(&(let $time = time || '' in {title: title, rating: rating || `null`, ratings: ratings || `0`, total_time: time || `null`, total_minutes: let $w = split($time, ' ') in (length($w) == `2` && starts_with($w[1], 'min') && to_number($w[0])) || (length($w) == `2` && starts_with($w[1], 'hr') && to_number($w[0]) * `60`) || (length($w) == `4` && starts_with($w[1], 'hr') && starts_with($w[3], 'min') && to_number($w[0]) * `60` + to_number($w[2])) || `null`, skill: skill || `null`, vegetarian: vegetarian, vegan: vegan, premium: premium == `true`, image: image || `null`, url: url}), steps.search[0].items || `[]`)}" }, "params": { "additionalProperties": false, "properties": { "page": { "default": 1, "maximum": 10, "minimum": 1, "type": "integer" }, "query": { "description": "Dish or ingredients, e.g. 'lasagne', 'chicken curry', 'banana bread'", "maxLength": 100, "minLength": 2, "type": "string" }, "sort": { "default": "relevance", "enum": [ "relevance", "newest", "popular", "quickest" ], "type": "string" } }, "required": [ "query" ], "type": "object" }, "provenance": { "method": "browser-inspect", "notes": "The search page /search?q=… renders its results from script#__POST_CONTENT__ (searchResults.items, totalItems, nextUrl). nextUrl is /api/search-frontend/search?search=…&page=…&sort=… (relevant, published, rating, quickest: the page's own sort menu), which answers the same JSON. Each item: title, rating.{ratingValue, ratingCount}, terms [{slug time|skillLevel|vegetarian|vegan, display}], isPremium, image.url, url. Premium recipes link to /premium/<slug>. A nonsense query still answers a few fuzzy matches (11 for 'qzxwvkjhgfdpl'), with no flag to tell them apart. total_minutes parses '30 mins', '2 hrs' and '1 hr 35 mins'; other formats stay null. Images are links to images.immediate.co.uk (never called). v2 (2026-11-07 22:38): tos.notes only; requests and output unchanged.", "recorded_at": "2026-11-07T22:15:00+01:00", "recorded_by": "C4" }, "requires_login": false, "schema": "https://wield.run/schema/recipe/v1.json", "site": { "country": "GB", "id": "bbcgoodfood.com", "language": "en", "name": "BBC Good Food", "origin": "https://www.bbcgoodfood.com", "origins": [ "https://www.bbcgoodfood.com" ] }, "steps": [ { "description": "BBC Good Food's search API (/api/search-frontend/search, the nextUrl of its search page; the page itself renders the same JSON as __POST_CONTENT__).", "expect": { "assert": "body.searchResults != `null`", "content_type": "json", "status": [ 200 ] }, "extract": { "json": { "items": "searchResults.items[?postType == 'recipe'].{title: title, rating: rating.ratingValue, ratings: rating.ratingCount, time: terms[?slug == 'time'] | [0].display, skill: terms[?slug == 'skillLevel'] | [0].display, vegetarian: length(terms[?slug == 'vegetarian']) > `0`, vegan: length(terms[?slug == 'vegan']) > `0`, premium: isPremium, image: image.url, url: url}", "total": "searchResults.totalItems" } }, "foreach": { "as": "f", "in": "let $s = params.sort || 'relevance' in [{sort: (`[[\"relevance\",\"relevant\"],[\"newest\",\"published\"],[\"popular\",\"rating\"],[\"quickest\",\"quickest\"]]`[?@[0] == $s] | [0][1]) || 'relevant'}]", "max": 1 }, "id": "search", "request": { "headers": { "Accept": "application/json" }, "method": "GET", "query": { "page": "{{params.page | default:1}}", "search": "{{params.query}}", "sort": "{{f.sort}}" }, "url": "/api/search-frontend/search" } } ], "task": "Find recipes on BBC Good Food", "tos": { "notes": "BBC Good Food sets Content-Signal ai-train=no (search=yes). robots.txt disallows /search* for bots (the recipe calls /api/search-frontend/search, which it does not cover) and signals search=yes, ai-train=no; this is a user's own search, nothing is used for training. One request per call; no recipe pages are fetched.", "reviewed": false }, "verify": { "checks": [ "length(output.recipes) == `30`", "output.total > `30`", "length(output.recipes[?starts_with(url, 'https://www.bbcgoodfood.com/recipes/') || (premium && starts_with(url, 'https://www.bbcgoodfood.com/premium/'))]) == length(output.recipes)", "length(output.recipes[?rating != `null` && rating >= `0` && rating <= `5`]) > `20`", "length(output.recipes[?total_minutes != `null`]) > `20`" ], "example_params": { "query": "lasagne", "sort": "popular" }, "max_ms": 3000 }, "version": 2 }