The Punchfork API lets you easily integrate recipes into your website or app by providing direct access to recipe data from all publishers in our database.
Some things you could do with the Punchfork API:
The Punchfork API uses an API key to identify your application. By default, all users may obtain a free API key.
Sign in now to get your free API key
Note: Certain API endpoints require a paid API plan. See our pricing table for the full breakdown.
Open source libraries for interacting with the Punchfork API are available on our GitHub page:
A Punchfork API request is an HTTP URL of the following form:
http://api.punchfork.com/{endpoint}?key={your-api-key}&{parameters}
https requests for added security of your API key.Endpoint:
http://api.punchfork.com/recipes?key={api-key}&{optional-params}
Parameters:
q (optional) — Recipe search query. Same as what you'd type into the search box on punchfork.com (see search tips). May also be a URL to look up the recipe with that URL (either a publisher URL or a punchfork.com URL). If no query is provided, the first N top-rated recipes are returned.ingred (optional) (paid) — When set to either "true" or "1", recipe responses will include ingredients data. count (optional) — Max number of recipes to be returned. Defaults to 10, maximum is 50. If you want more than 50 recipes, use cursor pagination.cursor (optional) — Start the query at the specified cursor value. This is used for pagination.sort (optional) — Sort recipes by "r"ating (default), "d"ate published, or "t"rendingness.from (optional) — Only get recipes from a specific publisher. If set, this parameter should contain the full publisher name, e.g. "The Pioneer Woman" (see our full list of publishers). If this parameter is not provided, the API will return recipes from all publishers.likes (optional) — Only get recipes from a specific user's likes. If set, this parameter should contain the user's Punchfork username.startdate (optional) — Only get recipes published on or after this date. Must be a UTC datetime in ISO format.enddate (optional) — Only get recipes published on or before this date. Must be a UTC datetime in ISO format.total (optional) — When set to either "true" or "1", the response will include a "total" value which indicates the total number of recipes in the database matching the query. Must be used along with the q parameter.Response:
The response is a JSON dictionary containing the following values:
count — Number of recipes in the result. If the query yields no results, the count will be 0.next_cursor — Value that can be passed back to the endpoint as cursor to yield the next page of recipes for the same query. If the query yields no results, next_cursor will be an empty string.recipes — Array of recipes. The array is sorted in decreasing order by the key specified in the sort parameter (defaults to recipe rating). Each recipe is a dictionary containing the following values: title, source_url, pf_url, source_name, source_img, thumb, rating, twc, fbc, suc, published (UTC datetime in ISO format), shortcode, and optionally source_ingred, cat_ingred and canon_ingred. If the query yields no results, recipes will be an array of length 0.total (optional) — If the total parameter is set, this value indicates the total number of recipes in the database matching the query.Example:
$ curl 'http://api.punchfork.com/recipes?key={key}&q=chicken+parmesan&count=2'
{
"count": 2,
"recipes": [
{
"rating": 99.562,
"source_name": "Skinny Taste",
"thumb": "http://img.punchfork.net/9414bb60098bd0b58115d2ad506a20bf_250x250.jpg",
"title": "Healthy Baked Chicken Nuggets",
"source_url": "http://www.skinnytaste.com/2011/04/healthy-baked-chicken-nuggets.html",
"pf_url": "http://punchfork.com/recipe/Healthy-Baked-Chicken-Nuggets-Skinny-Taste",
"published": "2011-04-12T13:00:00",
"source_img": "http://2.bp.blogspot.com/-jJOVHp44U2E/TaRqUWBT_ZI/AAAAAAAAC-4/VQoL7rrCaKM/s1600/healthy-baked-chicken-nuggets.jpg",
"shortcode": "upk7zQ",
"twc": 120,
"fbc": 3835,
"suc": 614961
},
{
"rating": 80.8558,
"source_name": "The Pioneer Woman",
"thumb": "http://img.punchfork.net/f2f020ef8f2dfc87d824547275ec7077_250x250.jpg",
"title": "Chicken Cacciatore",
"source_url": "http://thepioneerwoman.com/cooking/2010/10/chicken-cacciatore/",
"pf_url": "http://punchfork.com/recipe/Chicken-Cacciatore-The-Pioneer-Woman",
"published": "2010-07-21T14:00:00",
"source_img": "http://static.thepioneerwoman.com/cooking/files/2010/10/5091364415_b1058dec47_o.jpg",
"shortcode": "rro9yX",
"twc": 80,
"fbc": 2533,
"suc": 1552
}
],
"next_cursor": "80.8557733148"
}
Real-time results:
Real-time data is a paid API feature.
The free API only returns recipes at least 1 month old.
The paid API make recipes available immediately after they enter our database, often just minutes after they're published on the web.
Ingredients data:
Ingredients data is a paid API feature.
source_ingred lists the raw ingredient text from the source recipe.cat_ingred lists the categorized ingredients that Punchfork builds from source_ingred. This is a dictionary whose keys are category names (e.g. "Canned Goods") and whose values are the matching lists of ingredients. Each categorized ingredient has an easy to read format.canon_ingred lists the canonical ingredient terms that Punchfork builds from source_ingred. These are parsed ingredient names, singularized (e.g. "burgers" is changed to "burger"), canonicalized (e.g. "scallion" is changed to "green onion") and lowercased. Amounts ("2 tbsp") and modifiers ("diced") are discarded. Depending on what you want to do with the ingredients list, it can be easier to use canon_ingred rather than source_ingred.Example with ingredients data:
$ curl 'http://api.punchfork.com/recipes?key={key}&q=salmon+with+couscous&count=1&ingred=true'
{
"count": 1,
"recipes": [
{
"rating": 53.8188,
"source_name": "The Kitchn",
"thumb": "http://img.punchfork.net/f9c6047f7958927a0cff232e0da16853_250x250.jpg",
"title": "Quick Salmon & Couscous with Cilantro Vinaigrette",
"source_url": "http://www.thekitchn.com/thekitchn/main-dish/recipe-sauteed-salmon-with-cilantro-vinaigrette-over-couscous-142129",
"pf_url": "http://punchfork.com/recipe/Quick-Salmon-Couscous-with-Cilantro-Vinaigrette-The-Kitchn",
"published": "2011-02-19T08:00:00",
"source_img": "http://www.apartmenttherapy.com/uimages/kitchen/2011_03_22-Salmon.jpg",
"shortcode": "mB2Pwv",
"source_ingred": [
"1 10-ounce box plain couscous (1 1/2 cups)",
"1 10-ounce salmon fillet,skin removed and cut in 2 pieces",
"1/2 teaspoon sumac",
"Salt and pepper",
"3 tablespoons olive oil",
"1/4 cup cilantro,chopped",
"2 scallions, thinly sliced",
"2 tablespoons lemon juice"
],
"cat_ingred": {
"Cooking & Baking": [
"Olive oil (3 tablespoons)",
"Salt and pepper (1)",
"Sumac (1/2 teaspoon)"
],
"Drinks": [
"Lemon juice (2 tablespoons)"
],
"Pasta & Grains": [
"1 10-ounce box plain couscous, plain (1 1/2 cups)"
],
"Produce": [
"Cilantro (1/4 cup)",
"Scallions (2)"
],
"Seafood": [
"10-ounce salmon, fillet (1)"
]
},
"canon_ingred": [
"coriander",
"couscous",
"green onion",
"lemon juice",
"olive oil",
"salmon",
"salt and pepper",
"sumac"
]
}
],
"next_cursor": "53.8187618818"
}
Endpoint:
http://api.punchfork.com/random_recipe?key={api-key}
Parameters:
Response:
The response is a JSON dictionary containing the following values:
recipe — A single recipe selected at random from the Punchfork database. The format is the same as in the /recipes endpoint.Example:
$ curl 'http://api.punchfork.com/random_recipe?key={key}'
{
"recipe": {
"rating": 70.0612,
"source_name": "Simply Recipes",
"thumb": "http://img.punchfork.net/7cf6724743c607df27b9eebb9bf3134c_250x250.jpg",
"title": "Beer Can Chicken",
"source_url": "http://simplyrecipes.com/recipes/beer_can_chicken/",
"pf_url": "http://punchfork.com/recipe/Beer-Can-Chicken-Simply-Recipes",
"published": "2009-10-19T14:00:00",
"source_img": "http://simplyrecipes.com/photos/beer-can-chicken-a.jpg",
"shortcode": "x42PHv"
}
Endpoint:
http://api.punchfork.com/publishers?key={api-key}
Parameters:
Response:
The response is a JSON dictionary containing the following values:
publishers — Array of publisher records. This lists all recipe publishers on Punchfork.Example:
$ curl 'http://api.punchfork.com/publishers?key={key}'
{
"publishers": [
{
"name": "Allrecipes",
"twitter": "Allrecipes",
"site": "allrecipes.com",
"num_recipes": 6763,
"avatar": "http://si0.twimg.com/profile_images/1110173569/AR_Logo_Aug_2010_reasonably_small.png",
"avg_rating": 28.4673
},
...
]
}
This is a Premium API feature.
Endpoint:
http://api.punchfork.com/diet_index?key={api-key}&ingred={ingredients}
Parameters:
ingred — Recipe ingredients, as a newline-separated list. Each ingredient can be just a name, like "red onion", or free form text that includes units and modifiers, like "1 cup finely chopped red onion".Response:
The response is a JSON dictionary containing the following values:
diets — An array of diet terms describing which diets are safe for the input recipe ingredients. The possible diet terms are "vegetarian", "vegan", "gluten free" and "paleo". Diet classification applies to the recipe as a whole, e.g. the recipe is considered vegetarian only if all input ingredients are vegetarian-safe.alerts — An array of alert messages from the diet classification of the input ingredients. These are general alerts about unknown ingredients, or warnings about ingredients that are considered conditonally safe for a particular diet. For example, chocolate is considered vegan, but only if it's a particular brand of vegan-safe chocolate; therefore, inputs containing chocolate as an ingredient will receive an alert response saying Possibly vegan: "chocolate". (Note: if no alerts are generated, the alerts field will not be included in the response.)Example:
Input ingred parameter:
2 cups yellow cornmeal 2 teaspoons baking powder 3/4 to 1 teaspoon fine sea salt 1 large egg, lightly beaten 1 cup water, plus more if needed 1/4 to 1/3 cup mild-flavored vegetable oil for frying
Result:
$ curl 'http://api.punchfork.com/diet_index?key={key}&ingred={ingredients}'
{
"diets": [
"gluten free",
"vegetarian"
]
}
This is an Ultra API feature.
Endpoint:
http://api.punchfork.com/search_index?key={api-key}&title={title}&ingred={ingredients}
Parameters:
title — Recipe title.ingred — Recipe ingredients, as a newline-separated list. Each ingredient can be just a name, like "red onion", or free form text that includes units and modifiers, like "1 cup finely chopped red onion".Response:
The response is a JSON dictionary containing the following values:
terms — Search index terms for the input recipe. The index includes: (a) the ingredients in the recipe (e.g. "tilapia"), (b) the parent ingredients of each ingredient in the recipe (e.g. "fish"), and (c) the words in the recipe title (e.g. "Best", "Tilapia", "Ever"). Ingredient terms are singularized, canonicalized, and lowercased. Title words ignore punctuation.Example:
Input title parameter:
Chicken Parmigiana
Input ingred parameter:
1 egg, beaten 2 ounces dry bread crumbs 2 skinless, boneless chicken breast halves 3/4 (16 ounce) jar spaghetti sauce 2 ounces shredded mozzarella cheese 1/4 cup grated Parmesan cheese
Result:
$ curl 'http://api.punchfork.com/search_index?key={key}&title={title}&ingred={ingredients}'
{
"terms": [
"bird",
"bread crumb",
"cheese",
"chicken breast",
"chicken",
"condiment",
"dairy",
"egg",
"meat",
"mozzarella",
"parmesan",
"parmigiana",
"poultry",
"sauce",
"spaghetti sauce"
]
}
Endpoint:
http://api.punchfork.com/rate_limit_status?key={api-key}
Parameters:
Response:
The response is a JSON dictionary containing the following values:
remaining_calls — The number of remaining API calls allowed today for the given API key. Rate limit counters are reset each day at midnight Pacific US time.Example:
$ curl 'http://api.punchfork.com/rate_limit_status?key={key}'
{
"remaining_calls": 423
}
If an API error occurs, the JSON response will be {'error': 'message'} with the relevant HTTP status code.
| Status code | Reason | Whose fault |
|---|---|---|
| HTTP 200 OK | Successful request. No errors. | No one |
| HTTP 400 Bad Request | The API request was malformed, i.e. a required parameter was missing or a parameter value was invalid. | Your fault |
| HTTP 403 Forbidden | API key is missing or invalid. | Your fault |
| HTTP 404 Not Found | The API endpoint does not exist. | Your fault |
| HTTP 500 Internal Server Error | There was a bug in our code and the API call broke. If you see this, please let us know. | Our fault |
| HTTP 503 Service Unavailable | The API server is down for temporary maintenance. When this occurs, try your call again in a few minutes. | Our fault |
The Punchfork API limits the number of queries a single key can execute per day. For the exact rate limit numbers, see the pricing table below.
If your application is being rate limited by the API, it will receive an HTTP 400 response code, along with a JSON error message {'error': 'Rate limit exceeded.'}.
To check the current rate limit status of your application, call the rate_limit_status endpoint.
Please set your User-Agent header to something identifiable for your application.
If your application displays recipes from the Punchfork API, please include a "Powered by Punchfork" logo alongside the results. We recommend that you place the logo at the top of the results, flush with the right margin of the list of recipes. The logo should be clickable, with a link back to punchfork.com.
Paid API users are exempt from the logo requirement.
The following .zip file contains the "Powered by" logo, which can be resized according to the needs of your app:
Download logos (531kb .zip file)
The free API is intended for personal or nonprofit use. We ask that you don't use the free API in a commercial or business application without our explicit permission. Paid API plans may be used in commercial apps without restriction. If you have any questions about this policy, feel free to contact us. Thanks.
| Plan | Free | Basic | Premium | Ultra |
|---|---|---|---|---|
| Price | Free | $99/month | $295/month | $995/month |
| Rate limit | 250 API calls/day | 1,000 API calls/day | 10,000 API calls/day | Unlimited calls |
| Basic recipe data | ||||
| Recipes with ingredients | ||||
| Real-time results | ||||
| Diet indexing | ||||
| Search indexing | ||||
| Logo-free usage | ||||
| Commercial use |
To get started with a free API key, sign in now.
To upgrade to a paid API plan, contact us.
Where do the recipes in the Punchfork API come from?
From popular food blogs and mainstream recipe sites around the web. See our full list of recipe publishing partners. We're constantly adding new sources to our database, and as we include more recipes, API users will automatically see the benefits in improved API results.
Why aren't preparation steps provided by the recipe API?
We consider recipe preparation text to be the author's proprietary work, so we don't scrape them from our publishers. Instead of displaying preparation steps, we require API partners to link back to source recipes in their apps.
Can recipe data from the API be cached offline or on my servers?
For paid API users, yes, recipe data may be cached offline as long as the API subscription is maintained. Once a subscription ends, all cached data must be deleted on the client side. Users of the free API may only cache data from up to 1,000 recipes at a time.
Do you support JSONP callbacks?
Yes. If you supply a jsonp parameter to any call, it will wrap the resulting JSON in that function.
When is the rate limit counter reset each day?
At midnight, Pacific US time.
Other questions?
Contact us anytime with your questions about the API.
Get updates by following us on Twitter Follow @Punchfork