Piano Starter

API di ricerca multipla di alimenti

Ottieni fino a 100 alimenti in un'unica richiesta. Invia un array di ID o di codici a barre e ricevi le schede complete, più l'elenco di ciò che non è stato trovato: ideale per riempire un piano alimentare, un carrello, il diario alimentare di una giornata o un catalogo di prodotti scansionati senza cento andate e ritorno.

200 OK
POST /v1/foods/bulk
curl -X POST -H "X-API-Key: food_•••" \
  -H "Content-Type: application/json" \
  -d '{"ids":["62ea12b8...","2fc13a3b..."]}' \
  "https://foodbase.dev/v1/foods/bulk"

{
  "data": [
    { "id": "62ea12b8...", "name_default": "Original Taste", "brand": "Coca-Cola" },
    { "id": "2fc13a3b...", "name_default": "Nutella", "brand": "Ferrero" }
  ],
  "not_found": []
}

Preferisci cliccare? Prova l'esploratore di prodotti o l'area di prova foto.

Cosa ottieni

ids[]

Da 1 a 100 ID di alimenti nel corpo della richiesta, oppure:

barcodes[]

Da 1 a 100 codici a barre (GTIN-8/12/13/14), ognuno risolto come nell'API di ricerca per codice a barre, varianti con zeri iniziali comprese.

data[]

Schede complete nell'ordine richiesto; le ricerche per codice a barre aggiungono requested_barcode (il codice inviato).

not_found[]

Gli ID o i codici a barre senza prodotto, nessun errore per il lotto.

?lang=

Facoltativo: en/fr/es/de/it/bg, come nelle ricerche di una singola scheda.

Disponibile dal piano Starter in su. 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/foods/bulk" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":["62ea12b8-b260-c288-5c38-3a4906f5d6dd","2fc13a3b-1913-5ab6-d2c7-8c09b56f93bb"]}'
            

Come funziona

La richiesta, passo per passo

POST /v1/foods/bulk con Content-Type: application/json, la tua intestazione X-API-Key e un corpo della forma {"ids": [...]} o {"barcodes": [...]}: esattamente uno dei due, da 1 a 100 voci. Gli ids sono stringhe UUID (quelli degli esempi di codice qui sopra sono schede reali con cui fare prove); i codici a barre vengono risolti esattamente come con GET /v1/foods/barcode/{code}, quindi un EAN-13 trova anche un prodotto salvato nella sua forma UPC-12 o GTIN-14, e il campo barcode della scheda mostra la forma salvata accanto a requested_barcode.

La validazione avviene prima di toccare il database ed è tutto o niente. Un codice a barre dentro ids, entrambi i campi o nessuno, un array vuoto o 101 voci rifiutano l'intero lotto con 422 {"error": "Validation Error", "details": [{"field": "ids.3", "message": ...}]}. Un ?lang= facoltativo (en, fr, es, de, it, bg) localizza le etichette di categoria e allergeni come nelle ricerche di una singola scheda; nomi e ingredienti in altre lingue si trovano negli array name e ingredients.

Leggere la risposta

data è un array di oggetti FoodItem costruiti dallo stesso formattatore della Food Database API, quindi un parser scritto per il singolo record funziona senza modifiche, da id, barcode e source fino a categories_tags, image_url e allergens. I dati mancanti nella fonte sono null, mai una chiave assente.

nutrition_summary contiene energy_kcal, proteins_g, carbs_g, fat_g, sugars_g e fiber_g per 100 g. È null per intero solo quando il prodotto non ha alcuna riga di nutrienti; una riga a cui manca un valore mostra null solo per quella chiave. Testi d'etichetta come quantity e serving_size_raw arrivano esattamente come li hanno digitati i contributori, quindi analizzali in modo difensivo.

Voci mancanti, duplicati e deriva

La risposta può essere più corta della richiesta: non c'è un 404 per voce, ma ogni id o codice a barre senza prodotto è elencato in not_found, nell'ordine della richiesta, quindi non devi mai confrontarli tu. Un id o un codice a barre inviato due volte torna come una sola scheda: elimina i duplicati prima dell'invio, così ognuno dei 100 posti conta.

Gli id sono deterministici, derivati dalla fonte e dal suo identificativo di prodotto, quindi un prodotto mantiene il suo id tra le reimportazioni. Se un id salvato smette di risolversi, il prodotto non è più nel catalogo con quell'identità: segna la riga come obsoleta e risolvila di nuovo con la Barcode Lookup API o la Food Search API invece di eliminarla.

Quota e calcolo dei limiti

Una chiamata bulk è una richiesta contro la quota giornaliera e un token dal bucket al secondo, qualunque sia il numero di id. L'ordine del middleware è autenticazione, limite al secondo, controllo del piano, poi quota giornaliera, quindi un 401, un 429 per limite di frequenza o il 403 per Starter non consumano mai una richiesta giornaliera. Un 422 sì, perché la convalida avviene dopo il conteggio della quota; controlla gli UUID lato client.

Leggi gli header a ogni 200: X-RateLimit-Second-Limit, X-RateLimit-Burst-Capacity e X-RateLimit-Second-Remaining per il bucket per chiave, X-RateLimit-Account-Limit e X-RateLimit-Account-Remaining per l'aggregato al secondo su tutte le chiavi dell'account, e X-RateLimit-Daily-Limit, X-RateLimit-Daily-Remaining e X-RateLimit-Daily-Reset (sugli account normali) per il budget giornaliero condiviso e il suo reset a mezzanotte UTC. La POST non porta alcun header Cache-Control, quindi nulla viene messo in cache dall'edge per te: conserva ciò che recuperi.

Sincronizzare un catalogo ogni notte

Per l'assortimento di un rivenditore, invia direttamente i codici a barre, 100 per chiamata, oppure salva l'id restituito accanto al tuo SKU e sincronizza poi per id. In entrambi i casi il job notturno non cerca mai: legge i codici salvati, elimina i duplicati, li divide in gruppi da 100, invia ogni gruppo qui e salva un checkpoint dopo ogni gruppo completato, così un catalogo più grande del budget di una notte riprende da dove si era fermato. Confronta updated_at con la tua copia per sapere cosa è cambiato.

Regola il ritmo in base agli header invece che con una pausa fissa, e tieni d'occhio X-RateLimit-Daily-Remaining affinché la sincronizzazione non affami il traffico diurno sullo stesso account. Quando una vista richiede la tabella di oltre 40 nutrienti, chiama la Nutrition API per quell'id su richiesta; accetta un id per richiesta e conta anch'essa come richiesta.

  • Deduplica gli id, dividi a blocchi di 100, registra un checkpoint per blocco.
  • Segna come obsoleto tutto ciò che è in not_found; ricontrollalo più tardi.
  • Recupera /nutrients in modo pigro, per prodotto, non nella sincronizzazione.

Cosa puoi costruire

Piani alimentari e diari alimentari

Risolvi ogni voce del piano di una giornata con una sola chiamata.

Idratazione del carrello

Trasforma un elenco di ID di alimenti salvati in record completi in modo efficiente.

Job di sincronizzazione

Aggiorna molti alimenti in cache a lotti, con una pianificazione.

Limiti per piano

Free Non disponibile: 403 con required_plan starter (non conta nelle 100 richieste/giorno)
Starter 5.000 richieste/giorno, 5/s costanti, burst 25; fino a 100 ID o codici a barre per richiesta
Pro 25.000 richieste/giorno, 20/s costanti, burst 100; fino a 100 ID o codici a barre per richiesta
Enterprise 100.000 richieste/giorno, 50/s costanti, burst 250; fino a 100 ID o codici a barre per richiesta

Ogni risposta include gli header X-RateLimit-* con il budget residuo; ogni 429 include Retry-After . Confronta i piani →

Errori e come gestirli

403 — Account Free; il corpo ha error Plan upgrade required, required_plan starter, current_plan free e un upgrade_url

Passa a un piano superiore all'upgrade_url, oppure usa GET /v1/foods/{id} su Free

422 — Nessuno o entrambi i campi ids e barcodes; un array vuoto o con più di 100 voci; un non-UUID in ids o un codice a barre vuoto; details[] indica la posizione non valida

Valida ed elimina i duplicati lato client; invia i codici a barre in barcodes[], non in ids[]

429 — Bucket per chiave o per account vuoto, oppure X-RateLimit-Daily-Remaining è arrivato a 0 (corpo: Daily quota exceeded)

Attendi Retry-After secondi; nel caso della quota giornaliera è il tempo fino a mezzanotte UTC

401 — Header X-API-Key mancante, oppure la chiave non è valida o è stata revocata

Controlla il nome dell'header e la chiave nella dashboard

503 — L'archivio di quota o limiti di frequenza non è raggiungibile; l'API si blocca per sicurezza

Riprova con backoff; la richiesta non è stata conteggiata

Confronto con altre API

Rispetto alla GET sul singolo record, il guadagno sta in round-trip e quota: 100 record con una richiesta invece di 100 richieste. La GET vince quando molti client leggono lo stesso prodotto molto richiesto, perché le sue risposte sono memorizzabili per 300 secondi da qualsiasi cache HTTP e accetta lang; il bulk non è memorizzabile in cache e serve a riempire il tuo archivio. La Food Search API e la Barcode Lookup API trasformano testo o un GTIN in un id; questo endpoint trasforma gli id che già possiedi in record. La Nutrition API va nella direzione opposta: la tabella completa per un solo prodotto invece di sei valori di riepilogo per un massimo di 100.

Vedi il confronto completo delle API di dati alimentari →

Domande frequenti

Posso inviare codici a barre o termini di ricerca al posto degli id? +

No. Ogni voce deve essere un UUID, altrimenti l'intero batch viene rifiutato con 422. Risolvi i codici a barre con la Barcode Lookup API e i nomi con la Food Search API, salva gli id, poi usali qui.

Una chiamata con 100 id costa 100 richieste? +

No, ne costa una. Il contatore giornaliero e il bucket al secondo avanzano ciascuno di uno per richiesta, a prescindere da quanti id contiene.

Perché non c'è un parametro lang? +

Il bulk restituisce il record grezzo senza i campi di supporto localizzati. Gli array name e ingredients contengono ogni lingua fornita dai contributori, quindi scegli la voce lato client; se ti servono category_localized o allergens_localized, usa GET /v1/foods/{id}?lang= per quel prodotto.

Cosa vede un account Free? +

Un 403 con error Plan upgrade required, required_plan starter e un upgrade_url che punta alla pagina di fatturazione. Il controllo avviene prima della quota giornaliera, quindi quei 403 non consumano le 100 richieste al giorno, e GET /v1/foods/{id} resta disponibile.

Posso ottenere il dettaglio completo dei nutrienti in bulk? +

No. I record bulk contengono solo nutrition_summary. La tabella di oltre 40 nutrienti viene dalla Nutrition API, un id per richiesta; dallo Starter in su non ha un limite giornaliero separato, su Free è limitata a 25 al giorno.

Inizia subito con API di ricerca multipla di alimenti

Gratis per iniziare. Nessuna carta di credito richiesta.

Ottieni la chiave API Vai alla dashboard