{
  "openapi": "3.1.0",
  "info": {
    "title": "BiteRight Nutrition API (private preview)",
    "version": "0.1.0-preview",
    "summary": "Log a meal from a photo, voice note or text description and receive a JSON food log with the recognised dish, ingredients, estimated weight and nutrients.",
    "description": "Public description of the BiteRight business nutrition API, published for evaluation. The API is in private preview: endpoints, fields and limits are not final, production access is not available yet, and sandbox access is by request (https://biteright.app/contact/?intent=api). Each team receives its own base URL and access token. Pricing and usage limits have not been published. Input languages: English and Arabic. Nutrient values come from food-composition records; results are estimates and not medical advice.",
    "contact": { "name": "BiteRight", "email": "info@biteright.app", "url": "https://biteright.app/nutrition-api/" },
    "termsOfService": "https://biteright.app/terms-of-service/"
  },
  "externalDocs": { "description": "API overview, example requests and nutrient coverage", "url": "https://biteright.app/nutrition-api/#api-reference" },
  "servers": [
    {
      "url": "{baseUrl}",
      "description": "Assigned to your team when sandbox access is confirmed.",
      "variables": { "baseUrl": { "default": "https://example.invalid", "description": "Your team's API base URL." } }
    }
  ],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/api/b2b/v1/food-log": {
      "post": {
        "operationId": "createFoodLog",
        "summary": "Log a meal from photos or a text description",
        "description": "Send one or more meal photos (images[]) for photo logging, or a text description (meal_name) for text logging.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["date"],
                "properties": {
                  "date": { "type": "string", "format": "date", "examples": ["2026-09-07"], "description": "Meal date." },
                  "images[]": { "type": "array", "items": { "type": "string", "format": "binary" }, "description": "Meal photo file(s), for photo logging." },
                  "meal_name": { "type": "string", "examples": ["Salmon bowl with quinoa, broccoli, avocado and sweet potato"], "description": "Text description of the meal, for text logging." },
                  "size": { "type": "string", "enum": ["Small", "Medium", "Large", "Custom"], "description": "Portion size." },
                  "custom_size": { "type": "string", "examples": ["300"], "description": "Portion amount when size is Custom." }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/FoodLog" }
        }
      }
    },
    "/api/b2b/v1/food-log-voice": {
      "post": {
        "operationId": "createVoiceFoodLog",
        "summary": "Log a meal from a voice note",
        "description": "Send one or more voice notes describing the meal, in English or Arabic. Requires the user's dietary profile and RDI setup first.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["date", "voices[]"],
                "properties": {
                  "date": { "type": "string", "format": "date", "description": "Meal date." },
                  "voices[]": { "type": "array", "items": { "type": "string", "format": "binary" }, "description": "Voice note file(s), for example .m4a." }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/FoodLog" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "description": "Access token assigned to your team. Keep it on your server." }
    },
    "responses": {
      "FoodLog": {
        "description": "A food log. An HTTP 200 response can still contain an error field: treat any error value as a failed request.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/FoodLog" },
            "examples": {
              "photo": {
                "summary": "Abbreviated, with illustrative values",
                "value": {
                  "recognized_dish": "Salmon grain bowl",
                  "total_weight": "300 g",
                  "calories": { "name": "Calories", "amount": "542", "unit": "kcal" },
                  "macronutrients": {
                    "protein": { "name": "Protein", "amount": "34", "unit": "g" },
                    "carbohydrates": { "name": "Carbohydrates", "amount": "48.7", "unit": "g" },
                    "fiber": { "name": "Fiber", "amount": "8", "unit": "g" }
                  },
                  "minerals": { "potassium": { "name": "Potassium", "amount": "980", "unit": "mg" } },
                  "ingredients": ["salmon", "quinoa", "broccoli", "avocado", "sweet potato"]
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Nutrient": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "amount": { "type": "string", "description": "Numeric value as a string in the documented examples." },
          "unit": { "type": "string" }
        }
      },
      "NutrientGroup": {
        "type": "object",
        "additionalProperties": { "$ref": "#/components/schemas/Nutrient" }
      },
      "FoodLog": {
        "type": "object",
        "description": "Documented fields. Further vitamin, mineral and dietary-information fields are described in the sandbox documentation.",
        "additionalProperties": true,
        "properties": {
          "recognized_dish": { "type": "string" },
          "total_weight": { "type": "string" },
          "calories": { "$ref": "#/components/schemas/Nutrient" },
          "macronutrients": { "$ref": "#/components/schemas/NutrientGroup" },
          "vitamins": { "$ref": "#/components/schemas/NutrientGroup" },
          "minerals": { "$ref": "#/components/schemas/NutrientGroup" },
          "ingredients": { "type": "array", "items": { "type": "string" } },
          "error": { "type": "string", "description": "Present when the request failed, even with HTTP 200." }
        }
      }
    }
  }
}
