{
  "openapi": "3.1.0",
  "info": {
    "title": "Kallo API",
    "version": "1.0.0",
    "summary": "Nutrition logging from natural-language meal descriptions.",
    "description": "The HTTP API behind Kallo, a nutrition tracker that starts from a sentence rather than a search box.\n\n## Authentication\n\nEvery endpoint except those tagged `Public` needs a Supabase-issued user JWT in `Authorization: Bearer <jwt>`. There is no API-key programme and no OAuth authorization server: the only way to obtain a token today is to sign in as a Kallo user. Protected-resource metadata is published at [/.well-known/oauth-protected-resource](https://kallo.fit/.well-known/oauth-protected-resource) per RFC 9728, and it deliberately declares no scopes, because the tokens carry none.\n\n## Errors\n\nEvery documented API error returns the same envelope: `{ \"error\": { \"code\", \"status\", \"retryable\", \"message\", \"resolution\" } }`. `code` is stable and machine-readable; `retryable` says whether repeating the identical request could ever succeed; `resolution` gives the next machine-actionable step. Any `/api/*` path with no handler returns a 404 in this same shape, never HTML. Redirect-only operations and the health probe document their own non-error responses explicitly.\n\n## Stability\n\nOperations marked `x-internal` serve Kallo's own web and mobile clients and may change without a version bump. The `Public` tag marks the handful that are safe to depend on.\n\nHuman documentation: [https://kallo.fit/en/docs/developers/api](https://kallo.fit/en/docs/developers/api).",
    "contact": {
      "name": "Kallo support",
      "email": "support@kallo.fit",
      "url": "https://kallo.fit/en/docs/company/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://kallo.fit/en/docs/legal/terms"
    },
    "termsOfService": "https://kallo.fit/en/docs/legal/terms"
  },
  "servers": [
    {
      "url": "https://kallo.fit",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Developer documentation",
    "url": "https://kallo.fit/en/docs/developers/api"
  },
  "tags": [
    {
      "name": "Public",
      "description": "Callable with no credentials."
    },
    {
      "name": "Meals",
      "description": "Logging, editing and re-logging meals."
    },
    {
      "name": "Logging",
      "description": "The day view and the non-AI logging paths."
    },
    {
      "name": "Nutrition",
      "description": "Micronutrients, and reading a label from a photo."
    },
    {
      "name": "Tracking",
      "description": "Dashboard and weight."
    },
    {
      "name": "Circle",
      "description": "Friends, groups and shared meals."
    },
    {
      "name": "Account",
      "description": "Profile, export, deletion."
    },
    {
      "name": "Billing",
      "description": "Entitlements and checkout configuration."
    },
    {
      "name": "Onboarding",
      "description": "First-run setup."
    },
    {
      "name": "Support",
      "description": "Feedback and bug reports."
    },
    {
      "name": "Reference data",
      "description": "The food-composition tables behind every estimate: the Vietnam National Food Composition Table 2007, plus FAO and USDA."
    }
  ],
  "components": {
    "securitySchemes": {
      "supabaseBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "A Supabase Auth access token for a Kallo user. The token carries no scopes — it grants whatever that user can do — so an agent acting on someone’s behalf holds their full account authority. Treat it accordingly."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "description": "The shared API error envelope. `code` is stable, `message` is human-facing, and `resolution` is the next machine-actionable step.",
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "status",
              "retryable",
              "message",
              "resolution"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable error identifier.",
                "enum": [
                  "NOT_AUTHENTICATED",
                  "PROFILE_NOT_FOUND",
                  "VALIDATION_FAILED",
                  "NOT_FOUND",
                  "CONFLICT",
                  "RATE_LIMITED",
                  "PIPELINE_TIMEOUT",
                  "feature_locked",
                  "INTERNAL"
                ]
              },
              "status": {
                "type": "integer",
                "description": "Mirrors the HTTP status."
              },
              "retryable": {
                "type": "boolean",
                "description": "Whether retrying the identical request can succeed. `false` means fix the request or the session first."
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "resolution": {
                "type": "string",
                "description": "Machine-actionable next step that does not require parsing the message."
              },
              "feature": {
                "type": "string",
                "description": "Present only on `feature_locked`: the gated feature."
              },
              "reason": {
                "type": "string",
                "description": "Present only on `feature_locked`: why it is gated."
              }
            }
          }
        }
      },
      "HealthCheck": {
        "type": "object",
        "required": [
          "ok",
          "service"
        ],
        "description": "Liveness plus a handful of schema invariants.",
        "properties": {
          "ok": {
            "type": "boolean",
            "description": "True when every check passed."
          },
          "service": {
            "type": "string",
            "enum": [
              "kallo"
            ]
          },
          "checks": {
            "type": "object",
            "properties": {
              "hasUserProfiles": {
                "type": "boolean"
              },
              "hasFoodTable": {
                "type": "boolean"
              },
              "hasFoodSourceId": {
                "type": "boolean"
              },
              "hasNewUserTrigger": {
                "type": "boolean"
              },
              "seededFoodRows": {
                "type": "integer"
              },
              "orphanedAuthUsers": {
                "type": "integer"
              }
            }
          },
          "error": {
            "type": "string",
            "description": "Present instead of `checks` when the probe itself failed."
          }
        }
      },
      "WaitlistSignupResponse": {
        "type": "object",
        "required": [
          "ok"
        ],
        "additionalProperties": false,
        "description": "Deliberately content-free: identical whether the address is new, already pending, or already confirmed, so the endpoint cannot be used to test whether someone is on the list.",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        }
      },
      "InvitePreview": {
        "type": "object",
        "required": [
          "inviter",
          "status",
          "signedOut"
        ],
        "description": "Preview of a friend-invite link. A blocked edge returns the same 404 as an invalid slug — the payload never reveals that a block exists.",
        "properties": {
          "inviter": {
            "$ref": "#/components/schemas/PublicProfile"
          },
          "status": {
            "type": "string",
            "enum": [
              "self",
              "accepted",
              "none"
            ],
            "description": "`self` — your own link. `accepted` — already connected. `none` — connectable."
          },
          "signedOut": {
            "type": "boolean",
            "description": "True when the viewer has no session."
          }
        }
      },
      "WeightSummary": {
        "type": "object",
        "description": "Weight over a range, plus the trend the clients render. `weights` and `weightDates` are parallel arrays of the same length and order.",
        "required": [
          "range",
          "weights",
          "weightDates",
          "currentWeight"
        ],
        "properties": {
          "range": {
            "type": "string",
            "enum": [
              "30d",
              "90d"
            ]
          },
          "weights": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "Kilograms."
          },
          "weightDates": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "date"
            },
            "description": "`YYYY-MM-DD`, parallel to `weights`."
          },
          "currentWeight": {
            "type": "number",
            "description": "Most recent logged weight, kg."
          },
          "todayWeight": {
            "type": [
              "number",
              "null"
            ],
            "description": "Today's weight if logged."
          },
          "weightPlaceholder": {
            "type": "number",
            "description": "Suggested value for an empty weight input."
          },
          "daysLogged": {
            "type": "integer"
          },
          "periodStartWeight": {
            "type": "number",
            "description": "Weight at the start of the range, kg."
          },
          "expectedEndWeight": {
            "type": "number",
            "description": "Target weight at the end of the range, kg."
          },
          "goalDirection": {
            "type": "string",
            "enum": [
              "up",
              "down",
              "flat"
            ]
          },
          "periodElapsedDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "projectedEndWeight": {
            "type": "number",
            "description": "Server-computed forecast, kg."
          },
          "canProject": {
            "type": "boolean",
            "description": "False when there is too little data for the forecast to mean anything."
          }
        }
      },
      "Heatmap": {
        "type": "object",
        "required": [
          "cells",
          "monthHeaders"
        ],
        "additionalProperties": false,
        "description": "Calorie-adherence grid backing the dashboard consistency view.",
        "properties": {
          "cells": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "date",
                  "ratio",
                  "consumedRatio",
                  "status"
                ],
                "additionalProperties": false,
                "properties": {
                  "date": {
                    "type": "string",
                    "format": "date"
                  },
                  "ratio": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Adherence ratio for colour grading; null on partial days."
                  },
                  "consumedRatio": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Calories ÷ target, never gated by the partial rule."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "logged",
                      "partial",
                      "unlogged",
                      "future",
                      "outside"
                    ]
                  },
                  "hasCheatMeal": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "monthHeaders": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "month",
                "monthIndex",
                "startColumn",
                "span"
              ],
              "additionalProperties": false,
              "properties": {
                "month": {
                  "type": "string",
                  "description": "English short name."
                },
                "monthIndex": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 12
                },
                "startColumn": {
                  "type": "integer"
                },
                "span": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "DashboardBundle": {
        "type": "object",
        "description": "The four dashboard payloads in one response. Each slice is byte-identical to its standalone endpoint, so a client can seed four caches from one round-trip.",
        "properties": {
          "profile": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/OnboardingProfile"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for a user who never finished onboarding."
          },
          "day": {
            "$ref": "#/components/schemas/LoggingDay"
          },
          "weightSummary": {
            "$ref": "#/components/schemas/WeightSummary"
          },
          "heatmap": {
            "$ref": "#/components/schemas/Heatmap"
          }
        }
      },
      "IngredientSearchResults": {
        "type": "object",
        "required": [
          "results"
        ],
        "description": "Matches from the food-composition tables (Vietnam National Food Composition Table 2007, FAO, USDA).",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IngredientSearchResult"
            }
          }
        }
      },
      "NutritionValues": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "caloriesKcal",
          "proteinG",
          "carbohydrateG",
          "fatG",
          "fiberG",
          "sodiumMg",
          "calciumMg",
          "ironMg",
          "magnesiumMg",
          "phosphorusMg",
          "potassiumMg",
          "zincMg",
          "copperMcg",
          "manganeseMg",
          "betaCaroteneMcg",
          "vitaminAMcg",
          "vitaminDMcg",
          "vitaminEMg",
          "vitaminKMcg",
          "vitaminCMg",
          "vitaminB1Mg",
          "vitaminB2Mg",
          "vitaminPpMg",
          "vitaminB5Mg",
          "vitaminB6Mg",
          "vitaminB9Mcg",
          "vitaminB12Mcg",
          "vitaminHMcg"
        ],
        "properties": {
          "caloriesKcal": {
            "type": [
              "number",
              "null"
            ]
          },
          "proteinG": {
            "type": [
              "number",
              "null"
            ]
          },
          "carbohydrateG": {
            "type": [
              "number",
              "null"
            ]
          },
          "fatG": {
            "type": [
              "number",
              "null"
            ]
          },
          "fiberG": {
            "type": [
              "number",
              "null"
            ]
          },
          "sodiumMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "calciumMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "ironMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "magnesiumMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "phosphorusMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "potassiumMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "zincMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "copperMcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "manganeseMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "betaCaroteneMcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminAMcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminDMcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminEMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminKMcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminCMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminB1Mg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminB2Mg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminPpMg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminB5Mg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminB6Mg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminB9Mcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminB12Mcg": {
            "type": [
              "number",
              "null"
            ]
          },
          "vitaminHMcg": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "PublicProfile": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "userId",
          "handle",
          "displayName",
          "avatarSeed",
          "avatarUrl",
          "hasCustomAvatar"
        ],
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "handle": {
            "type": "string"
          },
          "displayName": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatarSeed": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatarUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "hasCustomAvatar": {
            "type": "boolean"
          }
        }
      },
      "IngredientSearchResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "namePrimary",
          "nameEn",
          "nameAlt",
          "state",
          "similarity",
          "per100g"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "namePrimary": {
            "type": "string"
          },
          "nameEn": {
            "type": [
              "string",
              "null"
            ]
          },
          "nameAlt": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "state": {
            "type": "string"
          },
          "similarity": {
            "type": "number"
          },
          "semantic": {
            "type": "boolean"
          },
          "per100g": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "caloriesKcal",
              "proteinG",
              "carbohydrateG",
              "fatG"
            ],
            "properties": {
              "caloriesKcal": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "proteinG": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "carbohydrateG": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "fatG": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        }
      },
      "LoggingDay": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "persistedMeals",
          "pendingConfirmations"
        ],
        "properties": {
          "persistedMeals": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "rawInput",
                "mealSlot",
                "confidenceOverall",
                "loggedAt",
                "nutrition",
                "mealItemGroups",
                "entryMode",
                "alcoholG",
                "cheatSliders",
                "share"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "rawInput": {
                  "type": "string"
                },
                "mealSlot": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "confidenceOverall": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "loggedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "nutrition": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "caloriesKcal",
                    "proteinG",
                    "carbohydrateG",
                    "fatG",
                    "fiberG",
                    "sodiumMg",
                    "calciumMg",
                    "ironMg",
                    "magnesiumMg",
                    "phosphorusMg",
                    "potassiumMg",
                    "zincMg",
                    "copperMcg",
                    "manganeseMg",
                    "betaCaroteneMcg",
                    "vitaminAMcg",
                    "vitaminDMcg",
                    "vitaminEMg",
                    "vitaminKMcg",
                    "vitaminCMg",
                    "vitaminB1Mg",
                    "vitaminB2Mg",
                    "vitaminPpMg",
                    "vitaminB5Mg",
                    "vitaminB6Mg",
                    "vitaminB9Mcg",
                    "vitaminB12Mcg",
                    "vitaminHMcg"
                  ],
                  "properties": {
                    "caloriesKcal": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "proteinG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "carbohydrateG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "fatG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "fiberG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "sodiumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "calciumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "ironMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "magnesiumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "phosphorusMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "potassiumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "zincMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "copperMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "manganeseMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "betaCaroteneMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminAMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminDMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminEMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminKMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminCMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB1Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB2Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminPpMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB5Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB6Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB9Mcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB12Mcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminHMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                },
                "mealItemGroups": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "name",
                      "order",
                      "ingredients",
                      "nutrition"
                    ],
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "order": {
                        "type": "integer"
                      },
                      "ingredients": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "ingredientName",
                            "foodCompositionId",
                            "estimatedGrams",
                            "userFacingUnit",
                            "cookingMethod",
                            "matchConfidence",
                            "nutrition"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "ingredientName": {
                              "type": "string"
                            },
                            "foodCompositionId": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "estimatedGrams": {
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "userFacingUnit": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "cookingMethod": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "matchConfidence": {
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "nutrition": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "caloriesKcal",
                                "proteinG",
                                "carbohydrateG",
                                "fatG",
                                "fiberG",
                                "sodiumMg",
                                "calciumMg",
                                "ironMg",
                                "magnesiumMg",
                                "phosphorusMg",
                                "potassiumMg",
                                "zincMg",
                                "copperMcg",
                                "manganeseMg",
                                "betaCaroteneMcg",
                                "vitaminAMcg",
                                "vitaminDMcg",
                                "vitaminEMg",
                                "vitaminKMcg",
                                "vitaminCMg",
                                "vitaminB1Mg",
                                "vitaminB2Mg",
                                "vitaminPpMg",
                                "vitaminB5Mg",
                                "vitaminB6Mg",
                                "vitaminB9Mcg",
                                "vitaminB12Mcg",
                                "vitaminHMcg"
                              ],
                              "properties": {
                                "caloriesKcal": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "proteinG": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "carbohydrateG": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "fatG": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "fiberG": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "sodiumMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "calciumMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "ironMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "magnesiumMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "phosphorusMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "potassiumMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "zincMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "copperMcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "manganeseMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "betaCaroteneMcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminAMcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminDMcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminEMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminKMcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminCMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminB1Mg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminB2Mg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminPpMg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminB5Mg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminB6Mg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminB9Mcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminB12Mcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "vitaminHMcg": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                }
                              }
                            }
                          }
                        }
                      },
                      "nutrition": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "caloriesKcal",
                          "proteinG",
                          "carbohydrateG",
                          "fatG",
                          "fiberG",
                          "sodiumMg",
                          "calciumMg",
                          "ironMg",
                          "magnesiumMg",
                          "phosphorusMg",
                          "potassiumMg",
                          "zincMg",
                          "copperMcg",
                          "manganeseMg",
                          "betaCaroteneMcg",
                          "vitaminAMcg",
                          "vitaminDMcg",
                          "vitaminEMg",
                          "vitaminKMcg",
                          "vitaminCMg",
                          "vitaminB1Mg",
                          "vitaminB2Mg",
                          "vitaminPpMg",
                          "vitaminB5Mg",
                          "vitaminB6Mg",
                          "vitaminB9Mcg",
                          "vitaminB12Mcg",
                          "vitaminHMcg"
                        ],
                        "properties": {
                          "caloriesKcal": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "proteinG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "carbohydrateG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "fatG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "fiberG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "sodiumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "calciumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "ironMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "magnesiumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "phosphorusMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "potassiumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "zincMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "copperMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "manganeseMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "betaCaroteneMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminAMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminDMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminEMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminKMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminCMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB1Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB2Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminPpMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB5Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB6Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB9Mcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB12Mcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminHMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "entryMode": {
                  "type": "string",
                  "enum": [
                    "precise",
                    "cheat"
                  ]
                },
                "alcoholG": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "cheatSliders": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "description": "Persisted cheat-mode slider specification and levels."
                },
                "share": {
                  "oneOf": [
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "shareId",
                        "visibility"
                      ],
                      "properties": {
                        "shareId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "visibility": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "portionFactor": {
                  "type": "number",
                  "minimum": 0
                }
              }
            }
          },
          "pendingConfirmations": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "rawInput",
                "loggedAt"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "rawInput": {
                  "type": "string"
                },
                "loggedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "parsedMeal": {
                  "type": "object",
                  "description": "Parsed precise-meal review payload."
                },
                "cheatSpec": {
                  "type": "object",
                  "description": "Cheat-mode slider review payload."
                }
              }
            }
          }
        }
      },
      "Meal": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "rawInput",
          "mealSlot",
          "confidenceOverall",
          "loggedAt",
          "nutrition",
          "mealItemGroups",
          "entryMode",
          "alcoholG",
          "cheatSliders",
          "share"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "rawInput": {
            "type": "string"
          },
          "mealSlot": {
            "type": [
              "string",
              "null"
            ]
          },
          "confidenceOverall": {
            "type": [
              "string",
              "null"
            ]
          },
          "loggedAt": {
            "type": "string",
            "format": "date-time"
          },
          "nutrition": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "caloriesKcal",
              "proteinG",
              "carbohydrateG",
              "fatG",
              "fiberG",
              "sodiumMg",
              "calciumMg",
              "ironMg",
              "magnesiumMg",
              "phosphorusMg",
              "potassiumMg",
              "zincMg",
              "copperMcg",
              "manganeseMg",
              "betaCaroteneMcg",
              "vitaminAMcg",
              "vitaminDMcg",
              "vitaminEMg",
              "vitaminKMcg",
              "vitaminCMg",
              "vitaminB1Mg",
              "vitaminB2Mg",
              "vitaminPpMg",
              "vitaminB5Mg",
              "vitaminB6Mg",
              "vitaminB9Mcg",
              "vitaminB12Mcg",
              "vitaminHMcg"
            ],
            "properties": {
              "caloriesKcal": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "proteinG": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "carbohydrateG": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "fatG": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "fiberG": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "sodiumMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "calciumMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "ironMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "magnesiumMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "phosphorusMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "potassiumMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "zincMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "copperMcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "manganeseMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "betaCaroteneMcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminAMcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminDMcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminEMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminKMcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminCMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminB1Mg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminB2Mg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminPpMg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminB5Mg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminB6Mg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminB9Mcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminB12Mcg": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vitaminHMcg": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "mealItemGroups": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "name",
                "order",
                "ingredients",
                "nutrition"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "order": {
                  "type": "integer"
                },
                "ingredients": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "id",
                      "ingredientName",
                      "foodCompositionId",
                      "estimatedGrams",
                      "userFacingUnit",
                      "cookingMethod",
                      "matchConfidence",
                      "nutrition"
                    ],
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "ingredientName": {
                        "type": "string"
                      },
                      "foodCompositionId": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "estimatedGrams": {
                        "type": [
                          "number",
                          "null"
                        ]
                      },
                      "userFacingUnit": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "cookingMethod": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "matchConfidence": {
                        "type": [
                          "number",
                          "null"
                        ]
                      },
                      "nutrition": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "caloriesKcal",
                          "proteinG",
                          "carbohydrateG",
                          "fatG",
                          "fiberG",
                          "sodiumMg",
                          "calciumMg",
                          "ironMg",
                          "magnesiumMg",
                          "phosphorusMg",
                          "potassiumMg",
                          "zincMg",
                          "copperMcg",
                          "manganeseMg",
                          "betaCaroteneMcg",
                          "vitaminAMcg",
                          "vitaminDMcg",
                          "vitaminEMg",
                          "vitaminKMcg",
                          "vitaminCMg",
                          "vitaminB1Mg",
                          "vitaminB2Mg",
                          "vitaminPpMg",
                          "vitaminB5Mg",
                          "vitaminB6Mg",
                          "vitaminB9Mcg",
                          "vitaminB12Mcg",
                          "vitaminHMcg"
                        ],
                        "properties": {
                          "caloriesKcal": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "proteinG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "carbohydrateG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "fatG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "fiberG": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "sodiumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "calciumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "ironMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "magnesiumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "phosphorusMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "potassiumMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "zincMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "copperMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "manganeseMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "betaCaroteneMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminAMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminDMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminEMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminKMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminCMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB1Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB2Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminPpMg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB5Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB6Mg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB9Mcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminB12Mcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "vitaminHMcg": {
                            "type": [
                              "number",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "nutrition": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "caloriesKcal",
                    "proteinG",
                    "carbohydrateG",
                    "fatG",
                    "fiberG",
                    "sodiumMg",
                    "calciumMg",
                    "ironMg",
                    "magnesiumMg",
                    "phosphorusMg",
                    "potassiumMg",
                    "zincMg",
                    "copperMcg",
                    "manganeseMg",
                    "betaCaroteneMcg",
                    "vitaminAMcg",
                    "vitaminDMcg",
                    "vitaminEMg",
                    "vitaminKMcg",
                    "vitaminCMg",
                    "vitaminB1Mg",
                    "vitaminB2Mg",
                    "vitaminPpMg",
                    "vitaminB5Mg",
                    "vitaminB6Mg",
                    "vitaminB9Mcg",
                    "vitaminB12Mcg",
                    "vitaminHMcg"
                  ],
                  "properties": {
                    "caloriesKcal": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "proteinG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "carbohydrateG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "fatG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "fiberG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "sodiumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "calciumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "ironMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "magnesiumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "phosphorusMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "potassiumMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "zincMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "copperMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "manganeseMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "betaCaroteneMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminAMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminDMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminEMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminKMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminCMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB1Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB2Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminPpMg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB5Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB6Mg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB9Mcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminB12Mcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "vitaminHMcg": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "entryMode": {
            "type": "string",
            "enum": [
              "precise",
              "cheat"
            ]
          },
          "alcoholG": {
            "type": [
              "number",
              "null"
            ]
          },
          "cheatSliders": {
            "type": [
              "object",
              "null"
            ],
            "description": "Persisted cheat-mode slider specification and levels."
          },
          "share": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "shareId",
                  "visibility"
                ],
                "properties": {
                  "shareId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "visibility": {
                    "type": "string"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "portionFactor": {
            "type": "number",
            "minimum": 0
          }
        }
      },
      "PendingMeal": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "rawInput",
          "loggedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "rawInput": {
            "type": "string"
          },
          "loggedAt": {
            "type": "string",
            "format": "date-time"
          },
          "parsedMeal": {
            "type": "object",
            "description": "Parsed precise-meal review payload."
          },
          "cheatSpec": {
            "type": "object",
            "description": "Cheat-mode slider review payload."
          }
        }
      },
      "RecentCheatOccasion": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mealId",
          "rawInput",
          "loggedAt"
        ],
        "properties": {
          "mealId": {
            "type": "string",
            "format": "uuid"
          },
          "rawInput": {
            "type": "string"
          },
          "loggedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RelogCandidates": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "dishes",
          "meals"
        ],
        "properties": {
          "dishes": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "kind",
                "sourceMealId",
                "mealItemOrder",
                "name",
                "ingredientCount",
                "occurrenceCount",
                "lastLoggedAt",
                "totalGrams",
                "caloriesKcal",
                "proteinG",
                "carbohydrateG",
                "fatG"
              ],
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "dish"
                  ]
                },
                "sourceMealId": {
                  "type": "string",
                  "format": "uuid"
                },
                "mealItemOrder": {
                  "type": "integer",
                  "minimum": 0
                },
                "name": {
                  "type": "string"
                },
                "ingredientCount": {
                  "type": "integer",
                  "minimum": 0
                },
                "occurrenceCount": {
                  "type": "integer",
                  "minimum": 1
                },
                "lastLoggedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "totalGrams": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "caloriesKcal": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "proteinG": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "carbohydrateG": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "fatG": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              }
            }
          },
          "meals": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "kind",
                "sourceMealId",
                "name",
                "dishCount",
                "occurrenceCount",
                "lastLoggedAt",
                "totalGrams",
                "caloriesKcal",
                "proteinG",
                "carbohydrateG",
                "fatG"
              ],
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "meal"
                  ]
                },
                "sourceMealId": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "dishCount": {
                  "type": "integer",
                  "minimum": 0
                },
                "occurrenceCount": {
                  "type": "integer",
                  "minimum": 1
                },
                "lastLoggedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "totalGrams": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "caloriesKcal": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "proteinG": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "carbohydrateG": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "fatG": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              }
            }
          }
        }
      },
      "StagedRelogAnalysis": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "analysisId",
          "parsedMeal",
          "rawInput",
          "loggedAt"
        ],
        "properties": {
          "analysisId": {
            "type": "string",
            "format": "uuid"
          },
          "parsedMeal": {
            "type": "object",
            "description": "Parsed precise-meal payload ready for user review."
          },
          "rawInput": {
            "type": "string"
          },
          "loggedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OnboardingProfile": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "userId",
          "onboardingStep"
        ],
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "weightKg": {
            "type": [
              "string",
              "null"
            ]
          },
          "heightCm": {
            "type": [
              "integer",
              "null"
            ]
          },
          "age": {
            "type": [
              "integer",
              "null"
            ]
          },
          "biologicalSex": {
            "type": [
              "string",
              "null"
            ]
          },
          "activityLevel": {
            "type": [
              "string",
              "null"
            ]
          },
          "tdeeKcal": {
            "type": [
              "integer",
              "null"
            ]
          },
          "goal": {
            "type": [
              "string",
              "null"
            ]
          },
          "aggression": {
            "type": [
              "string",
              "null"
            ]
          },
          "carbSplit": {
            "type": [
              "string",
              "null"
            ]
          },
          "calorieTarget": {
            "type": [
              "integer",
              "null"
            ]
          },
          "proteinTargetG": {
            "type": [
              "integer",
              "null"
            ]
          },
          "carbsTargetG": {
            "type": [
              "integer",
              "null"
            ]
          },
          "fatTargetG": {
            "type": [
              "integer",
              "null"
            ]
          },
          "countryOfOrigin": {
            "type": [
              "string",
              "null"
            ]
          },
          "countryOfResidence": {
            "type": [
              "string",
              "null"
            ]
          },
          "preferredLocale": {
            "type": [
              "string",
              "null"
            ]
          },
          "oilUsage": {
            "type": [
              "string",
              "null"
            ]
          },
          "defaultRicePortion": {
            "type": [
              "string",
              "null"
            ]
          },
          "sugarBraised": {
            "type": [
              "string",
              "null"
            ]
          },
          "defaultProteinPortion": {
            "type": [
              "string",
              "null"
            ]
          },
          "brothConsumption": {
            "type": [
              "string",
              "null"
            ]
          },
          "onboardingStep": {
            "type": "integer"
          },
          "onboardingCompletedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "onboardingMinimizedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "NutritionOverview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "requestedRange",
          "resolvedRange",
          "bucketTimezone",
          "loggedDays",
          "completeDays",
          "partialDays",
          "loggedDaysLast30",
          "trendStatus",
          "period",
          "summary",
          "calorieAverages",
          "previousCalorieAverages",
          "macros",
          "daySeries",
          "micronutrients",
          "spotlight",
          "steady",
          "moreNutrients",
          "educationCards"
        ],
        "properties": {
          "requestedRange": {
            "type": "string",
            "enum": [
              "auto",
              "1d",
              "7d",
              "30d",
              "90d"
            ]
          },
          "resolvedRange": {
            "type": "string",
            "enum": [
              "1d",
              "7d",
              "30d",
              "90d"
            ]
          },
          "bucketTimezone": {
            "type": "string",
            "enum": [
              "local",
              "utc"
            ]
          },
          "loggedDays": {
            "type": "integer",
            "minimum": 0
          },
          "completeDays": {
            "type": "integer",
            "minimum": 0
          },
          "partialDays": {
            "type": "integer",
            "minimum": 0
          },
          "loggedDaysLast30": {
            "type": "integer",
            "minimum": 0
          },
          "trendStatus": {
            "type": "string",
            "enum": [
              "ready",
              "too_few_logged_days"
            ]
          },
          "period": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "startDate",
              "endDate"
            ],
            "properties": {
              "startDate": {
                "type": "string",
                "format": "date"
              },
              "endDate": {
                "type": "string",
                "format": "date"
              }
            }
          },
          "summary": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "mostConsistent",
              "needsAttention",
              "limitedDataCount",
              "macroConsistency"
            ],
            "properties": {
              "mostConsistent": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "needsAttention": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "limitedDataCount": {
                "type": "integer",
                "minimum": 0
              },
              "macroConsistency": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "averageConsistencyPct",
                  "weakestMacro"
                ],
                "properties": {
                  "averageConsistencyPct": {
                    "type": "number"
                  },
                  "weakestMacro": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "calories",
                      "protein",
                      "carbohydrate",
                      "fat",
                      null
                    ]
                  }
                }
              }
            }
          },
          "calorieAverages": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "all",
              "complete"
            ],
            "properties": {
              "all": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "averagePerDay",
                  "days"
                ],
                "properties": {
                  "averagePerDay": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              },
              "complete": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "averagePerDay",
                  "days"
                ],
                "properties": {
                  "averagePerDay": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          },
          "previousCalorieAverages": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "all",
              "complete"
            ],
            "properties": {
              "all": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "averagePerDay",
                  "days"
                ],
                "properties": {
                  "averagePerDay": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              },
              "complete": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "averagePerDay",
                  "days"
                ],
                "properties": {
                  "averagePerDay": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          },
          "macros": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "daySeries": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "unit",
              "series"
            ],
            "properties": {
              "unit": {
                "type": "string",
                "enum": [
                  "day",
                  "week"
                ]
              },
              "series": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            }
          },
          "micronutrients": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "spotlight": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "steady": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "moreNutrients": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "educationCards": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "Entitlements": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "userId",
          "purchasesEnabled",
          "tier",
          "reconciliationRequired",
          "isLifetime",
          "expiresAt",
          "willRenew",
          "source",
          "store",
          "managementUrl",
          "managementStore",
          "hasActiveSubscription",
          "trial",
          "features"
        ],
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "purchasesEnabled": {
            "type": "boolean"
          },
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "premium"
            ]
          },
          "reconciliationRequired": {
            "type": "boolean"
          },
          "isLifetime": {
            "type": "boolean"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "willRenew": {
            "type": "boolean"
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "store": {
            "type": [
              "string",
              "null"
            ]
          },
          "managementUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "managementStore": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasActiveSubscription": {
            "type": "boolean"
          },
          "trial": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "active",
              "endsAt",
              "daysRemaining"
            ],
            "properties": {
              "active": {
                "type": "boolean"
              },
              "endsAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "daysRemaining": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "features": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "ai_analysis"
            ],
            "properties": {
              "ai_analysis": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "allowed",
                  "reason"
                ],
                "properties": {
                  "allowed": {
                    "type": "boolean"
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "entitled",
                      "trial",
                      "trial_expired",
                      "not_entitled"
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "ChatGroup": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "kind",
              "title",
              "avatarSeed",
              "updatedAt",
              "lastMessagePreview",
              "lastMessageAt",
              "unread",
              "lastMealSharedAt"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "direct",
                  "group"
                ]
              },
              "title": {
                "type": "string"
              },
              "avatarSeed": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time"
              },
              "lastMessagePreview": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "lastMessageAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "unread": {
                "type": "boolean"
              },
              "lastMealSharedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "kind",
              "name",
              "members",
              "myRole"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "direct",
                  "group"
                ]
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "members": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "userId",
                    "handle",
                    "displayName",
                    "avatarSeed",
                    "avatarUrl",
                    "hasCustomAvatar",
                    "role"
                  ],
                  "properties": {
                    "userId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "handle": {
                      "type": "string"
                    },
                    "displayName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "avatarSeed": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "avatarUrl": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uri"
                    },
                    "hasCustomAvatar": {
                      "type": "boolean"
                    },
                    "role": {
                      "type": "string"
                    }
                  }
                }
              },
              "myRole": {
                "type": "string",
                "enum": [
                  "owner",
                  "member"
                ]
              }
            }
          }
        ]
      },
      "Feed": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "entries",
          "nextCursor"
        ],
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "friend",
                "isSelf",
                "meal",
                "reactions",
                "replies",
                "repliesTotal"
              ],
              "properties": {
                "friend": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "userId",
                    "handle",
                    "displayName",
                    "avatarSeed",
                    "avatarUrl",
                    "hasCustomAvatar"
                  ],
                  "properties": {
                    "userId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "handle": {
                      "type": "string"
                    },
                    "displayName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "avatarSeed": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "avatarUrl": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uri"
                    },
                    "hasCustomAvatar": {
                      "type": "boolean"
                    }
                  }
                },
                "isSelf": {
                  "type": "boolean"
                },
                "meal": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "mealId",
                    "shareId",
                    "rawInput",
                    "caloriesKcal",
                    "proteinG",
                    "carbohydrateG",
                    "fatG",
                    "portionFactor",
                    "sharedAt",
                    "isBackfilled"
                  ],
                  "properties": {
                    "mealId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "shareId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "rawInput": {
                      "type": "string"
                    },
                    "caloriesKcal": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "proteinG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "carbohydrateG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "fatG": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "portionFactor": {
                      "type": "number"
                    },
                    "sharedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "isBackfilled": {
                      "type": "boolean"
                    }
                  }
                },
                "reactions": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "count",
                    "mine"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "mine": {
                      "type": "boolean"
                    }
                  }
                },
                "replies": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                },
                "repliesTotal": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Acknowledgement": {
        "type": "object",
        "additionalProperties": false,
        "required": [],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "ok": {
            "type": "boolean"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "mealId": {
            "type": "string",
            "format": "uuid"
          },
          "analysisId": {
            "type": "string",
            "format": "uuid"
          },
          "path": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "added": {
            "type": "integer"
          },
          "removed": {
            "type": "boolean"
          },
          "left": {
            "type": "boolean"
          },
          "lastReadAt": {
            "type": "string",
            "format": "date-time"
          },
          "autoShareToCircle": {
            "type": "boolean"
          },
          "data": {
            "type": "object"
          }
        }
      },
      "MealList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/Meal"
        },
        "description": "Meals for the requested day."
      }
    }
  },
  "security": [],
  "paths": {
    "/api/healthz": {
      "get": {
        "operationId": "getHealth",
        "summary": "Service health",
        "description": "Liveness probe. Returns 200 when the service is up and the database invariants it depends on hold, 503 otherwise. Safe to poll; no authentication.",
        "tags": [
          "Public"
        ],
        "responses": {
          "200": {
            "description": "All checks passed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthCheck"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/api/v1/waitlist": {
      "post": {
        "operationId": "joinWaitlist",
        "summary": "Join the launch waitlist",
        "description": "Registers an email address for the mobile launch announcement and sends a confirmation link. Rate limited per IP address.",
        "tags": [
          "Public"
        ],
        "requestBody": {
          "required": true,
          "description": "The address to add, and optionally where the signup came from.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "maxLength": 254,
                    "format": "email",
                    "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "locale": {
                    "type": "string",
                    "enum": [
                      "en",
                      "vi"
                    ]
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "hero",
                      "cta"
                    ]
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted. The response is identical for a new, pending, or already-confirmed address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WaitlistSignupResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/api/v1/waitlist/confirm": {
      "get": {
        "operationId": "confirmWaitlist",
        "summary": "Confirm a waitlist signup",
        "description": "The target of the emailed confirmation link. Always redirects to the landing page with `?waitlist=<confirmed|already|expired|invalid>`; it never returns a body.",
        "tags": [
          "Public"
        ],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The single-use token from the confirmation email.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "307": {
            "description": "Redirect to `/{locale}/?waitlist=<status>`."
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/api/v1/groups/invite/{slug}": {
      "get": {
        "operationId": "getInvitePreview",
        "summary": "Preview a friend-invite link",
        "description": "Resolves an invite slug to the person who owns it. Callable signed out, in which case `signedOut` is true and `status` is `none`. A blocked relationship returns the same 404 as an invalid slug, so the response can never be used to detect a block.",
        "tags": [
          "Public",
          "Circle"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "The invite slug from the shared link.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The inviter, and the viewer’s relationship to them.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitePreview"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/api/v1/meals": {
      "get": {
        "operationId": "listMeals",
        "summary": "List a day’s meals",
        "description": "Every meal logged on one calendar day, with its items and macros.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "The calendar day to read, `YYYY-MM-DD`, in the user's own timezone.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MealList"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/{mealId}": {
      "patch": {
        "operationId": "updateMeal",
        "summary": "Edit a logged meal",
        "description": "Adjusts the grams of individual items, or removes them. Nutrition is recomputed server-side from composition data — the client never sends calorie or macro figures.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "mealId",
            "in": "path",
            "required": true,
            "description": "UUID of the meal to edit.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "edits": {
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "newGrams": {
                          "type": "number",
                          "exclusiveMinimum": 0,
                          "maximum": 100000
                        }
                      },
                      "required": [
                        "id",
                        "newGrams"
                      ]
                    }
                  },
                  "removeIds": {
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "delete": {
        "operationId": "deleteMeal",
        "summary": "Delete a logged meal",
        "description": "Removes the meal and every item under it. Not reversible.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "mealId",
            "in": "path",
            "required": true,
            "description": "UUID of the meal to delete.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/{mealId}/duplicate": {
      "post": {
        "operationId": "duplicateMeal",
        "summary": "Copy a meal to another day",
        "description": "Copies an existing meal, items and all, onto the given date. `newMealId` is a client-generated UUID so an optimistic card and the persisted row share a key.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "mealId",
            "in": "path",
            "required": true,
            "description": "UUID of the meal to copy.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "newMealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  }
                },
                "required": [
                  "loggedDate",
                  "timezoneOffset"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new meal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/confirm": {
      "post": {
        "operationId": "confirmMeal",
        "summary": "Persist an analysed meal",
        "description": "Turns a staged analysis into a saved meal. This is the write step of the describe-a-meal flow: `POST /api/analyze-meal` produces the estimate, the user corrects it, and this commits it.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "analysisId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "mealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "edits": {
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "mealItemOrder": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "ingredientIndex": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "newGrams": {
                          "type": "number",
                          "exclusiveMinimum": 0,
                          "maximum": 100000
                        }
                      },
                      "required": [
                        "mealItemOrder",
                        "newGrams"
                      ]
                    }
                  },
                  "levels": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "enum": [
                        "protein",
                        "carbs",
                        "fat",
                        "drinks"
                      ]
                    },
                    "additionalProperties": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 10
                    }
                  }
                },
                "required": [
                  "analysisId"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/manual": {
      "post": {
        "operationId": "logMealManually",
        "summary": "Log a meal from ingredient ids and grams",
        "description": "Deterministic logging with no AI in the path: the client sends food-composition ids and gram weights, the server computes nutrition from per-100g data and saves the meal. Use this when the caller already knows exactly what was eaten.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "items": {
                    "minItems": 1,
                    "maxItems": 30,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "foodCompositionId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 120
                        },
                        "grams": {
                          "type": "number",
                          "exclusiveMinimum": 0,
                          "maximum": 5000
                        },
                        "label": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        }
                      },
                      "required": [
                        "foodCompositionId",
                        "grams"
                      ]
                    }
                  },
                  "mealSlot": {
                    "type": "string",
                    "enum": [
                      "breakfast",
                      "lunch",
                      "snack",
                      "dinner"
                    ]
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  }
                },
                "required": [
                  "items",
                  "loggedDate",
                  "timezoneOffset"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/dates": {
      "get": {
        "operationId": "listLoggedDates",
        "summary": "Dates that have any meal logged",
        "description": "Backs the calendar picker: which days have data to show.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "format": "date"
                  },
                  "description": "`YYYY-MM-DD`, ascending."
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/pending": {
      "get": {
        "operationId": "listPendingMeals",
        "summary": "Analyses awaiting confirmation",
        "description": "Meals that were analysed but never confirmed — the review cards a client restores after a reload or an app switch.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "The calendar day to read, `YYYY-MM-DD`, in the user's own timezone.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PendingMeal"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/cheat-occasions": {
      "get": {
        "operationId": "listCheatOccasions",
        "summary": "Recent cheat-mode occasions",
        "description": "Past cheat-mode entries, most recent first, so one can be repeated without re-describing it.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many occasions to return. Default 12.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RecentCheatOccasion"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/cheat-repeat": {
      "post": {
        "operationId": "repeatCheatOccasion",
        "summary": "Repeat a cheat-mode entry",
        "description": "Logs a previous cheat occasion again on a new date. For meals that cannot be itemised — a buffet, a barbecue, a box of pastries.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sourceMealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  }
                },
                "required": [
                  "sourceMealId",
                  "loggedDate",
                  "timezoneOffset"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/relog": {
      "post": {
        "operationId": "relogMeals",
        "summary": "Re-log past dishes or meals",
        "description": "Every entry is a reference, never a payload: no names, grams or nutrition cross the wire. The server re-resolves each reference against the caller’s own rows, so a stale or tampered client can only ever point at its own data.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "newMealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "items": {
                    "minItems": 1,
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "kind": {
                              "type": "string",
                              "const": "dish"
                            },
                            "sourceMealId": {
                              "type": "string",
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                            },
                            "mealItemOrder": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 10000
                            }
                          },
                          "required": [
                            "kind",
                            "sourceMealId",
                            "mealItemOrder"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "kind": {
                              "type": "string",
                              "const": "meal"
                            },
                            "sourceMealId": {
                              "type": "string",
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                            }
                          },
                          "required": [
                            "kind",
                            "sourceMealId"
                          ]
                        }
                      ]
                    }
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  }
                },
                "required": [
                  "items",
                  "loggedDate",
                  "timezoneOffset"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/relog/stage": {
      "post": {
        "operationId": "stageRelog",
        "summary": "Stage a re-log for review",
        "description": "Like `relogMeals`, but stages the picks as a pending analysis so they land in the same editable review card an AI-analysed meal does, instead of being written immediately. `attemptId` is required — it is the upsert key that stops repeated staging accumulating rows.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "minItems": 1,
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "kind": {
                              "type": "string",
                              "const": "dish"
                            },
                            "sourceMealId": {
                              "type": "string",
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                            },
                            "mealItemOrder": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 10000
                            }
                          },
                          "required": [
                            "kind",
                            "sourceMealId",
                            "mealItemOrder"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "kind": {
                              "type": "string",
                              "const": "meal"
                            },
                            "sourceMealId": {
                              "type": "string",
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                            }
                          },
                          "required": [
                            "kind",
                            "sourceMealId"
                          ]
                        }
                      ]
                    }
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  },
                  "attemptId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "items",
                  "loggedDate",
                  "timezoneOffset",
                  "attemptId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The staged pending analysis.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StagedRelogAnalysis"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/meals/relog/candidates": {
      "get": {
        "operationId": "searchRelogCandidates",
        "summary": "Search past dishes and meals to re-log",
        "description": "Backs the slash-picker. An empty `q` returns the caller’s top dishes and meals by a frequency-and-recency score, so there is no separate \"recents\" endpoint. Queries are normalised to NFC because Vietnamese typed through Telex or VNI arrives decomposed.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Meals"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search text. Empty or omitted returns the top candidates.",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many candidates to return. Default 8.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching dish and meal candidates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RelogCandidates"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/logging/day": {
      "get": {
        "operationId": "getLoggingDay",
        "summary": "One day of logging",
        "description": "Meals, totals and targets for a single calendar day — everything the logging screen renders in one request.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Logging"
        ],
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "The calendar day to read, `YYYY-MM-DD`, in the user's own timezone.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoggingDay"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/ingredients/search": {
      "get": {
        "operationId": "searchIngredients",
        "summary": "Search the food-composition tables",
        "description": "Full-text search over the reference data behind every estimate: the Vietnam National Food Composition Table 2007, plus FAO and USDA. Results are per-100g composition rows, not user data. This is the lookup step of manual logging.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Logging",
          "Reference data"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search text. Vietnamese diacritics are significant and are not stripped.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many matches to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngredientSearchResults"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/barcode/search": {
      "get": {
        "operationId": "searchBarcode",
        "summary": "Look up a packaged product by barcode",
        "description": "Resolves a scanned barcode to a product and its label figures. Returns 404 when the code is not in the database — nothing is invented for an unknown product.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Logging"
        ],
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": true,
            "description": "The barcode digits as scanned (EAN-8, EAN-13 or UPC-A).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matched product and its per-serving nutrition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/barcode/log": {
      "post": {
        "operationId": "logBarcodeMeal",
        "summary": "Log a scanned product",
        "description": "Saves a barcode match as a meal. Figures come straight from the product label, so no estimation is involved.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Logging"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "barcode": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^\\d+$"
                  },
                  "grams": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 100000
                  },
                  "mealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  }
                },
                "required": [
                  "barcode",
                  "grams",
                  "loggedDate",
                  "timezoneOffset"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/nutrition/overview": {
      "get": {
        "operationId": "getNutritionOverview",
        "summary": "Micronutrient intake over a range",
        "description": "Per-nutrient intake against the reference target, with the data-coverage figure behind each one — the share of logged grams that had a value for that nutrient. A high intake on low coverage is not a high intake, and the payload says so rather than hiding it.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Nutrition"
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": true,
            "description": "`auto` picks the widest range with enough data. The rest are fixed windows.",
            "schema": {
              "type": "string",
              "enum": [
                "auto",
                "7d",
                "30d",
                "90d"
              ]
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Which days count toward the averages. `complete` uses only fully logged days; `all` uses every day in the range.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "complete"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NutritionOverview"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/nutrition/candidates": {
      "post": {
        "operationId": "getNutrientFoodSources",
        "summary": "Foods that supply a given nutrient",
        "description": "Suggests foods high in one nutrient, drawn from the composition tables, with the per-100g amount for each. Answers \"what should I eat more of\" without inventing a recommendation.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Nutrition",
          "Reference data"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nutrient": {
                    "type": "string",
                    "enum": [
                      "calciumMg",
                      "ironMg",
                      "vitaminCMg",
                      "phosphorusMg",
                      "vitaminB1Mg",
                      "vitaminB2Mg",
                      "vitaminPpMg",
                      "vitaminAMcg",
                      "sodiumMg",
                      "magnesiumMg",
                      "potassiumMg",
                      "zincMg",
                      "copperMcg",
                      "manganeseMg",
                      "vitaminB12Mcg",
                      "vitaminB9Mcg",
                      "vitaminB5Mg",
                      "vitaminB6Mg",
                      "vitaminEMg",
                      "vitaminKMcg"
                    ]
                  }
                },
                "required": [
                  "nutrient"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Candidate foods, each with its per-100g amount and unit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/nutrition-label/scan": {
      "post": {
        "operationId": "scanNutritionLabel",
        "summary": "Read a nutrition label from an image",
        "description": "OCR over a photographed nutrition label. Read-only: it returns what it read and writes nothing. Returns 422 with `OCR_NO_LABEL_DETECTED` when the image contains no label it can parse — which is a normal outcome, not an error to retry blindly.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Nutrition"
        ],
        "requestBody": {
          "required": true,
          "description": "Base64-encoded image bytes.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "imageBase64": {
                    "type": "string",
                    "minLength": 1
                  },
                  "mimeType": {
                    "type": "string",
                    "enum": [
                      "image/jpeg",
                      "image/png",
                      "image/webp"
                    ]
                  }
                },
                "required": [
                  "imageBase64",
                  "mimeType"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The parsed label figures.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/nutrition-label/log": {
      "post": {
        "operationId": "logNutritionLabelMeal",
        "summary": "Log a meal from scanned label figures",
        "description": "Saves the result of a label scan — after the user has confirmed or corrected it — as a meal.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Nutrition"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "productName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "amount": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 100000
                  },
                  "unit": {
                    "type": "string",
                    "enum": [
                      "g",
                      "ml",
                      "serving"
                    ]
                  },
                  "confidence": {
                    "type": "string",
                    "enum": [
                      "high",
                      "medium",
                      "low"
                    ]
                  },
                  "calories": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 20000
                  },
                  "proteinGrams": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5000
                  },
                  "carbsGrams": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5000
                  },
                  "fatGrams": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5000
                  },
                  "fiberGrams": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 2000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in grams; null when not printed on the label"
                  },
                  "sodiumMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 50000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "calciumMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 20000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "ironMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "magnesiumMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 20000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "phosphorusMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 20000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "potassiumMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 30000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "zincMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "copperMcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "manganeseMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "betaCaroteneMcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "vitaminAMcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "vitaminCMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 20000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminDMcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 10000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "vitaminEMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 10000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminKMcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "vitaminB1Mg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminB2Mg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminPpMg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 5000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminB5Mg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminB6Mg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in milligrams; null when not printed on the label"
                  },
                  "vitaminB9Mcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "vitaminB12Mcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "vitaminHMcg": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Absolute amount in micrograms; null when not printed on the label"
                  },
                  "mealId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "minimum": -840,
                    "maximum": 720
                  }
                },
                "required": [
                  "productName",
                  "amount",
                  "unit",
                  "confidence",
                  "calories",
                  "proteinGrams",
                  "carbsGrams",
                  "fatGrams",
                  "loggedDate",
                  "timezoneOffset"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/dashboard": {
      "get": {
        "operationId": "getDashboard",
        "summary": "The whole dashboard in one request",
        "description": "Collapses four calls — profile, day, weight summary, adherence heatmap — into one round-trip. Each slice is byte-identical to its standalone endpoint, so a client can seed four caches from this one response. Ranges are fixed to what the dashboard renders: weight 30 days, heatmap 90.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Tracking"
        ],
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "The calendar day to read, `YYYY-MM-DD`, in the user's own timezone.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardBundle"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/dashboard/heatmap": {
      "get": {
        "operationId": "getAdherenceHeatmap",
        "summary": "Calorie-adherence grid",
        "description": "One cell per day: whether it was logged, and how close intake came to the target. Under-logged days are marked `partial` and carry a null `ratio` rather than being graded as poor adherence — a day you forgot to log is not a day you overate.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Tracking"
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": true,
            "description": "Window to render.",
            "schema": {
              "type": "string",
              "enum": [
                "30d",
                "90d",
                "year"
              ]
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Heatmap"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/weight": {
      "post": {
        "operationId": "logWeight",
        "summary": "Log a weight",
        "description": "Records a weight for a date. Logging the same date twice replaces the earlier value rather than adding a second one.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Tracking"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "loggedDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "weightKg": {
                    "type": "number",
                    "minimum": 30,
                    "maximum": 300
                  }
                },
                "required": [
                  "loggedDate",
                  "weightKg"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The refreshed summary, so a client need not re-fetch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WeightSummary"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/weight/{loggedDate}": {
      "delete": {
        "operationId": "deleteWeight",
        "summary": "Delete a logged weight",
        "description": "Removes the weight entry for one date.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Tracking"
        ],
        "parameters": [
          {
            "name": "loggedDate",
            "in": "path",
            "required": true,
            "description": "The date to clear, `YYYY-MM-DD`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/weight/summary": {
      "get": {
        "operationId": "getWeightSummary",
        "summary": "Weight trend over a range",
        "description": "The weight series plus the trend the clients draw. The projection is computed server-side so web and mobile never disagree about the forecast, and `canProject` is false when there is too little data for it to mean anything.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Tracking"
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": true,
            "description": "Window. Note this is narrower than the heatmap range — no `year`.",
            "schema": {
              "type": "string",
              "enum": [
                "30d",
                "90d"
              ]
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as JavaScript's `Date.getTimezoneOffset()` reports it (UTC minus local). Omit to use the stored profile timezone.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WeightSummary"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups": {
      "get": {
        "operationId": "listChatGroups",
        "summary": "Groups the caller belongs to",
        "description": "Every group the caller is a member of, with unread state.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "timezoneOffset",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as `Date.getTimezoneOffset()` reports it. Decides which meals fall on which day in the feed.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChatGroup"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "post": {
        "operationId": "createChatGroup",
        "summary": "Create a group",
        "description": "Creates a group with the caller as its first member.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Display name."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatGroup"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups/{groupId}": {
      "get": {
        "operationId": "getChatGroup",
        "summary": "One group",
        "description": "The group and its members. 404 if the caller is not a member.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatGroup"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "patch": {
        "operationId": "updateChatGroup",
        "summary": "Rename a group",
        "description": "Changes the group’s display name.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "New display name."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatGroup"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups/{groupId}/members": {
      "post": {
        "operationId": "addChatGroupMember",
        "summary": "Add someone to a group",
        "description": "Adds an existing friend to the group.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Who to add."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups/{groupId}/members/{userId}": {
      "delete": {
        "operationId": "removeChatGroupMember",
        "summary": "Remove someone from a group",
        "description": "Removes a member. Use `leaveChatGroup` to remove yourself.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "description": "UUID of the member to remove.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups/{groupId}/messages": {
      "get": {
        "operationId": "listChatGroupMessages",
        "summary": "Messages in a group",
        "description": "The group’s messages, newest last.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Acknowledgement"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "post": {
        "operationId": "sendChatGroupMessage",
        "summary": "Post a message",
        "description": "Sends a text message to the group.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string",
                    "description": "Message text."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups/{groupId}/feed": {
      "get": {
        "operationId": "getChatGroupFeed",
        "summary": "Meals shared into a group",
        "description": "A page of meals shared into this group, newest first.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Cursor: return items older than this one. Omit for the newest page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Feed"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/chat-groups/{groupId}/leave": {
      "delete": {
        "operationId": "leaveChatGroup",
        "summary": "Leave a group",
        "description": "Removes the caller from the group.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "UUID of the chat group.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/feed": {
      "get": {
        "operationId": "getCircleFeed",
        "summary": "The whole circle feed",
        "description": "Meals shared by everyone the caller is connected to, across friends and groups.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "timezoneOffset",
            "in": "query",
            "required": false,
            "description": "Timezone offset in minutes, as `Date.getTimezoneOffset()` reports it. Decides which meals fall on which day in the feed.",
            "schema": {
              "type": "integer",
              "minimum": -840,
              "maximum": 840
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Feed"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/friends": {
      "get": {
        "operationId": "listFriends",
        "summary": "People the caller is connected to",
        "description": "Accepted connections only. Blocked edges are not listed.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicProfile"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/friends/feed": {
      "get": {
        "operationId": "getFriendsFeed",
        "summary": "Meals shared by friends",
        "description": "A page of meals from connected people, newest first.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "parameters": [
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Cursor: return items older than this one. Omit for the newest page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Feed"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/friends/read-marker": {
      "get": {
        "operationId": "getFriendsFeedReadMarker",
        "summary": "How far the caller has read the friends feed",
        "description": "Backs the unread badge without downloading the feed itself.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/friends/block": {
      "post": {
        "operationId": "blockFriend",
        "summary": "Block someone",
        "description": "Blocks a connection. Afterwards their invite link resolves for the caller exactly as an invalid slug does, so the block is never observable from the other side.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetUserId"
                ],
                "properties": {
                  "targetUserId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The other person in the connection."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/friends/remove": {
      "delete": {
        "operationId": "removeFriend",
        "summary": "Disconnect from someone",
        "description": "Deletes the connection. Unlike a block, either side can re-invite the other afterwards.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetUserId"
                ],
                "properties": {
                  "targetUserId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The other person in the connection."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/invite/accept": {
      "post": {
        "operationId": "acceptFriendInvite",
        "summary": "Accept a friend-invite link",
        "description": "Connects the caller to whoever owns the slug.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "slug"
                ],
                "properties": {
                  "slug": {
                    "type": "string",
                    "description": "The invite slug."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/invites": {
      "get": {
        "operationId": "listMealShareInvites",
        "summary": "Pending meal-split invites",
        "description": "Invitations to log your own share of a meal someone else logged — the split flow, not the friend flow.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Acknowledgement"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/invites/accept": {
      "post": {
        "operationId": "acceptMealShareInvite",
        "summary": "Accept a meal-split invite",
        "description": "Logs the caller’s share of the shared meal onto the given date, as their own meal.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "inviteId"
                ],
                "properties": {
                  "inviteId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The invite to act on."
                  },
                  "newMealId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Client-generated id for the meal that will be created."
                  },
                  "loggedDate": {
                    "type": "string",
                    "format": "date",
                    "description": "Which day to log it on."
                  },
                  "timezoneOffset": {
                    "type": "integer",
                    "description": "Caller timezone offset in minutes."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/invites/dismiss": {
      "post": {
        "operationId": "dismissMealShareInvite",
        "summary": "Dismiss a meal-split invite",
        "description": "Declines the invite without logging anything.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "inviteId"
                ],
                "properties": {
                  "inviteId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The invite to act on."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/shares": {
      "post": {
        "operationId": "setMealVisibility",
        "summary": "Share or unshare a meal",
        "description": "Flips one meal between `private` and `circle`. The default for new meals is set separately by `updateSharingPreference`.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mealId",
                  "visibility"
                ],
                "properties": {
                  "mealId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The meal to change."
                  },
                  "visibility": {
                    "type": "string",
                    "enum": [
                      "private",
                      "circle"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/shares/log": {
      "post": {
        "operationId": "logSharedMeal",
        "summary": "Copy or split a friend’s meal",
        "description": "Logs someone else’s shared meal as your own. `factor` is 1 to copy the whole thing or 0.5 to take half — the case where two people ate one dish.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "shareId",
                  "factor",
                  "loggedDate",
                  "timezoneOffset"
                ],
                "properties": {
                  "shareId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The shared meal."
                  },
                  "factor": {
                    "type": "number",
                    "enum": [
                      1,
                      0.5
                    ],
                    "description": "1 copies the meal, 0.5 takes half of it."
                  },
                  "loggedDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "timezoneOffset": {
                    "type": "integer"
                  },
                  "newMealId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Client-generated id for the meal that will be created."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Meal"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/shares/reaction": {
      "post": {
        "operationId": "toggleShareReaction",
        "summary": "React to a shared meal",
        "description": "Toggles the caller’s reaction on or off. There is one reaction type.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "shareId"
                ],
                "properties": {
                  "shareId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The shared meal."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/shares/reply": {
      "post": {
        "operationId": "replyToShare",
        "summary": "Comment on a shared meal",
        "description": "Adds a reply, optionally threaded under an existing one.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "shareId",
                  "body"
                ],
                "properties": {
                  "shareId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The shared meal."
                  },
                  "body": {
                    "type": "string",
                    "description": "Reply text."
                  },
                  "replyId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Reply to thread this one under."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/meal-share": {
      "post": {
        "operationId": "shareMealWithFriends",
        "summary": "Send a meal to specific friends",
        "description": "`copy` sends the meal for them to log as-is. `split` sends an invite for each recipient to log exactly their own portion of it — the shared-dish case.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mealId",
                  "friendUserIds",
                  "mode"
                ],
                "properties": {
                  "mealId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "friendUserIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Recipients. Must be accepted connections."
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "copy",
                      "split"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/profile": {
      "get": {
        "operationId": "getMyPublicProfile",
        "summary": "The caller’s public profile",
        "description": "Name, avatar and invite link. A shareable link is provisioned on first access, so this always returns a profile — there is no claim step.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "$ref": "#/components/schemas/PublicProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "post": {
        "operationId": "updateMyPublicProfile",
        "summary": "Change the invite handle or display name",
        "description": "Changing the handle changes the invite link, so links already shared stop resolving.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "handle"
                ],
                "properties": {
                  "handle": {
                    "type": "string",
                    "description": "The editable end of the invite link."
                  },
                  "displayName": {
                    "type": "string"
                  },
                  "avatarSeed": {
                    "type": "string",
                    "description": "Seed for the generated avatar."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "$ref": "#/components/schemas/PublicProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/profile/name": {
      "post": {
        "operationId": "renameMyPublicProfile",
        "summary": "Rename yourself",
        "description": "Sets the display name and re-derives the invite handle from it — so outstanding invite links change, exactly as they do when the handle is edited directly.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "displayName"
                ],
                "properties": {
                  "displayName": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "$ref": "#/components/schemas/PublicProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/groups/profile/avatar": {
      "post": {
        "operationId": "uploadAvatar",
        "summary": "Upload an avatar photo",
        "description": "Multipart upload with a single `file` field, under 5 MB. The upload goes through the caller’s own storage session so row-level security applies to it.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The avatar image, under 5 MB."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "$ref": "#/components/schemas/PublicProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "delete": {
        "operationId": "deleteAvatar",
        "summary": "Remove the avatar photo",
        "description": "Falls back to the generated avatar.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Circle"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "$ref": "#/components/schemas/PublicProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/account": {
      "get": {
        "operationId": "exportAccount",
        "summary": "Export everything stored about the caller",
        "description": "The full data export: profile, meals, weights, and circle activity. This is the machine-readable half of the data rights described in the privacy policy.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "The complete export document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      },
      "delete": {
        "operationId": "deleteAccount",
        "summary": "Delete the account",
        "description": "Schedules deletion of the account and everything under it. Irreversible once it runs; an hourly job completes any that fail on the first attempt.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/account/entitlements": {
      "get": {
        "operationId": "getEntitlements",
        "summary": "Which paid features the caller has",
        "description": "The current entitlement state and where it came from. Read this rather than inferring a plan from a purchase receipt.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account",
          "Billing"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entitlements"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/account/entitlements/reconcile": {
      "post": {
        "operationId": "reconcileEntitlements",
        "summary": "Re-sync entitlements with the billing provider",
        "description": "Forces a refresh against the billing provider. For the case where a webhook was missed and the stored state has fallen behind a purchase the user already made.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account",
          "Billing"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entitlements"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/account/billing-config": {
      "get": {
        "operationId": "getBillingConfig",
        "summary": "Client billing configuration",
        "description": "The publishable keys and product identifiers a client needs to open checkout. Contains no secrets.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account",
          "Billing"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/profile": {
      "put": {
        "operationId": "updateProfile",
        "summary": "Update body metrics and goal",
        "description": "Height, weight, activity, goal, region and cooking habits. These are the inputs every calorie and macro target is derived from, so a change here re-derives the numbers the app shows.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "biologicalSex": {
                    "type": "string",
                    "enum": [
                      "male",
                      "female"
                    ]
                  },
                  "weightKg": {
                    "type": "number",
                    "minimum": 30,
                    "maximum": 300
                  },
                  "heightCm": {
                    "type": "integer",
                    "minimum": 100,
                    "maximum": 250
                  },
                  "age": {
                    "type": "integer",
                    "minimum": 13,
                    "maximum": 100
                  },
                  "activityLevel": {
                    "type": "string",
                    "enum": [
                      "sedentary",
                      "light",
                      "moderate",
                      "very_active"
                    ]
                  },
                  "goal": {
                    "type": "string",
                    "enum": [
                      "cutting",
                      "bulking",
                      "maintaining"
                    ]
                  },
                  "aggression": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0.1,
                        "maximum": 0.8
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "carbSplit": {
                    "type": "string",
                    "enum": [
                      "moderate_carb",
                      "lower_carb",
                      "higher_carb"
                    ]
                  },
                  "tdeeKcal": {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "calorieTarget": {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "proteinTargetG": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "carbsTargetG": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "fatTargetG": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "countryOfOrigin": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 100,
                        "pattern": "^[^<>\\r\\n]*$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "countryOfResidence": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 100,
                        "pattern": "^[^<>\\r\\n]*$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "preferredLocale": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 10
                  },
                  "oilUsage": {
                    "type": "string",
                    "enum": [
                      "minimal",
                      "normal",
                      "heavy"
                    ]
                  },
                  "defaultRicePortion": {
                    "type": "string",
                    "enum": [
                      "small",
                      "medium",
                      "large"
                    ]
                  },
                  "sugarBraised": {
                    "type": "string",
                    "enum": [
                      "low",
                      "medium",
                      "high"
                    ]
                  },
                  "defaultProteinPortion": {
                    "type": "string",
                    "enum": [
                      "small",
                      "medium",
                      "large"
                    ]
                  },
                  "brothConsumption": {
                    "type": "string",
                    "enum": [
                      "leave_it",
                      "some",
                      "finish_it"
                    ]
                  }
                },
                "required": [
                  "biologicalSex",
                  "weightKg",
                  "heightCm",
                  "age",
                  "activityLevel",
                  "goal",
                  "aggression",
                  "carbSplit",
                  "tdeeKcal",
                  "calorieTarget",
                  "proteinTargetG",
                  "carbsTargetG",
                  "fatTargetG",
                  "countryOfOrigin",
                  "countryOfResidence",
                  "oilUsage",
                  "defaultRicePortion",
                  "sugarBraised",
                  "defaultProteinPortion",
                  "brothConsumption"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingProfile"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/profile/sharing": {
      "put": {
        "operationId": "updateSharingPreference",
        "summary": "Set whether new meals auto-share to your circle",
        "description": "Controls the default visibility of newly logged meals. Existing meals keep the visibility they were saved with.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Account",
          "Circle"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "autoShareToCircle": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "autoShareToCircle"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/onboarding/profile": {
      "get": {
        "operationId": "getOnboardingProfile",
        "summary": "The caller’s profile and targets",
        "description": "Body metrics, goal, region and cooking habits, plus the targets derived from them. Null for a user who never finished onboarding — that is a normal state, not an error.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Onboarding"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingProfile"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/onboarding/screen": {
      "post": {
        "operationId": "submitOnboardingScreen",
        "summary": "Submit one onboarding step",
        "description": "Onboarding is saved a screen at a time so a user who abandons halfway keeps what they entered.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Onboarding"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "step": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3
                  },
                  "data": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "step",
                  "data"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingProfile"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/onboarding/nudge/minimize": {
      "post": {
        "operationId": "minimizeOnboardingNudge",
        "summary": "Collapse the finish-setup prompt",
        "description": "Hides the reminder to finish onboarding without dismissing it forever.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Onboarding"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/onboarding/nudge/restore": {
      "post": {
        "operationId": "restoreOnboardingNudge",
        "summary": "Bring the finish-setup prompt back",
        "description": "The inverse of `minimizeOnboardingNudge`.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Onboarding"
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/feedback": {
      "post": {
        "operationId": "submitFeedback",
        "summary": "Send feedback or a bug report",
        "description": "Files a report against the running app version. Optionally references a screenshot uploaded first via `uploadFeedbackScreenshot`.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Support"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "bug",
                      "ingredient",
                      "idea"
                    ]
                  },
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4000
                  },
                  "screenshotPath": {
                    "type": "string",
                    "pattern": "^[0-9a-f-]{36}\\/[0-9a-f-]{36}\\.(png|jpg|webp)$"
                  },
                  "appVersion": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "platform": {
                    "type": "string",
                    "enum": [
                      "web",
                      "ios",
                      "android"
                    ]
                  },
                  "locale": {
                    "type": "string",
                    "maxLength": 16
                  },
                  "route": {
                    "type": "string",
                    "maxLength": 512
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "maxLength": 64
                    },
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 1024
                    }
                  }
                },
                "required": [
                  "type",
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    },
    "/api/v1/feedback/screenshot": {
      "post": {
        "operationId": "uploadFeedbackScreenshot",
        "summary": "Upload a screenshot for a feedback report",
        "description": "Multipart upload with a single `file` field. Returns the storage path to pass to `submitFeedback`. The request is size-checked from `Content-Length` before any bytes are buffered.\n\nFirst-party endpoint: it exists to serve the Kallo web and mobile clients and is not a stability contract for third parties. It may change without a version bump.",
        "tags": [
          "Support"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The screenshot image."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The stored path.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Acknowledgement"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (`VALIDATION_FAILED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No valid session (`NOT_AUTHENTICATED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include this feature (`feature_locked`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource, or it is not yours (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). Carries a `Retry-After` header when a wait is known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unhandled server error (`INTERNAL`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "supabaseBearer": []
          }
        ],
        "x-internal": true
      }
    }
  }
}