AI
Pass

Build an AI Nutrition Analyzer App — SDK Tutorial

Build an AI Nutrition Analyzer App — SDK Tutorial

Health apps consistently show the highest user retention in the AI tools space. In this tutorial, you'll build a nutrition analyzer that understands natural language meal descriptions and returns detailed breakdowns — using the AI Pass SDK with zero backend infrastructure.

Setup

  1. Sign up at aipass.one
  2. Developer DashboardOAuth2 Clients → New Client
  3. Copy your YOUR_CLIENT_ID

Complete App Code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>AI Nutrition Analyzer</title>
  <script src="https://aipass.one/aipass-sdk.js"></script>
  <style>
    * { box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #f0fdf4; padding: 24px; }
    .container { max-width: 700px; margin: 0 auto; }
    .card { background: white; border-radius: 16px; padding: 28px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); margin-bottom: 20px; }
    textarea { width: 100%; padding: 14px; border: 2px solid #bbf7d0; border-radius: 10px; font-size: 1rem; min-height: 100px; font-family: inherit; }
    button { background: linear-gradient(135deg, #22c55e, #16a34a); color: white; border: none; padding: 14px; border-radius: 10px; font-size: 1rem; font-weight: 600; cursor: pointer; width: 100%; margin-top: 12px; }
    .macro-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin: 20px 0; }
    .macro-card { background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 10px; padding: 16px; text-align: center; }
    .macro-value { font-size: 1.8rem; font-weight: 700; color: #16a34a; }
    .macro-label { font-size: 0.85rem; color: #4b5563; }
    .insights { background: #fffbeb; border-left: 4px solid #f59e0b; padding: 16px; border-radius: 0 10px 10px 0; margin-top: 16px; }
  </style>
</head>
<body>
  <div class="container">
    <h1 style="color:#166534">AI Nutrition Analyzer</h1>
    <p style="color:#16a34a;margin-bottom:24px">Describe any meal. Get instant calorie and macro breakdown.</p>

    <div class="card">
      <label style="font-weight:600;display:block;margin-bottom:8px">What did you eat?</label>
      <textarea id="meal" placeholder="E.g., Large Caesar salad with grilled chicken, croutons, and dressing. Also had a glass of orange juice."></textarea>
      <button onclick="analyzeMeal()">Analyze Nutrition</button>
    </div>

    <div id="results" style="display:none">
      <div class="card">
        <h3>Nutritional Breakdown</h3>
        <div class="macro-grid">
          <div class="macro-card"><div class="macro-value" id="calories">-</div><div class="macro-label">Calories</div></div>
          <div class="macro-card"><div class="macro-value" id="protein">-</div><div class="macro-label">Protein (g)</div></div>
          <div class="macro-card"><div class="macro-value" id="carbs">-</div><div class="macro-label">Carbs (g)</div></div>
          <div class="macro-card"><div class="macro-value" id="fat">-</div><div class="macro-label">Fat (g)</div></div>
        </div>
        <div class="insights" id="insights"></div>
      </div>
    </div>
  </div>

  <script>
    AiPass.initialize({
      clientId: 'YOUR_CLIENT_ID',
      requireLogin: true
    });

    async function analyzeMeal() {
      const meal = document.getElementById('meal').value.trim();
      if (!meal) return alert('Please describe your meal.');

      const btn = document.querySelector('button');
      btn.disabled = true; btn.textContent = 'Analyzing...';

      try {
        const r = await AiPass.generateCompletion({
          model: 'gpt-5-mini',
          temperature: 1,
          max_tokens: 16000,
          messages: [
            { role: 'system', content: 'You are a nutrition expert. Analyze the meal and return ONLY this JSON: {"calories":number,"protein":number,"carbs":number,"fat":number,"fiber":number,"insights":"2-3 sentence assessment","improvements":"one specific suggestion"}' },
            { role: 'user', content: 'Analyze: ' + meal }
          ]
        });

        let content = r.choices[0].message.content;
        if (content.includes('```')) content = content.split('```')[1].replace(/^json/, '').trim();
        const data = JSON.parse(content);

        document.getElementById('calories').textContent = data.calories;
        document.getElementById('protein').textContent = data.protein + 'g';
        document.getElementById('carbs').textContent = data.carbs + 'g';
        document.getElementById('fat').textContent = data.fat + 'g';
        document.getElementById('insights').innerHTML = '<strong>Analysis:</strong> ' + data.insights + '<br><br><strong>Tip:</strong> ' + data.improvements;
        document.getElementById('results').style.display = 'block';
      } catch (e) {
        alert('Error: ' + e.message);
      } finally {
        btn.disabled = false; btn.textContent = 'Analyze Nutrition';
      }
    }
  </script>
</body>
</html>

Key Pattern: Structured JSON Output

The key to reliable nutrition data extraction is prompting for JSON:

const r = await AiPass.generateCompletion({
  model: 'gpt-5-mini',
  temperature: 1,       // Always 1 for GPT-5 models
  max_tokens: 16000,    // Always set for GPT-5 models
  messages: [
    { role: 'system', content: 'Return ONLY valid JSON: {calories, protein, carbs, fat}' },
    { role: 'user', content: mealDescription }
  ]
});
const data = JSON.parse(r.choices[0].message.content);

Deploy & Earn

  • Self-host: Single HTML file, works on GitHub Pages, Netlify, Vercel
  • AI Pass catalog: Publish and earn 50% commission on every API call
  • Health apps have high repeat usage — great passive income potential

Resources