---
title: "Glycemic analysis of a meal photo"
method: POST
path: "/foods/glycemic/photo"
tags: ["Nutrition"]
---

# Glycemic analysis of a meal photo

`POST /foods/glycemic/photo`

## Request

- Base URL: `https://exercise-api.ymove.app/api/v2`
- URL: `https://exercise-api.ymove.app/api/v2/foods/glycemic/photo`
- Auth: one of:
  - API key in header `X-API-Key`
  - API key in query parameter `api_key`

Send a base64-encoded photo of a meal and get back its estimated ingredients with a glycemic index per ingredient, a glycemic load computed from the matched catalog carbohydrate and fiber figures, a meal-level load and category, and concrete advice for lowering the glycemic impact. Ingredient swaps in the advice are re-costed against the catalog so the projected meal load is grounded in the same data. Pro plan and above, and the key must have accepted the glycemic data waiver (POST /foods/glycemic/waiver) or the endpoint returns 403 glycemic_waiver_required. Uses your nutrition analysis quota.

## Request body

- object
  - `image` string, required: Base64-encoded image of a meal (JPEG/PNG)
  - `media_type` 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif'

## Response `200`

Ingredients with glycemic index and load, meal totals, and advice

- GlycemicAnalysisResult
  - `data` object
    - `items` object[]
      - `name` string: AI-identified ingredient name
      - `estimatedGrams` number: Estimated portion in grams
      - `confidence` 'high' | 'medium' | 'low'
      - `matchedFood` object, nullable: Matched food from the database (null if no match)
        - `id` string
        - `name` string
        - `servingSizeG` number
      - `nutrition` object, nullable
        - `calories` number
        - `protein` number
        - `fat` number
        - `carbs` number
      - `glycemicIndex` number, nullable: Glucose-referenced GI (0-110). Null for foods with no meaningful available carbohydrate.
      - `giBasis` 'published' | 'estimated' | 'not_applicable': Whether the GI is a published value, inferred from a similar food, or not applicable
      - `matchQuality` 'ok' | 'state_mismatch' | 'unrelated', nullable: Quality of the catalog match. 'state_mismatch' means the right food in the wrong preparation (carbohydrate per gram can be several-fold off); an 'unrelated' match is dropped, so it never appears with a matchedFood attached.
      - `fiberG` number, nullable
      - `availableCarbsG` number, nullable: Carbohydrate minus fiber, from the matched catalog food
      - `glycemicLoad` number, nullable: glycemicIndex x availableCarbsG / 100. Null when the ingredient could not be matched.
      - `glycemicLoadCategory` 'low' | 'medium' | 'high', nullable
    - `totals` object
      - `calories` number
      - `protein` number
      - `fat` number
      - `carbs` number
      - `fiber` number
      - `availableCarbs` number
    - `meal` object
      - `glycemicLoad` number: Sum of the matched ingredients glycemic loads
      - `glycemicLoadCategory` 'low' | 'medium' | 'high'
      - `estimatedGlycemicIndex` number, nullable: Available-carbohydrate weighted mean GI of the meal
      - `unmatchedItems` string[]: Ingredients with no catalog match, and therefore no load contribution
      - `flaggedItems` string[]: Ingredients counted in the total whose match was flagged state_mismatch
      - `scale` object: The cut-offs used for the category fields
        - `item` string
        - `meal` string
    - `advice` object[]: Concrete changes to this meal that lower its glycemic impact
      - `suggestion` string
      - `rationale` string
      - `swap` object: Present when the advice is an ingredient swap. Numbers are recomputed for the same gram weight when the replacement matches the catalog.
        - `from` string
        - `to` string
        - `glycemicIndex` number, nullable
        - `matchedFood` object
          - `id` string
          - `name` string
        - `glycemicLoad` number, nullable
        - `glycemicLoadDelta` number, nullable: Negative means the swap lowers the load
        - `projectedMealGlycemicLoad` number, nullable
    - `disclaimer` string
  - `usage` object
    - `analyses_used` integer
    - `analyses_included` integer
    - `is_overage` boolean
    - `overage_charge` number

## Other responses

- `403`: Requires Pro plan or higher

---

[API](https://skmtc.dev/ymove/apis/ymove-fitness-api.md) · [All operations](https://skmtc.dev/ymove/apis/ymove-fitness-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ymove/apis/ymove-fitness-api/revisions/6636f2b4a343?raw)
