New Release: Ingredients Endpoints


#1

We’ve just made live a couple of new API endpoints that have been requested by you guys, we’d love you to give them a try and test them out.

  • USDA Ingredients - Search by Name
  • USDA Ingredients - Get by ID
  • Simple Ingredients - Search by Name
  • Simple Ingredients - Get by ID

Check the Docs

All of these endpoints support both the User Scope (Oauth Bearer Token) and Application Scope (Valid App ID & Client Secret) auth methods.

Here’s an example using curl:

# Bearer token auth method
curl "https://api.nuapi.co/v3/simple_ingredients.json?name=chocolate" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer 17c17cThis17cIs17cWhere17cYour17cToken17cGoes17c17c" \

# Application ID & Secret auth method
curl "https://api.nuapi.co/v3/simple_ingredients.json?name=chocolate" \
  -H "Content-Type: application/json" \
  -H "Authorization: application_id 7050fa3cc27a056697263ec0221492a1a044ab, client_secret 1fdd7d268039eb5c0c622b3a382c80" \

Just replace your appID or client secret and paste into your terminal to try the request.

What can I do with these endpoints?

The ingredients endpoints are really useful for anything to do with Nutrition.

You could use them in a Recipe app to ensure your recipes have nutrition information.

You could use them to help Users with their Nutrition tracking.

You could use them to predict the presence of allergens in certain foods.

You could use them for adding nutrition information to restaurant menus.

What else can you do? We’d love to know what you come up with.

What are Simple Ingredients?

Simple Ingredients are a curated set of ingredients that Nuwe team created along with qualified nutritionists, in order to simplify the ingredients selection process for users. Read about it further in our Docs
See it in action in the Nuwe iOS App


#2

@lucassimmons wrote (via email):

Bananas in USDA… if I search bananas on the site


So why are the USDA results from Nuwe coming back as mostly baby food?

A couple of thoughts:

  1. I’ll check the response to make sure you’re getting all the results.

  2. The USDA returns 54 results for the keyword search “Banana”. If you scroll through them, 28 of those results are ingredients in the USDA “Baby Foods” category.

As you can see, if you select the ‘Limit to Food Group’ option on the USDA, you will only get 4 results, and reality is, you’re probably just after “Bananas, Raw”.

Nuwe Ingredients search doesn’t currently support pre-filter by USDA category - let’s talk about that if you think it would be useful.

But now you can see why we went down the road of creating Simple Ingredients - there’s a lot of hassle and decisions to handle when dealing with USDA raw database.

And I keep looking and I probably should not have sent that last email before I dug a little deeper. The user can have an option to say how big of a portion they ate…

Small (60)
Medium (120)
Large (200)

First up, yes you spotted the inclusion of “Default Quantities”. You can see how, the need to specify an amount to multiply the 1g representation of the ingredient by. This burden is typically on the user, and you would need a form field in your UI for them to input an amount. That generally sucks, unless you are reading off a recipe from a book or website where the amounts are explicit. Otherwise, it’s a guess and the increase in cognitive load on the user means this is a point where they get bored and jump out of your product.

Default Quantities alleviate some of that.

For each Simple Ingredient, we designated a Small, Medium and Large portion size that we felt was appropriate. You can see in the Simple Ingredients explanation post how that’s configured, I really encourage you to read that.

This value is just provided in the json response for the ingredient, in our case, we attached this value to a button in the UI of the Ingredients Select screen.

The user action with this, which could be to add the ingredient to create a Meal (along with a number of other ingredients each with amounts) or to say they have Eaten a certain amount of this ingredient.

In which case, with your POST to:

# Application ID & Secret auth method
curl "https://api.nuapi.co/v3/meals.json" \
  -H "Content-Type: application/json" \
  -H "Authorization: application_id 7050fa3cc27a056697263ec0221492a1a044ab, client_secret 1fdd7d268039eb5c0c622b3a382c80" \
  -X POST \
  -d "{\"meal\":{\"name\":\"Apple pie\",\"type\":\"breakfast\",\"favourite\":\"true\",\"components\":[{\"ingredient_id\":3,\"amount\":70},{\"ingredient_id\":1,\"amount\":200}],\"lat\":\"50.8571601\",\"lon\":\"-2.1645891\",\"images\":[\"BASE64STRING\"],\"places\":[{\"name\":\"The Place\",\"address\":\"Somewhere in the United Kingdom\",\"lat\":\"50.8571601\",\"lon\":\"-2.1645891\"}]}}"

You can see that you need to specify an amount. That amount could come from the user selecting a default quantity provided by Nuwe API if you choose to support that, you could define your own locally, or by inputting an explicit amount (or probably a number of other methods that you could get this data - e.g. you could in theory create a basic amount prediction engine based on population / user past activity.

So if I was looking for the amount of kcals for a medium portion it would be .89 * 120

106.8

Since I’m going ahead with the standard of misrepresenting kcals as Calories, I’m assuming this is my Calorie count? Is THAT right? Please tell me that is right :slight_smile:

After you have solved the amount, then this bit is easy. Your arithmetic is correct and yes, that is your Calorie (big C) / kcal count.


#3

I think though that the Nuwe search for “Banana” is not showing all of these results:

{  
   "usda_ingredients":[  
      {  
         "id":554,
         "name":"BABYFOOD,FRUIT,BANANAS W/TAPIOCA,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":570,
         "name":"BABYFOOD,FRUIT,APPLSAUC W/BANANA,JR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":576,
         "name":"BABYFOOD,FRUIT,BANANAS\u0026PNAPPL W/TAPIOCA,JR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":577,
         "name":"BABYFOOD,FRUIT,BANANAS\u0026PNAPPL W/TAPIOCA,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":583,
         "name":"BABYFOOD,FRUIT,BANANAS W/APPLS\u0026PEARS,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":587,
         "name":"BABYFOOD,APPLE-BANANA JUC",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":594,
         "name":"BABYFOOD,JUC,ORANGE\u0026APPL\u0026BANANA",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":596,
         "name":"BABYFOOD,JUC,ORANGE\u0026BANANA",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":603,
         "name":"BABYFOOD,CRL,MXD,W/BANANAS,DRY",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":604,
         "name":"BABYFOOD,CRL,MXD,W/APPLSAUC\u0026BANANAS,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":605,
         "name":"BABYFOOD,CRL,MXD,W/ APPLSAUC \u0026 BANANAS,JR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":607,
         "name":"BABYFOOD,CRL,OATMEAL,W/BANANAS,DRY",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":608,
         "name":"BABYFOOD,CRL,OATMEAL,W/APPLSAUC\u0026BANANAS,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":609,
         "name":"BABYFOOD,CRL,OATMEAL,W/APPLSAUC\u0026BANANAS,JR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":612,
         "name":"BABYFOOD,CRL,RICE,W/APPLSAUC\u0026BANANAS,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":622,
         "name":"BABYFOOD,CRL,RICE,W/BANANAS,DRY",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":651,
         "name":"BABYFOOD,FRUIT,BANANAS W/TAPIOCA,JR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":658,
         "name":"BABYFOOD,PLUMS,BANANAS\u0026RICE,STR",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":669,
         "name":"BABYFOOD,CRL,MXD,W/BANANAS,PREP W/WHL MILK",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":671,
         "name":"BABYFOOD,CRL,OATMEAL,W/BANANAS,PREP W/WHL MILK",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":677,
         "name":"BABYFOOD,CRL,RICE,W/BANANAS,PREP W/WHL MILK",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":2052,
         "name":"CEREALS,CRM OF WHEAT,MIX'N EAT,APPL,BANANA\u0026MAPLE FLAV,DRY",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":2053,
         "name":"CEREALS,CRM OF WHEAT,MIX'N EAT,APPL,BANANA\u0026MAPLE FLAV,PREP",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":2195,
         "name":"CEREALS,QUAKER,INST OATMEAL,BANANA BREAD,DRY",
         "summary":{  },
         "detailed":{  }
      },
      {  
         "id":2280,
         "name":"CEREALS RTE,GENERAL MILLS,CHEERIOS,BANANA NUT",
         "summary":{  },
         "detailed":{  }
      }
   ]
}

I think that the results must be paginated to 25, I will check that.


#4

@lucassimmons

Yep. Paginated of course.

Like many of our endpoints that return potentially 10’s, 1000’s or 1000’s of results, we often use pagination. You need to check the Headers for the page urls.


#5

@Retrosteve My question is more why the results are not the same. So why does baby food show up first from Nuwe but the USDA website shows non baby food items first?


#6

For the simple ingredients endpoint it seems like it would make more sense to put portions in its own object that we can iterate through. Is it always going to be small, medium and large or some day might there be an extra large ingredient option?


#7

Our search algorithm is not the same one as the USDA, so I wouldn’t expect to get the same ordering response exactly. But feedback on usability and improvements are very welcome…


#8

Yep that would make sense, I’ll raise it with the team.


#9

@Retrosteve Well yes, ok… In the current format the USDA data isn’t very pretty which is probably why (once again) you created Simple Ingredients. The food names are all in caps and really long sometimes


#10

@lucas_simmons via email:

This afternoon I walked to a restaurant called donuts and burgers (healthy I know :)) but hey I walked!

I ate
A donut
Cheeseburger
Fries
Part of my daughter's quesadilla
So if I wanted to enter that information into the GFD app but Simple Ingredients doesn't return a burger, probably because it is not "simple" enough
So I type in cheeseburger and the results are

Which is awesome aside from the formatting of everything which I imagine I can figure out how to cleanup... 

So the way we tackled this sort of thing in Simple Ingredients is by encouraging people to consider what they’re ACTUALLY eating. So for example.

Cheeseburger might contain:

Beef - Medium
Cheese - Small
Lettuce - Small
White Bread - Large
Tomato - Small
Gherkin - Small
Vegetable Oil - Small
Salt - Small

Which you’d select from the simple ingredients. In this case, where you have a compound product with multiple ingredients, you wouldn’t want to do this too many times (like once, max) - so then you could also pass those ingredients along to the POST request and save it as a meal for next time - and heck if you liked the old Maccie D’s, you may even pass along favorite:true. This was the whole user generated content flow.

Also for USDA ingredients are there no portions included in the results?

No, this is just raw USDA format - no (not much) tampering on our behalf. Would it be useful to have? Would love to hear your thoughts on the whole Simple Ingredients post I wrote

If I search mcdonald's cheeseburger though nothing comes up.  If I search just mcdonald's though I get a list of cheeseburgers... 

Kind of odd. Probably search needs a tweak, but roll with it for now and compile a list of things that don’t work as well as you’d like, then we can tackle them as a batch rather than individual adjustments. I would especially feel bad about optimising search for Mcdonald’s!!!


#11

Well if I’m eating a cheeseburger it would be cumbersome for me to put in all the ingredients into my phone. I don’t think the USDA results are useful without a portion… If I ate a burger I’d just want to say I ate 1 sandwich… or if I had fries, I had small, medium or large… In the USDA search portions like these are returned… not sure if they are returned on the API side?


#12

Ah, my bad - we must have missed that table when we sync’d. I’ll raise a ticket to capture the USDA provided default quantities.


#13

@lucas_simmons

This is now live, however, it’s only a partial fix.

The USDA Database contains portion data that varies in number of portions, units, etc. Doing a full import of this is going to take a while…

In the meantime, we had already a couple of relevant tables exported which typically provides 2 out of however many given portions there are per ingredient in the USDA.

So we’ve added these tables to the JSON response in ingredients to get you started, and we’ll extend this part when we have a bit more time.

see the Docs

"medium_portion":113,
"large_portion":226

#14

Great! FYI, it seems like a lot of the medium portions are returning 0 btw


#15

Also after looking at the USDA data vs the returned Nuwe data I am not sure if there is something wrong or if I am misunderstanding how it is formatted

When I look at a McDonald’s cheeseburger on USDA

http://ndb.nal.usda.gov/ndb/foods/show/6738?fg=&manu=&lfacet=&format=&count=&max=35&offset=&sort=&qlookup=cheeseburger

The large portion shows the kcal as 3 from the USDA front end, but as .0263 from the nuwe endpoint


#16

@Retrosteve thoughts on this?


#17

@lucas_simmons I probably need to write up a bit more documentation on which columns of the DB we have included for now. Sorry if it’s a bit confusing.


#18

My concern is the data… Is this right? For a mcdonald’s cheeseburger:

The large portion shows the kcal as 3 from the USDA front end, but as .0263 from the nuwe endpoint


#19

Hi Lucas
I think the easiest thing here is that we need to do a bit of work our side on this to sync better with the USDA Database than we have currently.
I’ve discussed it with the team today and we have this planned in for completion by the end of the month.

You can track it here https://trello.com/c/vKnvIHZ3/48-usda-ingredients-data-add-usda-portions-table and if you have any suggestions or questions, can direct them to Stephanie who is the developer on this.


#20

Hey @Retrosteve - Just checking in to see how things are progressing.