FitVeteDeveloper API Get an API key

Build with FitVete.

A practical reference for the food and nutrition API: one base URL, standard JSON, copy-ready requests, and honest response contracts. Pick a language once and every example on this page updates with it.

Introduction

Base URL:

https://auth.fitvete.com/functions/v1/food-api
  • Most endpoints are GET; the image endpoints (photo & label) are POST with an image body. All return JSON.
  • Authentication is accepted only in the x-api-key request header. Keys in URLs are rejected so they cannot leak through browser history, logs, or referrers.
  • Responses include a source field: corpus or corpus-parser when FitVete answers from its own library, and a provider label when a miss is resolved and evaluated for corpus promotion.
  • Public image URLs are always served from auth.fitvete.com. External source links are not exposed in result payloads.

Quick start

Make your first call in under a minute:

1. Create a free account and copy your key (fv_live_…) from the dashboard.

2. Put it in your environment, then call any endpoint:

3. Check your remaining quota in the response headers (see Rate limits). That's it — no SDK required, though one is available (see OpenAPI & SDKs).

Authentication

Create a free account and copy your key from the dashboard. Keys look like fv_live_…. Send it on every request:

Keep your key secret — treat it like a password. You can create up to 5 keys and delete any of them at any time from the dashboard. Deleting a key takes effect immediately.

Rate limits & points

Points are reserved after authorization. Handler errors (including 400, 404, 422, 502 and storage failures) retain that cost, as do cached/repeated scans. Rejected authentication, burst/quota limits, and invalid image uploads cost zero. Usage resets at UTC midnight. When account usage is unavailable, headers use zero values and X-Plan: unknown. X-RateLimit-Cost is the cost actually reserved.

Most requests spend points — most cost 1, image (vision) endpoints cost 10 (see the table below). Your daily point budget depends on your plan, and there is also a per-minute burst ceiling to keep the API fast for everyone.

PlanPoints / dayBurst / minute
Free5060
Starter1,000120
Pro10,000300
Ultra100,000600

Every response carries your current usage in headers:

X-RateLimit-Limit: 50 X-RateLimit-Remaining: 44 X-RateLimit-Used: 6 X-RateLimit-Cost: 1 X-Plan: free

Most endpoints cost 1 point. Vision endpoints cost more because they call image providers:

EndpointPoints
/v1/search-foods, /v1/compute-nutrition, recipes, drinks, barcode, autocomplete, alternatives1
/v1/analyze-ingredients2
/v1/score3
/v1/parse5
/v1/nutrition-from-photo10
/v1/nutrition-label10
Scan retrieval, correction, and deletion0

Data & concepts

A few fields appear across responses and are worth understanding:

FieldWhat it means
sourceWhere the answer came from: corpus (our curated, owned dataset — instant and free of upstream cost), or reference-provider / usda / apileague / openfoodfacts / vision for an external lookup. scan-memory and user-correction identify private reuse; vision+corpus still involves an outside vision model.
confidenceReference-food results use a 0–100 confidence score. Photo estimates use high, medium, or low. These are quality signals, not a measured probability or guarantee of accuracy.
Macro unitsRead nutrition_basis: food results may be per 100 g, 100 ml or serving. Unknown units return null nutrition and resolution_required. calories are kcal; protein_g / carbs_g / fat_g are grams. Each micronutrient in nutrients[] carries its own amount + unit.

The reference corpus grows through eligible provider food facts and imports. Private descriptions, photos, and corrections are kept separate. Reuse can reduce provider calls; improved accuracy requires independent evidence and evaluation.

Media URLs

Image delivery follows the same owned-path rule across recipes, drinks, ingredients, and barcode products:

  • Approved provider images are downloaded once, bounded to 5 MB, validated by MIME type, and stored in FitVete's public food-images bucket.
  • Returned image fields use https://auth.fitvete.com/storage/v1/object/public/food-images/….
  • If an image cannot be safely hosted, the field is omitted or returned as null; the API never falls back to an external image URL.
  • Attribution text and license metadata remain available where the underlying record requires them, without exposing a third-party link in the result.

Errors

Standard HTTP status codes. Error bodies are { "status": "failure", "code": <int>, "message": "…" }.

StatusMeaning
200OK
400Missing or invalid parameter
401Missing, invalid, or deleted API key
402Daily point limit reached — upgrade your plan
404Not found (e.g. unknown recipe id)
413Image upload exceeds the 5 MB limit
415Unsupported image type — use JPEG, PNG, or WebP
422Image is valid, but nutrition could not be read clearly
429Per-minute burst limit hit — retry after Retry-After seconds
502Vision provider temporarily unavailable — retry
503Authorization or storage temporarily unavailable — retry

One identification endpoint

POST /v1/identify accepts JSON with type: barcode|text|photo|label. Send barcode, text, or image_base64 plus content_type. It uses the corresponding barcode (1 point), parse (5 points), or image (10 points) operation exactly once. Direct developer keys only. Images remain limited to 5 MB after decoding.

Food names and portions are identified first; reference nutrition supplies text/photo numbers. Unresolved text items have resolved: false, null nutrition, and appear in unresolved_items. Incomplete meals have null totals and a separate resolved_totals subtotal. A photo with unresolved food returns 422. Portions remain estimates and should be reviewed.

Search, save and log foods

GET /v1/foods/search aliases food search. GET /v1/foods/{id} returns a reference food or a private food belonging to your developer account. POST /v1/foods creates a private food from name, nutrition_basis: "100g", calories, protein_g, carbs_g, and fat_g. POST /v1/logs accepts food_id, grams (0–3000, excluding zero), and optional ISO logged_at; the server calculates nutrition. Each costs 1 point. Creation returns 201. These are private developer-account records, excluded from the reference corpus and training. Authorize your own end users. Account deletion removes these records; do not blindly retry creation after an uncertain response.

The OpenAPI schema contains full request and response details.

Search foods

GET/v1/search-foods

Search the food database by name. Returns calories, macros, and a confidence score per match.

ParamTypeRequiredDescription
querystringyesFood name, e.g. chicken.
modestringnohybrid (default), semantic, or lexical.
numberintnoMax results, 1–25 (default 10).

Search combines exact names and aliases with semantic matches from FitVete's generic-food vector index. Use mode=semantic for meaning-based discovery or mode=lexical for names and branded products. The default is hybrid; it preserves lexical results when semantic inference is unavailable. Semantic-only requests return 503 during an encoder outage.

nutrient_coverage distinguishes reported, calculated, estimated and unresolved nutrient fields. Source facts in nutrients retain printed zeros and source precision. Each enriched field carries provenance with its method and source record. estimated_nutrients contains separately labeled values borrowed from compatible reference foods; these do not replace reported values or enter the authoritative macro calculation. unknown_keys lists gaps in the main nutrient array; unresolved_keys also accounts for available estimates. Estimates are not measurements of the target food. Legacy vitamin A values available only in IU are preserved as vitamin_a_iu, with no inferred micrograms or daily-value claim. match_score is a search rank, not an accuracy percentage.

Example response
{ "number": 1, "source": "corpus", "foods": [ { "name": "chicken breast", "calories": 120, "protein_g": 22, "carbs_g": 0, "fat_g": 3, "confidence": 100, "source": "corpus" } ] }

Compute nutrition

GET/v1/compute-nutrition

Nutrition for an ingredient list: macros, available measured vitamins and minerals, and caloric breakdown. Nutrient coverage varies by source; missing measurements are never invented.

ParamTypeRequiredDescription
ingredientsstringyesOne or more ingredients, e.g. 1 cup rice. Separate multiple lines with newlines.
Example response
{ "source": "corpus-parser", "calories": 206, "protein_g": 4, "carbs_g": 45, "fat_g": 0, "nutrients": [ { "key": "fiber", "name": "Fiber", "amount": 0.6, "unit": "g" } ], "confidence": 100 }

Private foods accept nutrition_basis: "100g" or "100ml". To log a liquid, send {"food_id":"…","amount":250,"unit":"ml"} to POST /v1/logs. The unit must match the food; volume is never stored as grams.

Calculate recipe nutrients

POST/v1/recipes/calculate · 1 point

Combine public food IDs with edible ingredient amounts, servings and the measured finished weight. The engine returns per_recipe, per_serving and per_100g nutrition with each ingredient's calculation evidence. It uses reported food facts stored in FitVete.

Send 1–40 ingredients. Weights and servings must be at least 0.000001; the limits are 100000 grams or milliliters (or 1000 ingredient servings), 10000 servings and 1000000 grams finished weight.

Send either grams or amount with unit: "g" | "ml" | "serving". A drink with values per 100 ml can use {"amount":250,"unit":"ml"} directly. Gram/ml conversion requires reviewed product-specific density or paired measurements. Unresolved ingredients return 422 with their IDs, accepted units and evidence needed. An old stored 100g flag alone is never mass evidence.

Set preparation: "as_recorded" when the ingredient has no further nutrient loss after the state described by its food record. For example, use an already-cooked egg record and its cooked weight. For further cooking, set preparation: "cooked" and choose a retention_code from GET /v1/recipes/retention-factors?query=greens.

FitVete stores all 270 USDA Release 6 preparation profiles and 6,994 published factors. The selected factor applies to the original nutrient mass before scaling by final yield. Select the profile for your actual food and preparation; these are calculation estimates.

Every positive-weight ingredient must supply a compatible value for a nutrient total to appear. Missing ingredient values, incompatible folate forms and missing cooking factors remain in unresolved_nutrients, with a recovery action. incomplete_nutrient_subtotals reports known contributions separately; these are never presented as complete totals. input_weight_g and yield_factor can be null for volume inputs, while measured finished weight still supports recipe per-100g results. Borrowed food estimates are excluded. The USDA retention table has no calorie or macro factors: for further-cooked inputs, final macros are null and original totals are labeled input_macros. Use cooked food references with as_recorded to calculate cooked macros. Recipes are calculated on request and are not automatically saved.

Ingredient quantities and conversions

GET /v1/ingredients/units lists supported units. POST /v1/ingredients/convert accepts {amount,from_unit,to_unit,food_id?}. For example, 1 lb becomes 453.59237 g. Liquid units use explicit names such as us_cup; bare cups or teaspoons are ambiguous.

POST /v1/ingredients/amount accepts {food_id,nutrient_key,target_amount,target_unit} and calculates grams, millilitres or servings needed for the target from that food's reported nutrition. Keys include protein, calories and nutrient keys from food detail. Each operation costs one point.

Cross-dimension conversions require a public food with verified density or serving evidence. Missing values, zero nutrient content, borrowed estimates and incompatible nutrient units return 422. Requests are limited to 4096 bytes. Unit definitions follow NIST conversion factors. Ingredient amounts are arithmetic results, not personalized intake recommendations.

Pantry, scaling & recipe tools

These endpoints use complete recipes stored in FitVete and make no external recipe requests. Missing recipes return 404; bulk requests list unavailable IDs in not_found.

GET endpointParametersResult
/v1/recipes/bulkids=1536314674330,1003283717259, up to 25 IDsRecipe payloads in request order, duplicates removed. 5 points.
/v1/recipes/by-ingredientsingredients=rice,chicken, number=1–25, ranking=1|2, ignorePantry=true|falseRecipes with used, missing and unused ingredient breakdowns. 1 point.
/v1/recipes/{id}/ingredientsOptional servings=1–1000Recorded quantities, source yield and scale factor. 1 point.
/v1/recipes/{id}/nutritionRecipe IDRecorded nutrients per serving. 1 point.
/v1/recipes/{id}/instructionsRecipe IDInstruction groups and ordered steps. 1 point.

Pantry matching uses exact normalized ingredient names. Ranking 1 prioritizes more used ingredients; ranking 2, the default, prioritizes fewer missing ingredients. ignorePantry=true ignores only water, salt and table salt. Name matches do not establish sufficient quantities, substitutions or allergy safety. catalogue_complete identifies whether discovery read the complete bounded catalogue.

Scaling preserves the recorded unit. Missing or vague amounts stay null with quantity_known=false. Changing yield requires known source servings; otherwise the API returns 422. Missing nutrients stay absent. Use /v1/recipes/calculate for food-reference nutrition arithmetic.
fitvete-food recipe-bulk 1536314674330 1003283717259 fitvete-food recipes-by-ingredients "rice,chicken" --ranking 2 fitvete-food recipe-ingredients 1536314674330 --servings 4 fitvete-food recipe-nutrition 1536314674330 fitvete-food recipe-instructions 1536314674330

Private users, plans & shopping

Connect each user from your backend with POST /v1/users and {"external_id":"your-opaque-user-id"}. Matching retries return the same user UUID within your developer account. Use a direct developer key on your server, and authorize your own users before proxying requests. The user UUID is an identifier, not a login token; never put the developer key in a mobile or browser app.

Under /v1/users/{user_id}, six resources support list/search, create, read, replace and delete: recipes, plans, templates, shopping-lists, foods and logs. They stay private to that developer and connected user, separate from native app accounts, public search and model training.

OperationRequestBehavior
GET resource collection?query=rice&limit=25&after=UUIDLiteral name search, 1–50 results, next_cursor. UUID-ordered pagination.
POST resource collection{"id":"YOUR-STABLE-UUID","data":{...}}Creates a document at revision 1. Identical retries return it; changed content at the same ID returns 409.
GET resource/{id}Document UUIDReturns data, revision and a revision ETag.
PUT resource/{id}{"data":{...}} and If-Match: 1Replaces the whole input document and increments its revision. Stale edits return 409.
DELETE resource/{id}If-Match: 1Deletes only at the expected revision.

Send the integer revision as If-Match. The returned ETag also works, including a W/ prefix added by a proxy. Each request costs one point. Limits are 10,000 connected users per developer, 500 documents per resource/user (10,000 logs), 80 KB input and 95 KB expanded JSON. Total private JSON storage per developer is 1 MiB on Free, 16 MiB on Starter, 64 MiB on Pro and 256 MiB on Ultra. Storage limits return 422; deleting or shrinking a document releases capacity. Deleting /v1/users/{user_id} permanently erases that user's workspace.

Save recipes with honest nutrition

A recipe supplies its name, yield in servings, ingredient quantities for the whole recipe, and ordered instructions. Optional nutrition is per serving and marked as unverified user input. Missing nutrients and quantities remain null.

fitvete-food connect-user customer-42 fitvete-food create-user-recipe USER_UUID '{"id":"RECIPE_UUID","data":{"name":"Rice bowl","servings":4,"ingredients":[{"name":"rice","amount":200,"unit":"g"}],"instructions":["Cook the rice."],"nutrition":{"calories":200,"protein_g":10,"carbs_g":30,"fat_g":5}}}' fitvete-food user-recipes USER_UUID --query rice

Generate and persist a plan

POST /v1/meal-plans/generate accepts days: 1|7, target_calories and optional protein, diet, cooking-time and excluded-ingredient filters. Generation uses owned recipes and returns actual target deviations, whether each day is within 20% of the requested calories, and plan_days ready to save. It does not save automatically. No matching source metadata returns 422; ingredient text exclusions do not establish allergy safety.

fitvete-food generate-plan '{"days":7,"target_calories":2000,"target_protein_g":120,"max_minutes":45}' # Save plan_days from that response as data.days, with a name and start_date. fitvete-food create-user-plan USER_UUID '{"id":"PLAN_UUID","data":{"name":"Monday lunch","start_date":"2026-09-14","days":[{"day":1,"meals":[{"recipe_id":"PRIVATE_RECIPE_UUID","servings":2,"slot":"lunch"}]}]}}'

Use an integer for an owned public recipe ID or a UUID for this user's private recipe. Saves resolve nutrition and scale ingredient amounts from the source yield. Stored plans are snapshots; editing a recipe does not silently rewrite an old plan. A partial nutrient makes its total unknown, with a missing-item count. Clear a day by replacing its meals with []. Templates use the same name/days input without start_date; read a template's day/meal references to create a dated plan. Derived response fields are read-only: send the documented input fields on replacement.

Turn a plan into a shopping list

fitvete-food plan-shopping-list USER_UUID PLAN_UUID '{"id":"LIST_UUID","name":"This week","plan_revision":1}' fitvete-food user-shopping-list USER_UUID LIST_UUID fitvete-food update-user-shopping-list USER_UUID LIST_UUID '{"data":{"name":"This week","items":[{"item_id":"1","name":"rice","amount":100,"unit":"g","checked":true}]}}' --revision 1

Lists combine exact normalized ingredient names in matching units, including SI kilograms/milligrams to grams and liters to milliliters. Grams and milliliters stay separate without density evidence; cups and spoons retain their stated unit. Unknown quantities stay separate. Generated lists record the plan revision; later plan edits do not overwrite checked items. The current limit is 500 items.

Private foods require plausible calorie/macronutrient values on an explicit 100g or 100ml basis. Logs accept a public food UUID or this user's private food UUID, an amount, g|ml, and logged_at. Nutrition is calculated from that reference. See the OpenAPI schemas for each input and response.

GET/v1/recipes/search

Search by name and/or filters. Every discovery request checks the owned recipe catalogue first, including filtered and paged searches. Returns id, title, image, ready time, and calories per result. Pass query or at least one filter.

ParamTypeDescription
querystringName or keywords (optional if a filter is given).
dietstringe.g. vegetarian, vegan, ketogenic, paleo. See diets.
cuisinestringe.g. italian, mexican, asian. See cuisines.
typestringMeal type, e.g. breakfast, dessert, main course (alias mealType). See meal types.
intolerancesstringComma-separated, e.g. gluten,dairy.
includeIngredientsstringComma-separated must-include ingredients.
excludeIngredientsstringComma-separated must-exclude ingredients.
maxReadyTimeintMax minutes to prepare.
minCalories / maxCaloriesintCalorie range.
minProteinintProtein floor (g).
sortstringe.g. popularity, calories, time, protein.
offsetintPagination offset (0–900).
numberintMax results, 1–25 (default 10).
Example response
{ "number": 1, "offset": 0, "totalResults": 42, "source": "corpus", "recipes": [ { "id": 715538, "title": "Pasta With Chicken and Mushrooms", "image": "https://auth.fitvete.com/storage/v1/object/public/food-images/8de2…jpg", "ready_in_minutes": 35, "calories": 463 } ] }
Use your owned recipe data. Add data=owned to recipe search, random, autocomplete, by-nutrients, similar or detail requests to disable external recipe fallback. Empty searches return an empty list; an unknown detail ID returns 404. The default data=auto checks owned recipes first. Owned discovery requires ingredients, instructions and per-serving nutrition; coverage_scope=owned_recipes identifies the result set, while catalogue_complete reports whether the full bounded catalogue was read. Diet and intolerance filters require explicit metadata. A supported filter does not guarantee matching recipe coverage.

Random recipes

GET/v1/recipes/random

Return random full recipes (great for "surprise me" / discovery). Harvested into the corpus.

ParamTypeDescription
numberintHow many, 1–25 (default 5).
tagsstringComma-separated diet/meal tags, e.g. vegetarian,dessert.

Recipe autocomplete

GET/v1/recipes/autocomplete

Title suggestions for a partial query — ideal for search-as-you-type.

ParamTypeRequiredDescription
querystringyesPartial recipe name, e.g. choc.
numberintnoMax suggestions, 1–25 (default 10).

Recipes by nutrients

GET/v1/recipes/by-nutrients

Find recipes that fit calorie/protein/carb/fat ranges — perfect for macro-target meal planning. At least one range is required.

ParamTypeDescription
minCalories / maxCaloriesintCalorie range.
minProtein / maxProteinintProtein range (g).
minCarbs / maxCarbsintCarb range (g).
minFat / maxFatintFat range (g).
numberintMax results, 1–25 (default 10).

Similar recipes

GET/v1/recipes/{id}/similar

Recipes similar to a given id — for "you might also like" recommendations.

ParamTypeRequiredDescription
idintyesRecipe id (path segment).
numberintnoMax results, 1–25 (default 5).

Diets, cuisines & meal types

Reference lists of the values accepted by the search filters (no upstream call):

  • GET/v1/recipes/diets — supported diet values.
  • GET/v1/recipes/cuisines — supported cuisine values.
  • GET/v1/recipes/meal-types — supported type values.

Get recipe

GET/v1/recipes/{id}

Full recipe detail: images, dietary properties, nutrition, ingredients with measures, and step-by-step instructions.

ParamTypeRequiredDescription
idintyesRecipe id (path segment), e.g. 715538.
servingsintnoAdds a serving_scale block with macros scaled to this many servings.

GET/v1/drinks/search

Search drinks and cocktails — flavors, glass type, ingredients, and nutrition.

ParamTypeRequiredDescription
querystringyesDrink name, e.g. margarita.
numberintnoMax results, 1–25 (default 10).

Barcode lookup

GET/v1/barcode/{code}

Look up a packaged food by UPC/EAN barcode. Results are harvested into the owned corpus so repeat lookups can serve from FitVete data.

ParamTypeRequiredDescription
codestringyesNumeric barcode path segment. Non-digits are ignored.

Photo nutrition

POST/v1/nutrition-from-photo

Estimate meal calories, macros, visible items, and nutrients from a JPEG, PNG, or WebP meal photo. Send raw image bytes with an image/* content type, or multipart form field image.

Max 5 MBJPEG / PNG / WebP10 points

Nutrition label

POST/v1/nutrition-label

Parse a Nutrition Facts label photo into calories, macros, serving information, and printed nutrients. The response includes status, an explicit basis (per_serving or per_100g), independent field_confidence, and verbatim raw_text. Core macros are required; unreadable or unsupported optional fields are returned as null, never inferred. Send raw image bytes with an image/* content type, or multipart form field image.

Max 5 MBJPEG / PNG / WebP10 points

Scan memory & corrections

With a direct developer key, successful photo and label scans return scan_id, scan_revision, and scan_expires_at. Structured results stay private to your developer account for 30 days. Identical image bytes reuse the latest result, including your correction, without another vision call. Scan requests still use their normal point cost.

GET /v1/scans/{id} reads the latest result. POST /v1/scans/{id}/feedback saves complete corrected totals. DELETE /v1/scans/{id} removes that memory. All three cost 0 points, require a valid direct key, and remain subject to per-minute limits.

Corrections remain private by default. Optional contributions require explicit end-user permission and human review before evaluation use. Raw images are not stored in scan memory. Read the correction, consent, and retention guide →

Nutrition intelligence

Beyond raw data, these endpoints add the judgment layer: a personalized health score, ingredient/additive analysis, natural-language meal parsing, and healthier swaps. The scoring engine is deterministic and explainable — a pure function of nutrients, processing (NOVA), and your user's profile — so every grade is auditable, not a black-box number. AI identifies foods and portions in free text; reference data supplies nutrition. Score explanations fall back to deterministic reasons when AI is unavailable.

Scoring rubric: a Nutri-Score-derived base (0–100) penalizes energy, saturated fat, sugar, and sodium and rewards fiber and protein; an ultra-processing (NOVA 4/3) penalty is subtracted; then profile modifiers adjust for the user's goals and diet. An allergen or avoid-list match forces grade F. Sustainability/eco data is community-sourced (Open Food Facts) with variable coverage.

Personalized score

POST/v1/score 3 points

Score a food 0–100 with an A–F grade and human-readable reasons, tuned to the user's profile. Reference the food by name, barcode, or id.

Body fieldTypeDescription
food.name / food.barcode / food.idstringExactly one is required. Barcode pulls richer data (additives, NOVA, eco).
profile.goalsstring[]e.g. ["build muscle","low sugar"] — adjusts the score.
profile.dietstringe.g. vegan, keto — penalizes/flags violations.
profile.allergiesstring[]A match forces grade F + flag.
profile.avoidstring[]Ingredients to avoid; a match forces grade F.
explainboolAdd a one-line natural-language summary.
Example response
{ "source": "corpus", "food": "chicken breast", "score": 96, "grade": "A", "reasons": [ "High protein (22 g/100g)", "Bonus: high protein for your muscle goal" ], "flags": [], "eco_score": null, "nova": null }

Analyze ingredients

POST/v1/analyze-ingredients 2 points

Detect additives/E-numbers (with concern level), allergens, the NOVA ultra-processing level (1–4), and vegan/vegetarian/gluten-free flags from an ingredient list.

Body fieldTypeRequiredDescription
ingredientsstringyesComma-separated ingredient list (≤ 4000 chars).
Example response
{ "nova": 4, "vegan": false, "vegetarian": true, "gluten_free": true, "additives": [ { "code": "E471", "name": "Mono- and Diglycerides", "concern": "low" } ], "allergens": [ "milk", "tree nut", "soy" ] }

Parse meal (NLP)

POST/v1/parse 5 points

Turn a free-text meal into structured items with quantities and per-item + total nutrition.

Body fieldTypeRequiredDescription
textstringyesNatural-language meal, e.g. "2 eggs and a slice of toast" (≤ 1000 chars).
Example response
{ "source": "vision+corpus", "calories": 286, "protein_g": 15, "carbs_g": 18, "fat_g": 17, "complete": true, "items": [ { "name": "Scrambled eggs", "quantity": 2, "unit": "large", "calories": 182, "protein_g": 12, "carbs_g": 1, "fat_g": 14, "resolved": true }, { "name": "Toast", "quantity": 1, "unit": "slice", "calories": 104, "protein_g": 3, "carbs_g": 17, "fat_g": 3, "resolved": true } ], "unresolved_items": [] }

Healthier swaps

GET/v1/alternatives 1 point

Given a food, return higher-scoring alternatives from the catalog, ranked best-first.

ParamTypeDescription
name / barcode / idstringExactly one is required.
numberintMax swaps, 1–10 (default 5).

Food autocomplete

GET/v1/foods/autocomplete 1 point

Fast food-name typeahead from the corpus (upstream fallback on a miss).

ParamTypeRequiredDescription
querystringyesPartial food name.
numberintnoMax suggestions, 1–25 (default 10).

Recipe import, analysis and rendering

Seven tools turn explicit recipe content into reusable data and visuals. Each costs 1 point and is available through REST, CLI and remote MCP.

OperationResult
POST /v1/recipes/extractExtract schema.org/Recipe JSON-LD from submitted HTML or an allowed HTTPS URL. Supply exactly one of html or url; use select_index when a page contains several recipes.
GET /v1/recipes/import-sourcesExact host allowlist and limits. HTML is limited to 1 MiB, metadata to 20 recipes; redirects are rejected. Pages without recipe JSON-LD return 422.
POST /v1/recipes/analyzeSubmit instructions as 1–100 strings. Returns explicit English equipment mentions, numeric timers/ranges and temperatures with UTF-16 offsets in each returned step.
GET /v1/recipes/{id}/equipmentThe same instruction analysis for an owned recipe. Each mention retains its context, including negation and alternatives.
GET /v1/recipes/{id}/summaryRecorded yield, time, per-serving macros, ingredients and steps from the owned catalogue.
GET /v1/recipes/{id}/cardJSON with escaped HTML and a self-contained SVG recipe card, generated on demand.
POST /v1/widgets/nutritionRender explicit nutrition values to HTML/SVG. Supply a name, basis (per_100g, per_100ml or per_serving) and nutrients. Energy uses kcal, sodium mg, and protein/carbs/fat/fiber/sugar grams.

Extraction preserves unverified source text and never saves it automatically. Only a yield explicitly labelled “servings” becomes a serving count. Review it before saving a private recipe. Nutrition is never inferred from instructions. Renderers show missing values as Not reported and preserve measured zero; submitted numbers remain unverified. They contain no remote assets or scripts, and make no regulatory nutrition-label claim.

Equipment is a text mention, not a requirement or safety check. Timers can overlap and are not added to a total. Cards are not persisted; your application may store the returned HTML/SVG. All three recipe-ID routes use only the owned dataset and return 404 on a miss.

fitvete-food recipe-extract '{"url":"https://fitvete.com/api/examples/recipe.html"}' fitvete-food recipe-analyze '{"instructions":["Bake in the oven at 180°C for 20–25 minutes."]}' fitvete-food nutrition-widget '{"name":"My food","basis":"per_100g","nutrients":{"kcal":120,"protein":8,"sodium":null}}'

Command-line interface (CLI)

The fitvete-food CLI wraps common food and nutrition endpoints and prints clean JSON to stdout — ideal for scripts, pipelines, and AI agents. Install it from npm: fitvete-food-cli.

# install from npm (Node 18+) npm install -g fitvete-food-cli # one-time: set your key export FITVETE_API_KEY=fv_live_your_key # search foods fitvete-food search-foods chicken --number 5 # compute nutrition for an ingredient list fitvete-food compute "1 cup rice" "2 eggs" # recipes & drinks fitvete-food recipes pasta fitvete-food recipe 715538 fitvete-food drinks margarita fitvete-food barcode 012345678905 fitvete-food photo ./meal.jpg fitvete-food label ./nutrition-label.jpg # human-readable table instead of JSON fitvete-food search-foods banana --pretty
  • --key <key> — override FITVETE_API_KEY.
  • --number <n> — result count for search commands.
  • photo and label accept local JPEG, PNG, or WebP files up to 5 MB.
  • --pretty — formatted table for humans (default output is raw JSON).
  • Exit codes: 0 ok, 1 request error, 2 usage error, 3 auth/limit.

AI agents

The CLI is built to be driven by autonomous agents. It emits a machine-readable tool manifest you can hand straight to a function-calling model, and every command returns parseable JSON with a non-zero exit code on failure.

# print a JSON tool manifest (function-calling schema for every command) fitvete-food tools

A typical agent loop: read fitvete-food tools once to learn the available functions, then call commands and parse stdout. Because output is pure JSON (no prompts, no spinners), it pipes cleanly into jq or any parser:

fitvete-food search-foods salmon | jq '.foods[0].protein_g'

Connect an MCP client

Use Streamable HTTP at https://auth.fitvete.com/functions/v1/food-mcp with your developer key in the x-api-key header. The server exposes all 80 documented API operations. Your client must support custom HTTP headers; OAuth-only clients and legacy SSE connections are not supported.

{ "mcpServers": { "fitvete": { "type": "http", "url": "https://auth.fitvete.com/functions/v1/food-mcp", "headers": { "x-api-key": "YOUR_FITVETE_API_KEY" } } } }

This is a generic configuration example; use your client's equivalent URL/header fields and secret store. Keep the key out of source control and prompts. Tool inputs are grouped as path, query, headers, and body:

{ "name": "fitvete_foods_search", "arguments": { "query": { "query": "banana", "number": 3 } } }

Discovery is free of daily points and uses the per-minute limit. Each tool call retains its REST cost, status, quota headers and private account scope. Writes and deletes are labelled; approve intended changes in your client. Edits require the current If-Match revision. Image tools accept base64 bytes and a content type, up to 5 MiB. The endpoint is stateless and does not retain conversations.

Connection guide →

OpenAPI & SDKs

The full API is described by an OpenAPI 3.1 specification. Use it to explore endpoints, import into a client, or generate a typed SDK in your language:

# Import into Postman or Insomnia # File → Import → URL → https://fitvete.com/api/openapi.yaml # Generate a client SDK (Python, TypeScript, Go, Java, Swift, …) npx @openapitools/openapi-generator-cli generate \ -i https://fitvete.com/api/openapi.yaml \ -g python -o ./fitvete-sdk # Or try requests live with the spec curl https://fitvete.com/api/openapi.yaml

Prefer not to generate one? The CLI works everywhere with zero setup, and the per-language samples above copy-paste into any project.

Best practices

  • Budget your points. Most calls cost 1 point; image (vision) calls cost 10. Read X-RateLimit-Remaining and back off before you hit zero.
  • Handle 402 and 429. A 402 means your daily budget is spent (upgrade or wait for reset); a 429 means you exceeded the per-minute burst — wait the Retry-After seconds and retry. Use exponential backoff for transient 502/503.
  • Cache on your side. Food facts are stable — cache results by query/barcode to spend fewer points. (We already serve repeats from our corpus, but client caching saves a round trip.)
  • Send clear images. For photo/label endpoints, use a well-lit, straight-on shot under 5 MB (JPEG/PNG/WebP). A blurry label returns 422 rather than guessed numbers.
  • Keep keys server-side. Never ship a key in a public web/mobile client; proxy through your backend. Rotate by creating a new key and deleting the old one (takes effect immediately).

FAQ

Is there a free tier? Yes — 50 points/day, no card required. Upgrade anytime for more.

How do points reset? Daily. Your budget refreshes each calendar day (UTC).

What does source: "corpus" mean? The answer came from our owned, curated dataset. Other values describe an external provider, a private cache, or a corrected scan. Private scan data is not automatically added to the public corpus. See Data & concepts.

Why did a food return slightly different numbers than another API? Foods can differ by preparation, brand, and serving size. Generic food records use 100g; barcode records retain 100g, 100ml, per_serving or unknown. Only the matching nutrition projection is populated. Recipe nutrition is per serving. Confidence reflects data consistency and completeness, not a measured accuracy percentage.

Can I use this from an AI agent? Yes — the CLI emits a function-calling manifest (fitvete-food tools) and pure-JSON output. See AI agents.

Do you have higher limits / an SLA? Yes — see plans or email api@fitvete.com for volume/custom pricing.

Changelog

1.8: Per-nutrient source evidence, separate compatible-food estimates, expanded exact-label mapping and owned ingredient/yield/retention recipe calculations.

VersionChanges
1.14Recipe JSON-LD extraction, instruction analysis, owned summaries/equipment/cards and explicit-value nutrition widgets. CLI 1.14.0 and all 80 remote MCP tools.
1.13Private developer end-user recipes, plans, templates, shopping lists, foods and logs; owned day/week generation, revision-safe edits and matching CLI tools.
1.12Owned pantry discovery, bulk recipe reads, ingredient scaling, nutrition and instruction projections, plus matching CLI commands. Unknown quantities remain explicit.
1.7Hybrid semantic food discovery, explicit nutrient coverage, broader exact-source USDA nutrients, and stricter real-label validation. CLI search supports the retrieval mode.
1.6Unified identification, private foods and food logs; database-priced text/photo nutrition; stricter uploads, label validation, source contracts, serving calculations and account isolation. CLI tools cover all 28 public operations.
1.5Own-data-first serving: bulk-imported USDA FoodData Central foods and imported Open Food Facts barcodes; FitVete's own ingredient parser prices /v1/compute-nutrition from the owned corpus (new source: "corpus-parser") before any external provider.
1.4Nutrition intelligence: personalized /v1/score (Nutri-Score+NOVA, profile-aware, allergen hard-fail), /v1/analyze-ingredients, /v1/parse (NLP), /v1/alternatives, /v1/foods/autocomplete; attributes badges + eco_score on food/barcode responses.
1.3Expanded recipe surface: filtered search (diet, cuisine, intolerances, ingredients, time, calorie/protein), random, autocomplete, similar, by-nutrients, diet/cuisine/meal-type reference lists, and a servings scaler on recipe detail.
1.2Added barcode lookup, photo nutrition, and Nutrition Facts label endpoints; per-endpoint point costs; X-RateLimit-Cost header.
1.1Self-growing corpus: on a miss, results are fetched upstream, returned, and saved. Added source field.
1.0Initial release: foods, compute-nutrition, recipes, drinks; API keys, tiered daily points, burst limits.

Data sources & attribution

The curated corpus combines USDA FoodData Central (public domain), product data from Open Food Facts — available under the Open Database License (ODbL) — and licensed provider lookups. Barcode responses derived from Open Food Facts remain subject to the ODbL.

Government recipes include ingredients, instructions, recipe yield, and published nutrition per serving. Source: National Heart, Lung, and Blood Institute; National Institutes of Health; U.S. Department of Health and Human Services. Source attribution identifies the origin of the data and does not imply endorsement.

Bulk imports validate barcode check digits, preserve source revisions, and exclude records with missing or inconsistent nutrition. Coverage varies by food, country, and brand; the catalogue does not contain every product or recipe. View the dated coverage snapshot.

Get your free API keyDownload OpenAPI specOpen dashboard