> For the complete documentation index, see [llms.txt](https://docs.january.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.january.ai/client-sdks/ios-sdk/reference/models-and-enums.md).

# Models and enums

## Typed identifiers

```swift
public struct FoodID: RawRepresentable, Codable, Hashable, Sendable {
    public let rawValue: String
    public init(rawValue: String)
    public init(rawValue: Int64)
}

public struct ServingID: RawRepresentable, Codable, Hashable, Sendable {
    public let rawValue: String
    public init(rawValue: String)
    public init(rawValue: Int64)
}

public struct PartnerUserID: RawRepresentable, Codable, Hashable, Sendable {
    public let rawValue: String
    public init(rawValue: String)
}
```

## Serving and selection

| Type               | Public fields                                                                                                  |
| ------------------ | -------------------------------------------------------------------------------------------------------------- |
| `ServingOption`    | `id`, `quantity`, `unit`, `scalingFactor`, `weightGrams`, `isPrimary`                                          |
| `ServingSelection` | `id`, `quantity`                                                                                               |
| `FoodSelection`    | `id`, `serving`                                                                                                |
| `FoodPortion`      | `foodID`, `serving`, `quantity`, `nutrition`, `totalWeightGrams`, `glycemicIndex`, `glycemicLoad`, `selection` |

```swift
public extension FoodSearchItem {
    func portion(
        servingID: ServingID? = nil,
        quantity: Double? = nil
    ) throws -> FoodPortion
}
```

Without a serving ID, portion selection uses the primary serving or the first serving. `quantity` is an amount in that serving's unit and defaults to one serving; `selection` sends the number of servings ([Quantity and servings](/client-sdks/ios-sdk/concepts/food-hydration-and-portions.md#quantity-and-servings)).

## Nutrition

`NutrientAmount` contains `value: Double` and `unit: String`. `NutritionFacts` exposes optional calories, protein, carbohydrates, net carbohydrates, total fat, trans fat, saturated fat, fiber, total/added sugars, cholesterol, calcium, iron, potassium, sodium, and vitamin D.

`CompleteScanNutritionFacts` is the subset food analysis returns: calories, protein, carbohydrates, net carbohydrates, total fat, saturated fat, fiber, total/added sugars, and sodium.

## Food models

`FoodSearchItem` includes a typed ID, an optional name and brand, structured and compatibility nutrition fields, glycemic values, an optional photo URL, and `[ServingOption]`, each with a nonoptional `ServingID`. `AlternativeFood.id` and a logged food's `LoggedFood.id` are nonoptional `FoodID` values, and `RestaurantMenuItem.id` is always present. `FoodSuggestion` is smaller: an ID, an optional name, and optional brand, image, and nutrition. `DetectedFood` is one food from food analysis. It carries the food `id`, the selected `serving` (`ServingSummary`, with the serving's `weightGrams` when known), and the `quantity` eaten. All three are optionals in Swift, and `quantity` is `nil` when no usable portion was found, so unwrap them before logging. `FoodLogSummaryGrouping` (`day`, `week`), `WeekStart` (`monday`, `sunday`), and `AnalysisEffort` (`none`, `xhigh`) are the remaining request enums.

## Dietary enums

`DietRestriction` values: `gluten`, `lactose`, `yeast`, `treeNuts`, `peanuts`, `dairy`, `eggs`, `sulfites`, `soy`, `wheat`, `shellfish`, `fish`, `mushrooms`, `sesame`, `monosodiumGlutamate`, `caffeine`, `fodmaps`.

`DietPreference` values: `vegetarian`, `vegan`, `keto`, `paleo`, `pescatarian`, `lowCarbohydrate`, `highProtein`, `kosher`, `halal`.

## Glucose enums and units

| Type               | Values                                                         |
| ------------------ | -------------------------------------------------------------- |
| `Sex`              | `male`, `female`                                               |
| `HeightUnit`       | `inches`, `centimeters`                                        |
| `WeightUnit`       | `pounds`, `kilograms`                                          |
| `ActivityLevel`    | `sedentary`, `lightlyActive`, `moderatelyActive`, `veryActive` |
| `MedicalCondition` | `type2Diabetes`, `prediabetes`                                 |

Use `Sex` for the profile's biological-sex field. Omit `healthConditions` or pass an empty array when no medical conditions apply. `age` is a whole number of years.

## Water and weight logs

| Type              | Fields                                                        |
| ----------------- | ------------------------------------------------------------- |
| `VolumeUnit`      | `fluidOunces` (`fl_oz`), `milliliters` (`ml`), `cups` (`cup`) |
| `WaterAmount`     | `value`, `unit` (`VolumeUnit`)                                |
| `Volume`          | `value` (one decimal place), `unit` (`VolumeUnit`)            |
| `WaterLog`        | `id`, `amount`, `consumedAtUTC`                               |
| `DailyWaterTotal` | `date`, `total` (`Volume`)                                    |
| `WeightLog`       | `weight` (`Weight`), `measuredAtUTC`                          |
| `DailyWeight`     | `date`, `weight` (`Weight`)                                   |

`Weight` and `WeightUnit` are shared with glucose prediction.

## Error categories

`ErrorCategory` values are `authentication`, `authorization`, `validation`, `notFound`, `rateLimited`, `server`, `transport`, `timeout`, and `decoding`.

`JanuaryError` exposes `category`, an optional `code`, `message`, and an optional `httpStatus` ([Errors](/client-sdks/ios-sdk/reference/error-handling.md#properties)). Its `requestID` and `retryAfterSeconds` are always `nil` in 0.3.2.

## Scanner types

`JanuaryFoodScannerMode` has `photo` and `barcode`. `JanuaryFoodScannerConfiguration` defaults to both modes, photo first, maximum dimension 1,000, and compression quality 0.7. `JanuaryFoodScannerResult` is either `.photo(image:analysis:)` or `.barcode(value:food:)`.
