> This page is for version v1 (default).
> For other versions, use one of these documentation indexes:
> - v1 (default): https://docs.truemed.com/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.truemed.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.truemed.com/_mcp/server.

# Nutrition and structured data

> Send nutrition, allergen, and attribute data for your catalog items through the API.

Send each meal's Nutrition Facts, allergens, and labels to Truemed as structured data. Truemed's Clinical Ops team reviews the nutrition data when it decides a meal's HSA/FSA eligibility.

## Block types

Truemed stores structured data in blocks. Each catalog item has at most one block of each type.

| Type             | Fields                                                                                                                                                   | No block                                                                |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `meal_nutrition` | `serving_size`, `nutrients`, and optional `additional_nutrients`                                                                                         | The item has no nutrition data.                                         |
| `allergens`      | `contains` and optional `may_contain`, each a list of `milk`, `eggs`, `fish`, `shellfish`, `tree_nuts`, `peanuts`, `wheat`, `soy`, `sesame`, or `gluten` | The allergens are unknown. Send `contains: []` to declare no allergens. |
| `attributes`     | A map of snake_case keys to a label or a list of labels                                                                                                  | The item has no labels.                                                 |

> **Note**
>
> Truemed shows `attributes` to its reviewers. Attributes never decide an item's eligibility.

## Step 1: Send the blocks with the catalog item

Add a `blocks` map to [`create_catalog_item`](/v-1/api-reference/product-catalog/create-item) or [`update_catalog_item`](/v-1/api-reference/product-catalog/update-item). Every request carries the full catalog item, including its `description`, the same as a row in a catalog CSV upload.

```json
{
  "sku": "MEAL-1042",
  "name": "Lemon Herb Chicken",
  "description": "Roast chicken with lemon, herbs, and farro.",
  "url": "https://example.com/meals/lemon-herb-chicken",
  "image_urls": ["https://example.com/images/lemon-herb-chicken.jpg"],
  "blocks": {
    "meal_nutrition": {
      "serving_size": {"household_measure": "1 Tray", "metric_amount": "352", "metric_unit": "g"},
      "nutrients": {
        "energy_kcal": 520,
        "protein_g": 38,
        "total_fat_g": 22,
        "saturated_fat_g": 6,
        "trans_fat_g": 1,
        "sodium_mg": 770,
        "total_carbohydrate_g": 41,
        "dietary_fiber_g": 7,
        "total_sugars_g": 9,
        "potassium_mg": 880
      },
      "additional_nutrients": {"omega_3": {"amount": "450", "unit": "mg"}}
    },
    "allergens": {"contains": ["milk", "wheat"], "may_contain": ["tree_nuts"]},
    "attributes": {"category": ["Mediterranean-style", "High Protein Recovery"]}
  }
}
```

Send amounts per serving, in the unit that ends each key. For example, send sodium in milligrams as `sodium_mg`. If a label shows a "less than" value such as "\<1g", send `0.5`.

The response shows each block's `state`, `version`, and `review_status`.

```json
{
  "blocks": {
    "meal_nutrition": {"state": "created", "version": 1, "review_status": "needs_confirmation"},
    "allergens": {"state": "created", "version": 1, "review_status": "not_required"},
    "attributes": {"state": "created", "version": 1, "review_status": "not_required"}
  }
}
```

## Step 2: Update a meal

Send the full catalog item to `update_catalog_item` with the whole block and its new values. Truemed replaces the stored block and leaves block types you do not send untouched.

* If the block is identical to the stored one, its `state` is `unchanged` and Truemed writes no new version.
* If the `meal_nutrition` block changes, Truemed's Clinical Ops team reviews the meal again. The meal keeps its eligibility until the review ends.
* An `allergens` or `attributes` change never starts a review.
* Send `null` for a block type to clear that block.

To avoid overwriting a change you have not seen, add `if_match` to a block with the version you last read. If the block is at another version, the request returns `409` and Truemed saves neither the item nor its blocks.

```json
"blocks": {"allergens": {"contains": ["milk"], "if_match": 1}}
```

## Step 3: Handle rejected blocks

An item's blocks apply together or not at all. If any block is invalid, the request returns `400` with each field path and error code, and Truemed saves neither the item nor its blocks.

Truemed rejects a `meal_nutrition` block in these cases:

* A key is unknown, or a nutrient uses a unit other than its own, such as `sodium_g`.
* Saturated fat and trans fat add up to more than total fat.
* Dietary fiber and total sugars add up to more than total carbohydrate.
* Added sugars are more than total sugars.
* Protein, fat, and carbohydrate add up to more grams than a serving in grams weighs.

## Read the blocks

[`get_item_detail`](/v-1/api-reference/product-catalog/get-item-detail) and [`list_catalog_items`](/v-1/api-reference/product-catalog/list-catalog-items) return each item's `blocks` at their latest version, with `version`, `source`, `review_status`, and `data`. An item without blocks has no `blocks` field.