Productos
Un producto es un artículo que compráis o vendéis como artículo terminado: un producto envasado, un componente listo que compráis, un artículo del catálogo de un proveedor. Su composición suele venir de la declaración de ingredientes del envase.
Lo guardáis una sola vez, con vuestro propio id, y leéis su huella calculada. Un producto guardado también se puede usar en una receta: referenciadlo con type: "products".
Guardar un producto
PUT /products/{id}, con vuestro propio id en la URL. La respuesta ya contiene el cálculo terminado: no hace falta una segunda solicitud.
{
"id": "carrot-puree-500g",
"gtin": "00123456789023",
"names": [{"language": "de", "value": "Karottenpüree"}],
"amount": 500,
"unit": "gram",
"producer": "ACME Foods",
"ingredients-declaration": "Karotten, Wasser, Salz",
"nutrient-values": {
"energy-kcal": 35,
"fat-gram": 0.2,
"protein-gram": 0.9,
"carbohydrates-gram": 7.5
}
}
El ingredients-declaration nos dice de qué está hecho realmente el producto, así que incluidlo siempre que el envase tenga uno. Sin él, el producto se identifica solo por su nombre.
Para subir un catálogo, usad POST /products/batch. Cada producto se procesa por separado y recibe su propia entrada en la respuesta, así que un producto que no se puede calcular no frena al resto. Asignad las entradas a vuestra solicitud por product-id, o por el request-id que hayáis enviado.
Una vez subidos, mantened vuestra copia local al día con GET /products?updated-since: ved Mantener vuestros datos al día.
Mantener vuestros datos al día
Los valores que calculamos no están congelados. Mejoran con el tiempo (un ingrediente se asigna con más precisión, se actualizan los datos de fondo), así que un producto que subisteis hace meses puede tener hoy un mejor valor de CO₂.
GET /products devuelve los ids de vuestros productos. Añadid updated-since con la fecha de vuestra última sincronización y recibiréis solo los que vale la pena volver a obtener:
GET /products?updated-since=2026-07-01
{
"products": ["carrot-puree-500g", "tomato-sauce-400g"]
}
Es decir: los productos que habéis cambiado, los que nunca se calcularon y aquellos cuyos valores pueden haber cambiado porque algo de lo que dependen ha mejorado. Obtened cada uno con GET /products/{id}. Un producto subido mediante POST /products/batch se comporta en este listado exactamente igual que uno subido con un solo PUT.
Un único espacio de ids
Los productos y los ingredientes normales comparten un único espacio de ids: un id lo tiene o bien un producto o bien un ingrediente, nunca ambos a la vez. GET /products/{id} devuelve el que lo tenga, y el campo type os dice cuál:
type | Qué tiene el id |
|---|---|
products | Un producto. Solo cambia a través de los endpoints de productos. |
conceptual-ingredients | Un ingrediente normal. Lo define una receta o un suministro, y cualquier receta o suministro lo modifica. |
Una receta o un suministro que envía un id modifica el ingrediente normal con ese id, nunca un producto. Para guardar un producto con un id que ya tiene un ingrediente normal, poned convert-ingredient-to-product=true.
Propiedades del producto
Propiedades de la solicitud
| Propiedad | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | String | Sí | Vuestro identificador único del producto |
names | Array | Sí | Nombre del producto como array de objetos de idioma: [{"language": "de", "value": "Karottenpüree"}] |
ingredients-declaration | String | Buena práctica | Lista de ingredientes tal como figura en el envase. Se analiza para determinar de qué está hecho el producto. |
nutrient-values | Object | Buena práctica | Valores nutricionales por 100 g tal como figuran en el envase (ved Referencia) |
gtin | String | Buena práctica | Global Trade Item Number (www.gtin.info) |
amount | Float | Buena práctica | Cantidad del producto en la unidad indicada. Sin ella, la huella corresponde a un kilogramo. |
unit | String | No | Unidad: kg, gram o liter. Por defecto: gram |
producer | String | Buena práctica | El productor o la marca del producto |
date | String | No | Fecha de producción para cálculos estacionales. Formato: YYYY-MM-DD |
origin | String | Buena práctica | Lugar de producción: dirección postal o país |
transport | String | Buena práctica | Medio de transporte: air o ground |
production | String | Buena práctica | Método de producción: standard, greenhouse, organic, fair-trade, farm, wild-caught, sustainable-fish |
processing | String | No | Nivel de procesado: raw, unboned, boned, skinned, beheaded, fillet, cut, boiled, peeled |
conservation | String | Buena práctica | Método de conservación: fresh, frozen, dried, conserved, canned, boiled-down |
packaging | String | No | Tipo de envase: none, plastic, paper, pet, tin, alu, glas, cardboard, tetra |
Propiedades de la respuesta
El producto se devuelve en product, junto a un statuscode que indica si se pudo calcular.
| Propiedad | Tipo | Descripción |
|---|---|---|
statuscode | Integer | 200 cuando el producto se ha calculado. Ved Códigos de estado. |
message | String | Explica el statuscode cuando no es 200 |
product-id | String | El id del producto al que pertenece esta entrada |
product | Object | El producto y sus valores calculados (abajo) |
| Propiedad | Tipo | Descripción |
|---|---|---|
id | String | Identificador del producto |
type | String | products (protegido contra escritura) o conceptual-ingredients (cualquier receta puede sobrescribirlo) |
names | Array | Nombres del producto como array de objetos de idioma |
co2-value | Integer | Emisiones de CO₂ en gramos de CO₂e para la amount indicada (ved la nota de abajo) |
rating | String | Calificación de CO₂ (A-E). A es la mejor, E la peor. |
eaternity-award | Boolean | true si el producto es respetuoso con el clima |
co2-value-improvement-percentage | Float | Comparación de la huella de CO₂ de este producto por unidad alimentaria con la media |
co2-value-reduction-value | Float | Gramos de CO₂ ahorrados frente a un producto medio que aporta el mismo valor nutricional |
food-unit | Float | Valor nutricional del producto para la amount indicada |
amount | Float | Cantidad del producto, devuelta tal como venía en vuestra solicitud |
unit | String | Unidad de medida |
gtin | String | Global Trade Item Number |
date | String | Fecha de producción |
ingredients-declaration | String | El texto original de la declaración de ingredientes (cuando se indica ingredients-declaration=true) |
nutrient-values-estimated-per-specified-amount | Object | Valores nutricionales estimados por el backend y escalados a la cantidad indicada (cuando se indica nutrient-values=true) |
indicators | Object | Indicadores ambientales (cuando se indica indicators=true) |
co2-value y food-unit se calculan para la amount (y la unit) de vuestra solicitud: diez veces la cantidad es diez veces la huella. 500 gram y 0.5 kilogram dan el mismo resultado. Si no enviáis cantidad, la huella corresponde a un kilogramo.
Cuando, en cambio, referenciáis el producto desde una receta, es la amount de esa línea de la receta la que lo escala: la amount propia del producto no se traslada.
Ejemplo de respuesta
{
"statuscode": 200,
"message": "",
"request-id": 0,
"product-id": "carrot-puree-500g",
"product": {
"food-unit": 0.62,
"eaternity-award": true,
"co2-value": 77,
"rating": "A",
"co2-value-improvement-percentage": 84,
"co2-value-reduction-value": 403,
"id": "carrot-puree-500g",
"gtin": "00123456789023",
"names": [{"language": "de", "value": "Karottenpüree"}],
"amount": 500.0,
"unit": "gram",
"producer": "ACME Foods",
"origin": "",
"transport": "",
"production": "",
"processing": "",
"conservation": "",
"packaging": "",
"type": "products"
}
}
Códigos de estado
Además de los códigos de estado habituales, los productos usan:
| Código | Significado | Qué hacer |
|---|---|---|
| 612 | El producto que habéis referenciado no existe | Guardad primero el producto y después enviad la receta |
| 613 | Una escritura que un producto no acepta: o bien una receta intentó definir un ingrediente con el id de un producto, o bien la escritura de un producto convertiría un ingrediente existente | Referenciad el producto con type: "products" en lugar de definirlo. Para convertir un ingrediente a propósito, añadid convert-ingredient-to-product=true. |
Nota al margen: productos e ingredientes
Un producto y un ingrediente describen lo mismo: un alimento con un nombre, una cantidad y atributos como origen, producción y conservación. Se diferencian en cómo se guardan. Un producto se guarda una sola vez con su propio id y solo cambia a través de los endpoints de productos. Un ingrediente se define dentro de una receta o de un suministro.
Endpoints
📄️ List products
Returns the ids of all products stored for your account.
📄️ Create or update a batch of products
Create or update many products in a single request - the recommended way to upload a product
📄️ Create or update a product
Create or update a single product. The response already contains the finished calculation, so
📄️ Get a product
Retrieve a product together with its calculated values.
📄️ Delete a product
Delete a product. Like the read, this also resolves an ordinary ingredient stored under this