> ## Documentation Index
> Fetch the complete documentation index at: https://docs.closient.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit Product Nutrition

> Create, update, and delete a product's nutrition-facts panel and nutrient rows — the programmatic equivalent of the dashboard's nutrition page.

Programmatic equivalent of the dashboard's `products/<gtin>/nutrition/` page
(and its per-nutrient `nutrition/<id>/edit/`, `nutrition/<id>/delete/`
sub-pages).

## When to use

* A brand owner needs to record or correct a product's nutrition-facts
  header (serving size, servings per container, label format) or its
  individual nutrient rows (calories, fat, sodium, etc.).

## Auth

`X-API-Key` header or OAuth token with `dashboard:write` scope. The caller
must be a member of `organization_id` and hold the
`organization.contribute_organization` permission; the product must be owned
by that organization.

## Flow

The header (one-per-product) and nutrient rows are managed separately.

```
GET    /dashboard/api/v1/trade-items/{organization_id}/{gtin}/nutrition
PUT    /dashboard/api/v1/trade-items/{organization_id}/{gtin}/nutrition
POST   /dashboard/api/v1/trade-items/{organization_id}/{gtin}/nutrition/nutrients
PATCH  /dashboard/api/v1/trade-items/{organization_id}/{gtin}/nutrition/nutrients/{nutrient_id}
DELETE /dashboard/api/v1/trade-items/{organization_id}/{gtin}/nutrition/nutrients/{nutrient_id}
```

* **`GET` nutrition** — returns the header plus nutrient rows (each with its
  id); `404` if no panel has been recorded yet.
* **`PUT` nutrition** — creates the header if absent, or updates it in place
  (it is one-per-product, so this is an upsert, not an append). Body:
  `serving_size`, `serving_size_g`, `servings_per_container`, `label_format`.
* **`POST` nutrients** — adds one nutrient row to an existing header. `409`
  if the nutrient already exists on this panel; `422` if the header doesn't
  exist yet (create it first via `PUT`).
* **`PATCH` / `DELETE` nutrients** — edit or remove a single row by id.

Returns `403` for a caller without the contribute permission (no row is
created or modified).

## Notes

Writes go through an audited `@org_action` service — the direct
`form.save()` this dashboard page used before C-4070 is gone; the API path
and the UI path now share the exact same permission check and audit trail.
