Crediti IA

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.

200 OK
POST /v1/vision/product
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]"
            

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.

Vedi il confronto completo delle API di dati alimentari →

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.

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