Endpoints
Parse
Accepts a free-text food description and returns nutrition data already calculated for the described quantity. Designed for AI agents, voice input, and conversational food logging: anywhere the input is natural language rather than a clean food name.
/v1/parse10 credits / requestWhen to use this
Use /v1/parsewhen the caller has natural language input: a user's spoken description, an LLM-generated ingredient list, or a free-form log entry. For human-typed queries against a search box, use /v1/foods/search instead. It is cheaper and faster.
Request body
{
"text": "2 grilled chicken breasts with olive oil and a handful of almonds"
}Example response
{
"data": {
"matched": [
{
"input": "2 grilled chicken breasts",
"foodId": "3f2a1b9c-2e1a-4b8b-9e0a-6b7c8d9e0f1a",
"foodName": "Chicken breast, grilled",
"assumedServing": "340 g",
"confidence": 0.91,
"nutrition": { "calories": 561, "proteinG": 105.4, "carbsG": 0, "fatG": 12.2 },
"alternatives": []
},
{
"input": "a handful of almonds",
"foodId": "a9b8c7d6-1234-4b8b-9e0a-6b7c8d9e0f1a",
"foodName": "Almonds",
"assumedServing": "28 g",
"confidence": 0.74,
"nutrition": { "calories": 164, "proteinG": 6.0, "carbsG": 6.1, "fatG": 14.2 },
"alternatives": []
}
],
"unmatched": []
},
"meta": { "matchedCount": 2, "unmatchedCount": 0, "status": "full_match" }
}Matched and unmatched items
Every parsed fragment ends up in either data.matched or data.unmatched. A fragment lands in unmatched when the model can tell it is food-like but cannot resolve it to a specific Forkbit food. meta.status summarizes the whole request: full_match when everything matched, partial_match when only some fragments did, and no_match when none did. All three are HTTP 200. A parse with no matches is not an error.
Confidence scores
Every matched item includes a confidence value between 0.0 and 1.0 reflecting how certain the API is about the food match and the quantity interpretation. Surface low-confidence items (we recommend < 0.7) to your user for confirmation rather than accepting them silently.
Latency
Parse calls are backed by an LLM and typically take 1 to 3 seconds, noticeably slower than search. They are not intended for autocomplete or anything in a hot UI path.
Errors
| Status | Code | Cause |
|---|---|---|
| 422 | VALIDATION_ERROR | text was sent as the wrong type. |
| 422 | PARSE_EMPTY_INPUT | text is missing or blank. |
| 422 | PARSE_TEXT_TOO_LONG | text exceeds 1000 characters. |
| 503 | LLM_UNAVAILABLE | The underlying language model is temporarily unreachable. Retry after a short delay. |
A parse with no matches is not an error, see Matched and unmatched items above. See Error handling for the common error codes every endpoint can return.