API de reconocimiento de imágenes de alimentos
Convierte una foto en datos de alimentos. Cuatro endpoints de visión cubren todo el flujo de la cámara: decodificar un código de barras, identificar un producto por su frontal, leer la etiqueta nutricional y los ingredientes, o analizar un plato de comida con estimaciones de ración, contrastado con 6,1 M de productos, en seis idiomas, cirílico incluido.
curl -X POST -H "X-API-Key: food_•••" \
-F "[email protected]" \
"https://foodbase.dev/v1/vision/product"
{
"extracted": {
"name": "Масло краве",
"brand": "Bulgaricum",
"quantity": "250g",
"lang": "bg",
"confidence": 0.95
},
"matches": [
{
"score": 0.95,
"product": {
"id": "c5b352b5-...",
"name_default": "Краве масло 82%"
}
}
],
"cached": false
} ¿Prefieres hacer clic? Prueba el explorador de productos o la zona de pruebas de fotos.
Qué obtienes
POST /vision/barcode
Decodifica EAN-13/UPC a partir de una foto y busca el producto. Gratis: 0 créditos.
POST /vision/product
Identifica un producto por su frontal y lo asocia al catálogo. 3 créditos.
POST /vision/label
Aplica OCR al panel de información nutricional y a la lista de ingredientes. 4 créditos.
POST /vision/meal
Identifica los platos de una bandeja con estimaciones de ración y kcal. 5 créditos.
confidence
Puntuación calibrada de 0 a 1 en cada extracción: decide cuándo preguntar al usuario.
cached
Las imágenes idénticas se sirven desde la caché: misma respuesta, al instante.
Disponible en todos los planes mediante créditos de IA mensuales: cada llamada tiene un precio fijo en créditos y todos los planes (incluido el gratuito) incluyen una asignación de créditos. Ver planes →
Ejemplos de código
La misma petición en curl, JavaScript y Python. Sustituye YOUR_API_KEY por una clave de tu panel.
curl "https://foodbase.dev/v1/vision/product" \
-H "X-API-Key: YOUR_API_KEY" \
-F "[email protected]"
const form = new FormData();
form.append("image", fileInput.files[0]); // a File/Blob from an <input type="file">
const res = await fetch("https://foodbase.dev/v1/vision/product", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY" },
body: form,
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
import requests
with open("photo.jpg", "rb") as f:
res = requests.post(
"https://foodbase.dev/v1/vision/product",
headers={"X-API-Key": "YOUR_API_KEY"},
files={"image": f},
timeout=30,
)
res.raise_for_status()
data = res.json()
Cómo funciona
Qué endpoint para qué foto
Las cuatro operaciones reciben un único campo multipart/form-data llamado image. El servidor inspecciona los bytes, no el nombre del archivo: JPEG, PNG o WebP, de hasta 8 MB, o la subida se rechaza antes de que se ejecute ningún modelo. Las fotos se giran automáticamente según EXIF y se redimensionan a 1024 px en el lado más largo, así que una captura a resolución completa solo cuesta tiempo de subida.
POST /v1/vision/barcode decodifica EAN-13, EAN-8, UPC-A, UPC-E y Code-128 con visión por computador clásica y busca el código igual que GET /foods/barcode/{code}. El cuerpo del 200 es { barcode, product } con el registro completo del catálogo (id, name_default, brand, nutrition_summary y el resto). No se ejecuta ningún modelo de lenguaje, así que cuesta 0 créditos y se contabiliza como una llamada de datos.
Las otras tres son llamadas de IA. /vision/product lee el frontal de un envase y produce extracted { name, brand, quantity, lang, confidence } más matches ordenadas. /vision/label transcribe un panel nutricional en números por 100 g, ingredients_text, allergens y ración; un panel que solo imprime valores por ración se convierte a por 100 g en código cuando se imprime el tamaño de ración (basis per_100g, converted: true); cuando no, los campos por 100 son null y los números impresos vuelven bajo per_serving (basis per_serving). /vision/meal devuelve items[] de platos reconocidos con estimaciones de ración. Cada respuesta lleva request_id y cached.
- Una petición sin el campo image es un 422 Validation Error con details[].field = "image".
Cómo leer una respuesta de /vision/product
extracted.lang es el idioma leído en el envase (bg para una etiqueta en cirílico) y guía una búsqueda en el catálogo consciente del idioma. confidence va de 0 a 1 y condiciona esa búsqueda: el catálogo solo se consulta cuando confidence es al menos 0.3 y se leyó un nombre; en caso contrario matches está vacío.
matches contiene hasta 5 productos, el mejor primero, cada uno { score, product } con la misma forma FoodItem completa que un registro de la API de base de datos de alimentos. score se deriva de confidence y de la posición, así que la primera coincidencia lleva la propia confidence y cada una siguiente puntúa menos. Conserva matches[0].product.id; los ids son estables entre reimportaciones.
Un fallo se ve así, ante la foto de un producto pequeño: {"matches":[],"extracted":{"lang":"","name":"","brand":"","quantity":"","confidence":0},"request_id":"bcca8231-f335-4468-81bf-e587b614d9a4","cached":true}. Las cadenas vacías y confidence 0 significan que no se pudo leer ningún nombre; cached: true significa que esos mismos bytes ya se habían visto antes, y la llamada se cobró igualmente con 3 créditos.
Etiquetas y comidas: lectura frente a estimación
/vision/label es transcripción, no inferencia. energy_kcal, fat_g, saturated_fat_g, carbs_g, sugars_g, fiber_g, proteins_g y salt_g se leen tal como están impresos, y todo lo que no figura en la etiqueta vuelve null, nunca adivinado. Un código de barras legible en la misma foto se devuelve como extracted.barcode y se busca: un acierto rellena product con el FoodItem completo; si no, product es null.
/vision/meal es lo contrario, y su campo disclaimer lo dice. Cada elemento tiene dish, kind, portion_g_est y confidence, además de match cuando el plato se resolvió a un alimento genérico del USDA: id, name_default, per_100g { energy_kcal, proteins_g, carbs_g, fat_g } y estimated_kcal, que es per_100g.energy_kcal por portion_g_est entre 100. Los elementos son platos enteros (kind "dish": una hamburguesa, una lasaña) o los componentes separados de un plato (kind "component": arroz, pollo a la plancha, ensalada), nunca un plato junto con sus propias partes, de modo que estimated_total_kcal, la suma de los elementos que tienen una, no cuenta nada dos veces; es null cuando ningún elemento la tiene. La asociación usa alimentos genéricos en inglés (USDA FNDDS para platos tal como se comen, como lasaña, burritos o pad thai, y después USDA SR Legacy para ingredientes), así que match.name_default está en inglés sea cual sea la foto, y un elemento sin una coincidencia fiable recibe match: null en lugar de un alimento equivocado.
- Muestra el texto de disclaimer a los usuarios finales de las estimaciones de comidas; un plato con match: null cuesta igualmente los 5 créditos.
Créditos, reembolsos y el límite de tasa de visión
Los créditos se descuentan antes de la inferencia: 3 para product, 4 para label, 5 para meal. La asignación mensual se comparte entre todas las claves de la cuenta (Free 20, Starter 500, Pro 1300, Enterprise 3000) y se reinicia el día 1 del mes UTC. Cuando ya no puede cubrir una llamada, la pagan los créditos de los paquetes de recarga puntuales (comprados en la página de Facturación del panel, válidos 12 meses). Las respuestas de IA llevan X-Credits-Limit, X-Credits-Remaining (mensuales más recarga), X-Credits-Topup-Remaining y X-Credits-Reset; GET /v1/credits devuelve ambos saldos gratis.
Quedarse sin créditos es un 402, no un 429: { "error": "Insufficient credits", "message": "This call costs 3 credits and your free plan's monthly allowance of 20 is exhausted, with no top-up credits left. Buy more at https://foodbase.dev/dashboard/billing (they apply instantly), or wait for the reset on 2026-12-01.", "top_up_url": "https://foodbase.dev/dashboard/billing" }. Solo hay reembolso cuando la petición nunca llegó a una respuesta: imagen rechazada (413 o 422), campo ausente (422), fallo del proveedor (502, el mensaje termina en "You were not charged.") o visión desactivada (503). Los aciertos de caché se cobran a precio completo a propósito.
Las llamadas de IA tienen su propio límite por segundo, sin ráfaga: 1/s en Free y Starter, 2/s en Pro, 5/s en Enterprise por clave, y el triple en toda la cuenta. Las respuestas llevan X-RateLimit-Vision-Limit y X-RateLimit-Vision-Remaining; superarlo es un 429 con Retry-After: 1 y sin cobro, porque el limitador se ejecuta antes de la deducción.
El flujo de escaneo y la foto
Primero lo más barato. Decodifica el código de barras en el dispositivo y llama a la API de consulta de códigos de barras, o deja que /vision/barcode lo decodifique por 0 créditos. Solo cuando no hay código de barras, o la consulta devuelve 404, envía el frontal del envase a /vision/product. Con matches[0].product.id, obtén el desglose por 100 g de la API de nutrición o un veredicto en lenguaje sencillo de la API de análisis de alimentos con IA.
La calidad de la foto decide la confianza. Para /vision/product, encuadra el frontal del envase con nombre, marca y tamaño legibles y nada más en la imagen. Para /vision/label, coloca el panel plano, llena el encuadre con la tabla nutricional y el párrafo de ingredientes e incluye el código de barras si cabe. Para /vision/barcode la regla es el propio mensaje 422 del servidor: llena el encuadre con el código de barras, evita reflejos, mantenlo enfocado.
- Reintenta un 502 tras una breve espera; se te reembolsó. No reintentes un 200 de baja confianza; vuelve a hacer la foto.
Qué puedes crear
Registro de alimentos con fotos
Haz una foto a un producto o a una comida y regístralo: sin teclear, sin buscar el código de barras.
Captura de etiquetas
Digitaliza la información nutricional y los ingredientes de cualquier envase, incluso de productos que aún no están en una base de datos.
Respaldo inteligente del escáner
¿No se lee el código de barras? Recurre al reconocimiento del frontal del envase dentro del mismo flujo.
Límites por plan
| Free | 20 créditos de IA/mes; 1 solicitud de IA/s por clave; /vision/barcode cuenta contra 100 solicitudes/día |
|---|---|
| Starter | 500 créditos de IA/mes; 1 solicitud de IA/s por clave; /vision/barcode cuenta contra 5000 solicitudes/día |
| Pro | 1300 créditos de IA/mes; 2 solicitudes de IA/s por clave; /vision/barcode cuenta contra 25.000 solicitudes/día |
| Enterprise | 3000 créditos de IA/mes; 5 solicitudes de IA/s por clave; /vision/barcode cuenta contra 100.000 solicitudes/día |
Cada respuesta incluye cabeceras X-RateLimit-* con el presupuesto restante; cada 429 incluye Retry-After . Comparar planes →
Errores y cómo gestionarlos
402 — Se agotaron los créditos de IA mensuales y los de recarga; el cuerpo indica el precio, tu asignación, la fecha de reinicio y un top_up_url.
Compra un paquete de créditos (se aplica al instante), espera a X-Credits-Reset o mejora tu plan. /vision/barcode sigue funcionando.
404 — /vision/barcode decodificó un código que no está en el catálogo; el cuerpo lo devuelve.
No reintentes. Recurre a /vision/product con una foto del frontal del envase.
413 — Subida de más de 8 MB.
Reduce el tamaño en el cliente; el servidor redimensiona a 1024 px de todos modos. Créditos reembolsados.
422 — Imagen ausente, no decodificable, de formato incorrecto, o sin código de barras en el encuadre.
Lee details[] o message y repite la foto. Créditos reembolsados.
429 — Se superó el límite por segundo de visión para la clave o la cuenta.
Espera Retry-After (1 segundo) y reenvía. No se cobró nada.
502 — El proveedor de visión falló a mitad de la llamada.
Reintenta una vez tras una pausa; el mensaje confirma que no se te cobró.
503 — La visión no está configurada, o el limitador o el almacén de créditos no está accesible.
Reintenta con retroceso exponencial. No se cobró nada.
Comparada con otras API
La mayoría de los servicios de foto a alimento devuelven una etiqueta de lo que creen ver y te dejan a ti encontrar el producto. FoodBase lo resuelve en la misma llamada: extracción más coincidencias ordenadas contra el catálogo de 6,1 M de productos, o un registro enlazado cuando la foto de una etiqueta lleva un código de barras. Separa leer de adivinar: los valores de la etiqueta se transcriben o son null, y solo /vision/meal estima, con un campo disclaimer. La contrapartida es que una foto mala produce una lista de coincidencias vacía y cuesta igualmente sus créditos, así que las indicaciones sobre cómo hacer la foto en tu interfaz se amortizan solas.
Preguntas frecuentes
¿/vision/product cuesta créditos cuando nada coincide? +
Sí. Los créditos se descuentan antes de la inferencia, y un 200 con matches: [] es una llamada completada. Repite la foto en lugar de reenviarla; reenviarla es un acierto de caché a precio completo.
¿Por qué se cobró una respuesta en caché? +
Los aciertos de caché cuestan deliberadamente lo mismo que las llamadas nuevas; la caché hace que las repeticiones sean rápidas y coherentes, no gratuitas. Deduplica las fotos idénticas en el cliente antes de una segunda subida.
¿Puede /vision/label rellenar valores que la etiqueta no muestra? +
No. Transcribe el panel y devuelve null para todo lo que no está impreso. Para una interpretación de esos números, envía el id del producto enlazado a la API de análisis de alimentos con IA.
¿El límite de tasa de visión es el mismo que el de mi API? +
No. Las llamadas de IA usan un cubo aparte y más bajo: 1/s en Free y Starter, 2/s en Pro, 5/s en Enterprise por clave, y el triple en todas las claves. Solo /vision/barcode usa el límite de la API de datos habitual y la cuota diaria.
¿Cómo compruebo los créditos restantes sin gastar ninguno? +
Llama a GET /v1/credits con tu clave. Devuelve el plan, la asignación mensual, los créditos usados y la fecha de reinicio, y no cuenta ni contra los créditos ni contra la cuota diaria.
Descubre más endpoints
API de análisis de alimentos con IA
Una llamada convierte los datos en bruto de un producto en algo que puedes mostrar a un usuario: un resumen de dos frases, puntos buenos y alertas calculados a partir de los datos nutricionales con umbrales publicados, los alérgenos declarados, la compatibilidad con dietas indicando de dónde sale cada respuesta y el nivel de procesamiento, en seis idiomas y basado estrictamente en los datos de etiqueta del producto.
Más información →API de consulta de códigos de barras
Escanea o escribe un código de barras y obtén el producto. Resuelve cualquier código EAN-13 o UPC a un registro de alimento (marca, categoría, Nutri-Score y resumen nutricional) en una sola petición. Pensada para apps con escáner.
Más información →API de nutrición
Ve más allá de los macros principales. Obtén un desglose detallado de más de 40 nutrientes por producto (energía, proteínas, hidratos de carbono, grasas, azúcares, fibra, sodio, vitaminas y minerales), todo por 100 g, para cualquier alimento por ID.
Más información →Empieza a crear con la API de reconocimiento de imágenes de alimentos
Gratis para empezar. Sin tarjeta de crédito.
Obtener clave API Ir al panel