💪 Body Mode
  • Features
  • How It Works
  • Docs
  • Download
  • Privacy

API Documentation

Version 1.0 - Last Updated: December 28, 2024

API Status: Operational

Base URL: https://bodymode.netlify.app

Overview

Body Mode's backend is powered by Netlify serverless functions that provide a secure proxy to Google's Gemini AI API. This architecture keeps API keys server-side while providing fast, scalable AI features to the mobile app.

Key Features

  • 🔒 Secure API Key Management: Keys never exposed to client applications
  • ⚡ Serverless Architecture: Auto-scaling with 99.9% uptime
  • 🌍 Global CDN: Low-latency responses worldwide
  • 💰 Free Tier: 125,000 function calls per month
  • 🛡️ CORS Enabled: Secure cross-origin requests from mobile apps

Authentication

The API does not require client-side authentication. The Gemini API key is securely stored as an environment variable on Netlify servers and never exposed to clients.

Note: While the endpoint is publicly accessible, it implements request validation and rate limiting to prevent abuse.

Endpoints

POST Gemini AI Proxy

/.netlify/functions/gemini-proxy

Proxies requests to Google's Gemini AI API for food recognition, plan generation, chat, and other AI features.

Request Headers

Header Value Required
Content-Type application/json ✅ Yes

Request Body Parameters

Parameter Type Required Description
model string ✅ Yes Gemini model name (e.g., "gemini-1.5-flash", "gemini-1.5-pro")
contents object ✅ Yes Message content with parts array containing text/images
config object ❌ No Optional configuration (systemInstruction, responseMimeType, etc.)

Example Request

{
  "model": "gemini-1.5-flash",
  "contents": {
    "parts": [
      {
        "text": "Analyze this meal and provide nutritional information"
      },
      {
        "inlineData": {
          "mimeType": "image/jpeg",
          "data": "base64_encoded_image_data..."
        }
      }
    ]
  },
  "config": {
    "systemInstruction": "You are a nutrition expert...",
    "responseMimeType": "application/json",
    "generationConfig": {
      "temperature": 0.7,
      "maxOutputTokens": 2048
    }
  }
}

Success Response (200 OK)

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "{\"food\":\"Chicken Salad\",\"calories\":350,...}"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP"
    }
  ],
  "text": "{\"food\":\"Chicken Salad\",\"calories\":350,...}"
}

Error Responses

Status Code Reason Response Example
400 Bad Request {"error": "Missing required fields"}
405 Method Not Allowed {"error": "Method not allowed"}
413 Payload Too Large {"error": "Request too large"}
500 Server Error {"error": "Internal server error"}
503 Service Unavailable {"error": "Gemini API unavailable"}

Rate Limits

Our free tier provides generous limits for all users:

  • Function Calls: 125,000 requests per month
  • Bandwidth: 100 GB per month
  • Concurrent Requests: 1,000 simultaneous
  • Request Timeout: 26 seconds maximum
  • Payload Size: 500 KB maximum per request

These limits are shared across all users. If you experience rate limiting, please wait a few seconds and retry.

Request Validation

All requests are validated before being forwarded to Gemini AI:

  • ✅ Method Validation: Only POST requests accepted
  • ✅ Content-Type Check: Must be application/json
  • ✅ Required Fields: model and contents must be present
  • ✅ Size Validation: Request body limited to 500 KB
  • ✅ JSON Validation: Malformed JSON rejected with error

Common Use Cases

1. Food Recognition from Photos

POST /.netlify/functions/gemini-proxy
{
  "model": "gemini-1.5-flash",
  "contents": {
    "parts": [
      {"text": "Analyze this food image"},
      {"inlineData": {"mimeType": "image/jpeg", "data": "..."}}
    ]
  },
  "config": {
    "systemInstruction": "You are a nutrition expert...",
    "responseMimeType": "application/json"
  }
}

2. Daily Plan Generation

POST /.netlify/functions/gemini-proxy
{
  "model": "gemini-1.5-flash",
  "contents": {
    "parts": [
      {"text": "Generate a personalized daily plan for..."}
    ]
  },
  "config": {
    "systemInstruction": "Create personalized health plans...",
    "responseMimeType": "application/json"
  }
}

3. Chat with AI Coach

POST /.netlify/functions/gemini-proxy
{
  "model": "gemini-1.5-flash",
  "contents": {
    "parts": [
      {"text": "User: How many calories should I eat?\nAI: "}
    ]
  },
  "config": {
    "systemInstruction": "You are a health and fitness coach...",
    "generationConfig": {"temperature": 0.9}
  }
}

Error Handling Best Practices

When integrating with the API, implement robust error handling:

async function callGeminiProxy(data) {
  try {
    const response = await fetch(
      'https://bodymode.netlify.app/.netlify/functions/gemini-proxy',
      {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(data),
        signal: AbortSignal.timeout(45000) // 45s timeout
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error || 'API request failed');
    }

    return await response.json();
  } catch (error) {
    if (error.name === 'TimeoutError') {
      console.error('Request timeout - try again');
    } else if (error.name === 'NetworkError') {
      console.error('Network error - check connection');
    } else {
      console.error('API Error:', error.message);
    }
    throw error;
  }
}

Mobile App Integration

The Body Mode React Native app uses a dedicated service wrapper to call the API:

Service File Location

mobile/src/services/netlifyGeminiService.ts

Key Features

  • Environment-based URL switching (dev/production)
  • 45-second timeout for long AI responses
  • Automatic retry logic with exponential backoff
  • Comprehensive error handling
  • Request/response logging in development

Testing the API

Using cURL

curl -X POST https://bodymode.netlify.app/.netlify/functions/gemini-proxy \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-1.5-flash",
    "contents": {
      "parts": [{"text": "Say hello"}]
    }
  }'

Using Postman

  1. Create new POST request to https://bodymode.netlify.app/.netlify/functions/gemini-proxy
  2. Set header: Content-Type: application/json
  3. Add JSON body with model, contents, and config
  4. Send request and inspect response

Using JavaScript Fetch

fetch('https://bodymode.netlify.app/.netlify/functions/gemini-proxy', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    model: 'gemini-1.5-flash',
    contents: {parts: [{text: 'Hello, AI!'}]}
  })
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));

Support & Contact

If you encounter issues with the API or have questions:

  • Email: viperotterdam@gmail.com
  • Website: bodymode.netlify.app
  • Status Page: API Status

← Back to Home | Privacy Policy | Terms of Service

Body Mode

Your AI-powered health & fitness companion

Product

  • Features
  • Documentation
  • Download

Legal

  • Privacy Policy
  • Terms of Service

© 2024 Body Mode. All rights reserved.