For the complete documentation index, see llms.txt. This page is also available as Markdown.

AI / LLM Friendly Docs

This is a comprehensive single-file reference for the Nutrition AI Platform, optimized for LLMs, AI agents, chatbots, and RAG systems. For the full documentation with interactive OpenAPI specs, see https://passio.gitbook.io/nutrition-ai.


1. What is Nutrition AI?

Passio's Nutrition AI Platform provides AI-powered food recognition, a 2.5M+ food database, and nutrition analysis. Available via:

  • REST API for web and backend development

  • Mobile SDKs for iOS (Swift/SwiftUI), Android (Kotlin), React Native, and Flutter

  • Easy AI - no-code platform for custom AI tools, chatbots, RAG, function chains

One Nutrition AI key works across the REST API and all SDKs. Easy AI uses a separate API key, available on the Easy AI platform.


2. Authentication

Step 1: Get your API key from https://accounts.passiolife.com

Step 2: Exchange it for a Bearer token (valid ~24 hours):

POST https://api.passiolife.com/v2/token-cache/unified/oauth/token/{YOUR_API_KEY}

Response:

{
  "access_token": "eyJhbGciOiJS...",
  "scope": "read:search read:products",
  "expires_in": 86155,
  "token_type": "Bearer",
  "customer_id": "0d8bb889-36e1-11ee-b9e9-92e504c243a4"
}

Step 3: Include on every request:

Cache the token and refresh before expires_in elapses. On 401, re-authenticate.


3. API Base URL and Path Prefixes

Base URL: https://api.passiolife.com/v2/products

Prefix
Use

/napi/...

Recommended. Current production path for all REST API calls.

/food/...

Legacy path. Still functional but may not support all newer features.

/sdk/...

Internal SDK use only. Do not call directly from REST API.

All endpoint paths in this document use the /napi/ prefix.


4. Pricing and Token System

Tier
Monthly
Included tokens
Refill per 1M
Easy AI
Insights
AI Insights
Model switching

Starter

$99

1M

$25

Yes

No

No

No

Growth

$599

5M

$10

Yes

Yes

No

Yes

Pro

$2,999

100M

$2.50

Yes

Yes

Yes

Yes

Token cap for the billing period: cap = (included_monthly_tokens + refill_tokens_this_cycle) x 1,000,000

Up to 10% over this cap is allowed (grace period) before requests are rejected with HTTP 429.

Auto-refill can be enabled in account settings. Manual refills available via Manage Plan.


5. Core Endpoints - Food Database

Semantic search (AI-powered)

Returns: { results: [...], alternateNames: [...] }. Each result has displayName, refCode, nutritionPreview (calories, macros for default serving).

Advanced search (legacy)

Same response format. Legacy endpoint, still available for exact brand name and product searches. Use semantic search as the default.

Full nutrition by refCode

Returns a complete food item with all ingredients, nutrients (per 100g), portions, serving sizes, and brand info. This is the main endpoint for detailed nutrition data after search or recognition.

Barcode / UPC lookup

Example: GET /napi/food/productCode/0602652257230

Returns full food item if found; empty or 404 if barcode not in database.


6. Core Endpoints - Vision (Image Recognition)

Food recognition (default vision endpoint)

Handles food photos, barcode images, and nutrition labels in a single call. Recommended image size: 500px (maintaining aspect ratio).

JSON input (recommended):

Multipart input: form field name image for images, video_file for videos.

Response (array of recognized items):

  • ingredientName, portionSize, weightGrams = AI's raw recognition output

  • nutritionPreview = pre-calculated from Passio's nutrition database (use for display)

  • refCode = fetch full details via /napi/food/search/result/refCode/{refCode}

  • mealName = the overall meal/dish (e.g. "Fruit Salad", "Chicken Stir Fry"). All items belonging to the same meal share this value. Use it to display the meal as a whole instead of listing individual ingredients.

  • componentName = sub-group within the meal (e.g. "salad", "dressing"). Groups related ingredients together; for a single dish, all items typically share the same componentName.

Sum nutritionPreview values across items sharing the same mealName for meal totals.

Nutrition label scan

Extracts serving size, calories, macros, micronutrients, ingredients list from nutrition facts labels. Recommended image size: 1200px.

Same input format as food recognition (base64 JSON or multipart image).


7. Core Endpoints - Text and Voice

Voice / text meal logging

Also accepts audio_file via multipart for voice input.

Response (array of log actions):

Extract ingredients from text

Returns array of ingredient objects with name, portion, quantity, weight, and Passio database matches.

Group ingredients to meal

Groups a flat ingredient list into logical meal components.

Other text tools

Endpoint
Purpose

POST /napi/tools/visualAlternativeSuggestions

Visually similar food alternatives for dietary preferences

POST /napi/tools/invisibleIngredientSuggestions

Hidden ingredients (sugar in coffee, oil in dressing)

POST /napi/tools/possibleIngredientSuggestions

Likely ingredients for a given food/meal

POST /napi/tools/predictIngredients

Predict constituent ingredients for dietary analysis

All text tools accept {"content": "..."} as JSON body, plus an optional message field for extra context such as a dietary profile. Many also accept audio_file via multipart.


8. Meal Plans

Two-step workflow

  1. Preview (fast, 4-20 seconds): POST /napi/tools/generateMealPlanPreview

  2. User reviews, rejects meals (rejected: true), re-sends for regeneration

  3. Full generation (1.5-6 minutes): POST /napi/tools/generateMealPlan

Input: {"content": "Generate a 3 day meal plan with high protein for a 33 year old athletic male"}

Optional query params: model (idea generation), model2 (day refinement). Using gemini-2-5-pro for both improves quality but costs more.

Preview response:

Additional meal plan endpoints

Endpoint
Purpose

POST /napi/tools/regenerateMeals

Regenerate specific meals from existing plan

POST /napi/tools/updateMealPlanShoppingList

Regenerate shopping list for plan

POST /napi/tools/humanizeShoppingList

Convert technical list to shopping format

POST /napi/affiliates/convertMealPlanToAffiliateLink

Generate Instacart/affiliate link


9. Rating and Analysis Endpoints

Endpoint
Purpose
Returns

POST /napi/tools/ultraProcessedFoodRating

UPF rating (1-10)

{rating, highlightedIngredients, chainOfThought}

POST /napi/tools/genericFoodRating

Custom criteria food rating

{rating, chainOfThought}

POST /napi/tools/estimateGlycemicIndexLoad

Glycemic index and load

{ingredients: [{gi_low, gi_high, gl_low, gl_high, confidence}]}

All accept {"content": "..."}.


10. Intelligence Profile (Personalization)

Send dietary context in the optional message field on any AI tool request. Free-form: plain text, stringified JSON, or YAML.

Vision and video tools take the same field next to image.

Optionally generate a normalized profile first and put its result into message.

Generate: POST /napi/tools/generateIntelligenceProfile

Response:

Legacy: The Passio-NutritionIP: <profileValue> header still works on the original AI routes (extractMealLogAction, nutritionAdvisor, generateMealPlan, extractIngredients), but newer tools read context from message.


11. Food Submission and Reporting

Endpoint
Purpose

POST /napi/food/submit/product

Submit a new food product to the database

POST /napi/food/report/product

Report inaccurate data for an existing product


12. Nutrition Data Model

Nutrients per 100g

All nutrients are stored assuming a 100g reference weight. To calculate nutrients for a specific serving:

Portions and serving sizes

Each food item has an array of portions. The first (default) portion is recommended. If no portions exist, assume 100g:

A typical portion:

Food item structure

A food item returned by refCode lookup:

For recipes (multiple ingredients), calculate each ingredient's nutrients separately, then sum. Apply the top-level portion to the combined total.

nutritionPreview vs full details

  • nutritionPreview (on search/recognition results): pre-calculated calories and macros for the default serving. Use for quick display.

  • Full details via refCode: complete nutrient profile (20-30 nutrients), all available portions, ingredient breakdown, brand info.

refCode

Base64-URL-encoded JSON containing lookup info. Returned by search results and recognition responses. Stable for persistent storage. Use with GET /napi/food/search/result/refCode/{refCode}.


13. Localization

Translation

ISO 639-1 code. Translates food names, descriptions, serving sizes in responses.

Regional optimization (does NOT translate)

BCP47 tag or ISO 639-1. Activates region-specific search indexes and optimizes AI responses for that region. Does not translate - use Localization-ISO for translation.

These are independent - use one or both. For a fully localized experience, set both.

Search filtering

Field
Type
Description

regionFilters

{code: priority}

Boost/restrict by region. Priority 1 = highest. Codes: ISO2, BCP47, or language.

sourceFilters

string[]

Filter by source: fdc, firebase, legacy, openfood, passio, passio-foodai

typeFilters

string[]

Filter by type: generic, branded, recipe

strictRegionMode

boolean

true = only matching regions; false (default) = boost

ignoreWithConcernFlags

number[]

Exclude items with data quality issues (e.g. 1002=missing nutrients, 1100=invalid serving)

dataSourceConfigs

object[]

Control databases and result counts

SDK localization methods

SDK Method
Header
Input

updateLanguage(languageCode:)

Localization-ISO

ISO 639-1 ("ja"). Translates responses.

updateProductLocalization(localizationCode:)

Passio-Product-Localization

BCP47 or ISO 639-1 ("ja-JP"). Regional optimization, does NOT translate.

updateSearchConfiguration(config:)

Passio-Search-Config

JSON string


14. Image Input Details

The data:image/jpeg;base64, prefix is required. Missing it causes 400 errors.

Multipart form data

Use image as the form field name for image uploads and video_file for video uploads.

  • Food recognition: 500px (maintaining aspect ratio)

  • Nutrition label scan: 1200px (maintaining aspect ratio)


15. Token Usage Tracking

Response headers (on every API response)

Header
Description

X-Budget-Cap

Total token budget for billing period

X-Period-Usage

Tokens used this period

X-Request-Usage

Tokens used by this request

X-Model-Tag

AI model used for this request

X-Estimated-Cost-Usd

Your total cost for this request (USD)

X-Wholesale-Cost-Usd

Raw AI provider cost for this request (USD)

X-Billed-Tokens-Total

Total billed tokens (input + output, after normalization)

X-Billed-Input-Tokens

Billed input tokens (after normalization)

X-Billed-Output-Tokens

Billed output tokens (after normalization)

SDK token tracking

Use PassioAccountListener (Android/RN/Flutter) or PassioAccountDelegate (iOS). Fires on each request with PassioTokenBudget:

  • requestUsage (iOS/RN) or tokensUsed (Android/Flutter) - tokens consumed by the request

  • budgetCap - total cap

  • periodUsage - cumulative usage this period

  • usedPercent - percentage of cap consumed (property on iOS/RN, method on Android/Flutter)

  • apiName - which API was called

Note: The SDK callback only surfaces X-Budget-Cap, X-Period-Usage, and X-Request-Usage. Cost and billed-token headers are not exposed — use the REST API or accounts dashboard for those.

Dashboard

https://accounts.passiolife.com - usage breakdown by route type, refill settings, projected usage.


16. Model Settings

Query parameter model on any AI endpoint overrides the default model. Growth/Pro users can set a default model in the accounts dashboard. Priority order:

  1. model query parameter (highest)

  2. Dashboard default (Growth/Pro)

  3. System default


17. Zero Data Retention (ZDR)

Per-account compliance setting that restricts every AI request from the account to models served under a no-retention / no-training contract. Available on Growth and Pro plans. Toggled by the account owner from the accounts portal: Account Info tab → Privacy & Compliance card. No client-side or SDK changes are required — the next request after the toggle uses the new policy.

What changes when ZDR is on

  • Default model selection is restricted to ZDR-eligible models (Vertex-routed only).

  • Saved per-route overrides pointing to non-eligible models are silently substituted with an eligible model at request time.

  • The automatic fallback chain walks only eligible models (Gemini → Anthropic → Gemma).

  • SDK requests respect the setting (same account-level routing).

  • Each AI call is recorded with an [AI_AUDIT] server-side log line.

Eligible model families

Family
Examples (model tag)
Notes

Google Gemini

gemini, gemini-pro, gemini-2, gemini-2-5-flash, gemini-2-5-flash-lite, gemini-2-5-pro, gemini-3-flash-preview, gemini-3-1-pro-preview, gemini-3-1-flash-lite, gemini-3-1-flash-lite-preview

All Gemini 1.5 → 3.x are eligible

Google Gemma

gemma-4

Vertex Model Garden

Anthropic Claude

claude-haiku-4-5, claude-sonnet-4-6, claude-opus-4-6, claude-opus-4-7

Vertex Model Garden

Embeddings

gemini-embeddings

Only ZDR-eligible embeddings model

Not eligible

  • OpenAI GPT family (all gpt-*, o3-*, o4-*) — no no-train contract by default.

  • OpenAI embeddings (openai-large, openai-small) — different vector space from gemini-embeddings, cannot be silently substituted.

  • xAI Grok (all grok*), Groq (groq-gemma, groq-llama), Cerebras (cerebras-*) — no no-train contract.

For GPT under ZDR, customers should contact support@passiolife.com.

Discovering eligible models programmatically

Returns only ZDR-eligible entries. The unfiltered /napi/models/available always includes a zero_data_retention: true|false field per entry, so the full list can be filtered client-side as well.

ZDR-specific error responses

HTTP

code body field

Cause

400

MODEL_NOT_FOUND

?model=<tag> references a tag that does not exist (typo).

403

ZDR_MODEL_NOT_ALLOWED

?model=<tag> references a real model that is not ZDR-eligible.

503

ZDR_NO_MODEL_AVAILABLE

All ZDR-eligible models for the tool are temporarily unavailable. Rare; retry with exponential backoff.

Response body example (403):

Notes

  • ZDR is per-account, not per-key. All Nutrition AI keys on the account share the same ZDR state.

  • Only the account owner can toggle ZDR; team members cannot.

  • Disabling is instant — the next request after the toggle uses the new policy.

  • X-Model-Tag response header always reflects the model that actually served the request; under ZDR it will only ever be an eligible tag.


18. Mobile SDKs

Platforms

iOS (Swift/SwiftUI, CocoaPods or SPM), Android (Kotlin, Gradle), React Native (npm), Flutter (pub).

Current versions

SDK
Stable
Preview

iOS

3.3.0

Android

3.3.1

Flutter

3.2.14

3.3.0-preview1

React Native

3.3.0-preview1

Always link customers to the platform-specific changelog for authoritative version info:

Configuration

All SDKs use remoteOnly = true by default (recommended - no model downloads needed):

Key SDK methods mapping to REST API

SDK Method
REST API Endpoint

recognizeImageRemote(image:)

POST /napi/tools/vision/extractIngredientsAutoTyped

recognizeNutritionFactsRemote(image:)

POST /napi/tools/vision/extractPackagedProduct

searchForFood(byText:)

GET /napi/food/search/advanced

searchForFoodSemantic(byText:)

GET /napi/food/search/semantic

recognizeSpeechRemote(text:)

POST /napi/tools/extractMealLogAction

fetchFoodItemForRefCode(refCode:)

GET /napi/food/search/result/refCode/{refCode}

fetchFoodItemForProductCode(code:)

GET /napi/food/productCode/{code}

SDK data model

  • PassioAdvisorFoodInfo - recognition result with ingredientName, portionSize, weightGrams (AI estimate), nutritionPreview, foodDataInfo, plus mealName (overall meal/dish, e.g. "Fruit Salad") and componentName (sub-group within the meal). Items in the same meal share the same mealName — use it to display the meal as a whole instead of listing every ingredient. Available on iOS (3.2.12+), Android (3.2.14+), Flutter (3.3.0-preview1+), and React Native (3.3.0-preview0+).

  • PassioFoodItem - full food item with name, ingredients[], amount (portions/servings)

  • PassioFoodAmount - selected serving unit and quantity, weightGrams() (calculated from serving), nutrientsSelectedSize(), nutrientsReference() (per 100g)

  • PassioIngredient - single ingredient with metadata containing nutrients and portions

Changing serving sizes (SDK)


19. Common Errors

Code
Cause
Fix

400

Malformed request. Common: missing data:image/...;base64, prefix, wrong Content-Type. Under ZDR, also code: MODEL_NOT_FOUND if ?model= references a non-existent tag (Section 17).

Check request format

401

Missing or expired Bearer token

Re-authenticate (tokens last ~24h)

403

Invalid API key or insufficient permissions. Under ZDR, also code: ZDR_MODEL_NOT_ALLOWED if ?model= references a real but non-eligible model (Section 17).

Verify key at accounts portal

429

Token cap exceeded (with grace period exhausted)

Check X-Period-Usage header, refill or wait for next billing period

500

Server error

Retry with exponential backoff

503

Service temporarily unavailable. Under ZDR, also code: ZDR_NO_MODEL_AVAILABLE when all eligible models are saturated (Section 17).

Retry with exponential backoff

Retry guidance: 401 = re-auth then retry once. 429 = exponential backoff (1s, 2s, 4s). 500 / 503 = exponential backoff.


20. Deprecated Features

REST API

Legacy
Replacement

Advisor threads (/nutrition-advisor/threads/...)

POST /napi/tools/nutritionAdvisor

Pre-built meal plans (/food/recommend/mealPlans)

generateMealPlan / generateMealPlanPreview

extractFoodAndIngredients

extractIngredientsAutoTyped (meal hierarchy now default)

SDK

Legacy
Replacement

startFoodDetection / stopFoodDetection

recognizeImageRemote

recognizeImageRemoteWithGrouping

recognizeImageRemote (hierarchy now default)

startNutritionFactsDetection / stopNutritionFactsDetection

recognizeNutritionFactsRemote

fetchMealPlans / fetchMealPlanForDay

generateMealPlan / generateMealPlanPreview

Advisor (initConversation, sendMessage, sendImage)

Pending migration to tools endpoint


21. Easy AI

No-code platform for building custom AI tools, chatbots, RAG systems, and function chains. Access via the accounts portal or easyai.passiolife.com.

  • Web / server-side: Use the code snippets provided on the Easy AI platform to call your endpoints directly. A separate Easy AI API key is available on the Easy AI webpage for authentication — no need to route through the Nutrition AI API.

  • Mobile SDKs: Easy AI access from within the SDK is currently in development.


22. Data Sources and Licensing

The database includes data from:

  • USDA FDC - US government food composition data

  • Open Food Facts - Community-sourced product data (ODbL 1.0 license, attribution required)

  • Passio-curated data - internally researched and maintained

When displaying data from Open Food Facts, attribution is required per the ODbL 1.0 license.


23. Additional Resources

  • OpenAPI interactive docs: https://api.passiolife.com/v2/products/napi/docs

  • OpenAPI spec JSON: https://cdn.passiolife.com/documentation/openapi_manual.json

  • Accounts portal: https://accounts.passiolife.com

  • Support: support@passiolife.com

  • Slack community: https://passio-community.slack.com/channels/help

  • Full documentation: https://passio.gitbook.io/nutrition-ai

Last updated