API di riconoscimento di immagini di cibo
Trasforma una foto in dati alimentari. Quattro endpoint di visione coprono l'intero flusso della fotocamera: decodifica un codice a barre, identifica un prodotto dal fronte, leggi l'etichetta nutrizionale e gli ingredienti, oppure analizza un piatto con stima delle porzioni — confrontando con 6,1 mln di prodotti, in sei lingue incluso il cirillico.
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
} Preferisci cliccare? Prova l'esploratore di prodotti o l'area di prova foto.
Cosa ottieni
POST /vision/barcode
Decodifica EAN-13/UPC da una foto e cerca il prodotto. Gratis — 0 crediti.
POST /vision/product
Identifica un prodotto dal fronte e lo associa al catalogo. 3 crediti.
POST /vision/label
OCR della tabella nutrizionale e dell'elenco degli ingredienti. 4 crediti.
POST /vision/meal
Identifica i piatti in un vassoio con stima di porzioni e kcal. 5 crediti.
confidence
Punteggio calibrato da 0 a 1 su ogni estrazione — decidi quando chiedere conferma all'utente.
cached
Le immagini identiche vengono servite dalla cache — stessa risposta, istantanea.
Disponibile su tutti i piani tramite i crediti IA mensili — ogni chiamata ha un prezzo fisso in crediti e ogni piano (anche Free) include una quota di crediti. Vedi i piani →
Esempi di codice
La stessa richiesta in curl, JavaScript e Python. Sostituisci YOUR_API_KEY con una chiave della tua dashboard.
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()
Come funziona
Quale endpoint per quale foto
Tutte e quattro le operazioni accettano un solo campo multipart/form-data chiamato image. Il server legge i byte, non il nome del file: JPEG, PNG o WebP, fino a 8 MB, altrimenti il caricamento viene rifiutato prima che giri qualsiasi modello. Le foto vengono ruotate automaticamente dall'EXIF e ridimensionate a 1024 px sul lato più lungo, quindi uno scatto a piena risoluzione costa solo tempo di caricamento.
POST /v1/vision/barcode decodifica EAN-13, EAN-8, UPC-A, UPC-E e Code-128 con semplice computer vision e cerca il codice esattamente come GET /foods/barcode/{code}. Il corpo 200 è { barcode, product } con il record completo del catalogo (id, name_default, brand, nutrition_summary e il resto). Non gira alcun modello linguistico, quindi costa 0 crediti ed è conteggiata come una chiamata ai dati.
Le altre tre sono chiamate IA. /vision/product legge il fronte di una confezione in extracted { name, brand, quantity, lang, confidence } più matches ordinate. /vision/label trascrive una tabella nutrizionale in numeri per 100 g, ingredients_text, allergens e serving; una tabella che stampa solo valori per porzione viene convertita a per 100 g nel codice quando la dimensione della porzione è stampata (basis per_100g, converted: true); quando non lo è, i campi per 100 sono null e i numeri stampati tornano sotto per_serving (basis per_serving). /vision/meal restituisce items[] di piatti riconosciuti con stime di porzione. Ogni risposta porta request_id e cached.
- Una richiesta senza il campo image è un 422 Validation Error con details[].field = "image".
Leggere una risposta di /vision/product
extracted.lang è la lingua letta sulla confezione (bg per un'etichetta in cirillico) e guida una ricerca nel catalogo attenta alla lingua. confidence va da 0 a 1 e condiziona quella ricerca: il catalogo viene interrogato solo quando confidence è almeno 0,3 e un nome è stato letto; altrimenti matches è vuoto.
matches contiene fino a 5 prodotti, dal migliore, ciascuno { score, product } nella stessa forma completa FoodItem di un record della Food Database API. score deriva da confidence e dalla posizione, quindi la prima corrispondenza porta la confidence stessa e ogni voce successiva ha un punteggio più basso. Conserva matches[0].product.id; gli id sono stabili tra le reimportazioni.
Un mancato riscontro si presenta così, per la foto di un piccolo prodotto: {"matches":[],"extracted":{"lang":"","name":"","brand":"","quantity":"","confidence":0},"request_id":"bcca8231-f335-4468-81bf-e587b614d9a4","cached":true}. Stringhe vuote e confidence 0 significano che non è stato possibile leggere alcun nome; cached: true significa che gli stessi byte erano già stati visti, e la chiamata è stata comunque addebitata di 3 crediti.
Etichette e pasti: letto contro stimato
/vision/label è trascrizione, non inferenza. energy_kcal, fat_g, saturated_fat_g, carbs_g, sugars_g, fiber_g, proteins_g e salt_g sono letti come stampati, e qualsiasi cosa non presente in etichetta torna null, mai ipotizzata. Un codice a barre leggibile nella stessa foto viene restituito come extracted.barcode e cercato: se c'è una corrispondenza, product si riempie con il FoodItem completo, altrimenti product è null.
/vision/meal è l'opposto, e il suo campo disclaimer lo dice. Ogni elemento ha dish, kind, portion_g_est e confidence, più match quando il piatto è stato risolto in un alimento generico USDA: id, name_default, per_100g { energy_kcal, proteins_g, carbs_g, fat_g } e estimated_kcal, che è per_100g.energy_kcal moltiplicato per portion_g_est diviso 100. Gli elementi sono o piatti interi (kind "dish": un hamburger, una lasagna) o i componenti separati di un vassoio (kind "component": riso, pollo alla griglia, insalata), mai un piatto insieme alle sue parti, quindi estimated_total_kcal, la somma degli elementi che ne hanno uno, non conta nulla due volte; è null quando nessun elemento ne ha uno. La corrispondenza usa alimenti generici in inglese — USDA FNDDS per i piatti come si mangiano (lasagna, burritos, pad thai), poi USDA SR Legacy per gli ingredienti — quindi match.name_default è in inglese qualunque sia la foto, e un elemento senza una corrispondenza sicura riceve match: null invece di un alimento sbagliato.
- Mostra il testo del disclaimer agli utenti finali delle stime dei pasti; un piatto con match: null costa comunque i 5 crediti.
Crediti, rimborsi e limite di frequenza della visione
I crediti vengono scalati prima dell'inferenza: 3 per product, 4 per label, 5 per meal. La quota mensile è condivisa da tutte le chiavi dell'account (Free 20, Starter 500, Pro 1.300, Enterprise 3.000) e si azzera il primo del mese UTC. Quando non può più coprire una chiamata, la pagano i crediti dei pacchetti di ricarica una tantum (acquistabili nella pagina Fatturazione della dashboard, validi 12 mesi). Le risposte IA portano X-Credits-Limit, X-Credits-Remaining (mensili più ricarica), X-Credits-Topup-Remaining e X-Credits-Reset; GET /v1/credits restituisce gratis entrambi i saldi.
Restare senza crediti è un 402, non 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" }. I rimborsi avvengono solo quando la richiesta non è mai arrivata a una risposta: immagine rifiutata (413 o 422), campo mancante (422), guasto del provider (502, il messaggio termina con “You were not charged.”) o visione disattivata (503). Le risposte dalla cache sono addebitate a prezzo pieno di proposito.
Le chiamate IA hanno un proprio limite al secondo, senza burst: 1/s su Free e Starter, 2/s su Pro, 5/s su Enterprise per chiave, e tre volte tanto sull'intero account. Le risposte portano X-RateLimit-Vision-Limit e X-RateLimit-Vision-Remaining; superarlo è un 429 con Retry-After: 1 e nessun addebito, perché il limitatore agisce prima della detrazione.
Il flusso di scansione e la foto
Prima il meno costoso. Decodifica il codice a barre sul dispositivo e chiama la Barcode Lookup API, oppure lascia che sia /vision/barcode a decodificarlo per 0 crediti. Solo quando non c'è un codice a barre, o la ricerca restituisce 404, invia il fronte della confezione a /vision/product. Con matches[0].product.id, recupera il dettaglio per 100 g dalla Nutrition API oppure un giudizio in linguaggio semplice dalla AI Food Analysis API.
La qualità della foto decide la confidence. Per /vision/product inquadra il fronte della confezione con nome, marca e formato leggibili e nient'altro nell'inquadratura. Per /vision/label appoggia la tabella in piano, riempi l'inquadratura con la tabella nutrizionale e il paragrafo degli ingredienti, e includi il codice a barre se ci sta. Per /vision/barcode vale il messaggio 422 del server stesso: riempi l'inquadratura con il codice a barre, evita i riflessi, mantienilo a fuoco.
- Riprova un 502 dopo una breve attesa; sei stato rimborsato. Non riprovare un 200 a bassa confidence; scatta di nuovo.
Cosa puoi costruire
Registro alimentare con foto
Scatta una foto a un prodotto o a un pasto e registralo — niente digitazione, niente caccia al codice a barre.
Acquisizione delle etichette
Digitalizza valori nutrizionali e ingredienti da qualsiasi confezione, anche di prodotti non ancora in un database.
Ripiego intelligente dello scanner
Codice a barre illeggibile? Ripiega sul riconoscimento del fronte della confezione nello stesso flusso.
Limiti per piano
| Free | 20 crediti IA/mese; 1 richiesta IA/s per chiave; /vision/barcode conta nelle 100 richieste/giorno |
|---|---|
| Starter | 500 crediti IA/mese; 1 richiesta IA/s per chiave; /vision/barcode conta nelle 5.000 richieste/giorno |
| Pro | 1.300 crediti IA/mese; 2 richieste IA/s per chiave; /vision/barcode conta nelle 25.000 richieste/giorno |
| Enterprise | 3.000 crediti IA/mese; 5 richieste IA/s per chiave; /vision/barcode conta nelle 100.000 richieste/giorno |
Ogni risposta include gli header X-RateLimit-* con il budget residuo; ogni 429 include Retry-After . Confronta i piani →
Errori e come gestirli
402 — Crediti IA mensili e crediti di ricarica esauriti; il corpo riporta il prezzo, la tua quota, la data del reset e un top_up_url.
Acquista un pacchetto di crediti (si applica subito), attendi X-Credits-Reset o passa a un piano superiore. /vision/barcode funziona comunque.
404 — /vision/barcode ha decodificato un codice che non è nel catalogo; il corpo lo restituisce.
Non riprovare. Ripiega su /vision/product con una foto del fronte della confezione.
413 — Caricamento superiore a 8 MB.
Riduci le dimensioni lato client; il server comunque ridimensiona a 1024 px. Crediti rimborsati.
422 — Immagine mancante, non decodificabile, di formato errato, oppure nessun codice a barre nell'inquadratura.
Leggi details[] o message e scatta di nuovo. Crediti rimborsati.
429 — Limite al secondo della visione superato per la chiave o per l'account.
Attendi Retry-After (1 secondo) e reinvia. Nulla è stato addebitato.
502 — Il provider di visione ha fallito durante la chiamata.
Riprova una volta dopo una pausa; il messaggio conferma che non ti è stato addebitato nulla.
503 — Visione non configurata, oppure il limitatore o l'archivio dei crediti non è raggiungibile.
Riprova con backoff. Nulla è stato addebitato.
Confronto con altre API
La maggior parte dei servizi da foto a cibo restituisce un'etichetta per ciò che pensa di vedere e lascia a te il compito di trovare il prodotto. FoodBase risolve nella stessa chiamata: estrazione più corrispondenze ordinate sul catalogo da 6,1 mln di prodotti, oppure un record collegato quando la foto di un'etichetta contiene un codice a barre. Tiene separati lettura e ipotesi: i valori d'etichetta sono trascritti o null, e solo /vision/meal stima, con un campo disclaimer. Il compromesso è che una foto scadente produce un elenco di corrispondenze vuoto e costa comunque i suoi crediti, quindi le indicazioni sulla foto nella tua UI si ripagano da sole.
Domande frequenti
/vision/product costa crediti quando nulla corrisponde? +
Sì. I crediti vengono scalati prima dell'inferenza, e un 200 con matches: [] è una chiamata completata. Scatta di nuovo la foto invece di reinviarla; un reinvio è un riscontro in cache a prezzo pieno.
Perché una risposta dalla cache è stata comunque addebitata? +
I riscontri in cache costano volutamente come le chiamate nuove; la cache rende le ripetizioni veloci e coerenti, non gratuite. Deduplica le foto identiche lato client prima di un secondo caricamento.
/vision/label può riempire valori che l'etichetta non mostra? +
No. Trascrive la tabella e restituisce null per tutto ciò che non è stampato. Per un'interpretazione di quei numeri, invia l'id del prodotto collegato alla AI Food Analysis API.
Il limite di frequenza della visione è lo stesso del limite di frequenza della mia API? +
No. Le chiamate IA usano un bucket separato e più basso: 1/s su Free e Starter, 2/s su Pro, 5/s su Enterprise per chiave, e tre volte tanto su tutte le chiavi. Solo /vision/barcode usa il normale limite e la quota giornaliera dell'API dati.
Come controllo i crediti rimanenti senza spenderne? +
Chiama GET /v1/credits con la tua chiave. Restituisce piano, quota mensile, crediti usati e data del reset, e non conta né nei crediti né nella quota giornaliera.
Scopri altri endpoint
API di analisi alimentare IA
Una sola chiamata trasforma i dati grezzi di un prodotto in qualcosa che puoi mostrare a un utente: un riepilogo di due frasi, punti di forza e avvertenze calcolati dai dati nutrizionali con soglie pubblicate, gli allergeni dichiarati, la compatibilità con le diete che indica da dove viene ogni risposta e il livello di lavorazione — in sei lingue, basato rigorosamente sui dati d'etichetta del prodotto.
Scopri di più →API di ricerca per codici a barre
Scansiona o digita un codice a barre, ottieni il prodotto. Risolvi qualsiasi codice EAN-13 o UPC in un record alimentare — marca, categoria, Nutri-Score e riepilogo nutrizionale — con una sola richiesta. Pensata per le app basate su scanner.
Scopri di più →API nutrizionali
Vai oltre i macronutrienti principali. Ottieni il dettaglio di oltre 40 nutrienti per prodotto — energia, proteine, carboidrati, grassi, zuccheri, fibre, sodio, vitamine e minerali — tutti per 100 g, per qualsiasi alimento tramite ID.
Scopri di più →Inizia subito con API di riconoscimento di immagini di cibo
Gratis per iniziare. Nessuna carta di credito richiesta.
Ottieni la chiave API Vai alla dashboard