API de consultation groupée d'aliments
Récupérez jusqu'à 100 aliments en une seule requête. Envoyez un tableau d'ID ou de codes-barres, recevez les fiches complètes ainsi que la liste de ce qui n'a pas été trouvé — idéal pour remplir un plan de repas, un panier, le journal alimentaire d'une journée ou un catalogue de produits scannés sans cent allers-retours.
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": []
} Vous préférez cliquer ? Essayez l'explorateur de produits ou le bac à sable photo.
Ce que vous obtenez
ids[]
De 1 à 100 ID d'aliments dans le corps de la requête — ou :
barcodes[]
De 1 à 100 codes-barres (GTIN-8/12/13/14), chacun résolu comme par l'API de recherche par code-barres, variantes avec zéros de tête comprises.
data[]
Fiches alimentaires complètes dans l'ordre demandé ; les recherches par code-barres ajoutent requested_barcode (le code envoyé).
not_found[]
Les ID ou codes-barres sans produit — pas d'erreur pour le lot.
?lang=
Facultatif : en/fr/es/de/it/bg, comme pour les consultations d'une seule fiche.
Disponible à partir du forfait Starter. Voir les forfaits →
Exemples de code
La même requête en curl, JavaScript et Python. Remplacez YOUR_API_KEY par une clé de votre tableau de bord.
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"]}'
const res = await fetch("https://foodbase.dev/v1/foods/bulk", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"ids": [
"62ea12b8-b260-c288-5c38-3a4906f5d6dd",
"2fc13a3b-1913-5ab6-d2c7-8c09b56f93bb"
]
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
import requests
res = requests.post(
"https://foodbase.dev/v1/foods/bulk",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"ids": [
"62ea12b8-b260-c288-5c38-3a4906f5d6dd",
"2fc13a3b-1913-5ab6-d2c7-8c09b56f93bb"
]
},
timeout=30,
)
res.raise_for_status()
data = res.json()
Comment ça marche
La requête, étape par étape
POST /v1/foods/bulk avec Content-Type: application/json, votre en-tête X-API-Key et un corps de la forme {"ids": [...]} ou {"barcodes": [...]} — exactement l'un des deux, de 1 à 100 entrées. Les ids sont des chaînes UUID (celles des exemples de code ci-dessus sont de vraies fiches pour vos tests) ; les codes-barres sont résolus exactement comme par GET /v1/foods/barcode/{code} : un EAN-13 trouve un produit enregistré sous sa forme UPC-12 ou GTIN-14, et le champ barcode de la fiche indique la forme enregistrée à côté de requested_barcode.
La validation a lieu avant tout accès à la base et c'est tout ou rien. Un code-barres dans ids, les deux champs ou aucun, un tableau vide ou 101 entrées rejettent tout le lot avec 422 {"error": "Validation Error", "details": [{"field": "ids.3", "message": ...}]}. Un paramètre facultatif ?lang= (en, fr, es, de, it, bg) traduit les libellés de catégorie et d'allergènes comme pour les consultations d'une seule fiche ; les noms et ingrédients dans d'autres langues se trouvent dans les tableaux name et ingredients.
Lire la réponse
data est un tableau d'objets FoodItem construits par le même formateur que l'API de base de données alimentaire : un parseur écrit pour la fiche unique fonctionne tel quel, de id, barcode et source jusqu'à categories_tags, image_url et allergens. Les données manquantes à la source valent null, jamais une clé absente.
nutrition_summary contient energy_kcal, proteins_g, carbs_g, fat_g, sugars_g et fiber_g pour 100 g. Il ne vaut null en entier que lorsque le produit n'a aucune ligne de nutriments ; une ligne à laquelle il manque une valeur affiche null pour cette seule clé. Les textes d'étiquette comme quantity et serving_size_raw arrivent exactement tels que les contributeurs les ont saisis : analysez-les avec prudence.
Éléments manquants, doublons et dérive
La réponse peut être plus courte que la requête : il n'y a pas de 404 par élément, mais chaque id ou code-barres sans produit figure dans not_found, dans l'ordre de la requête — inutile de comparer vous-même. Un id ou un code-barres présent deux fois revient comme une seule fiche : dédoublonnez avant l'envoi pour que chacune des 100 places serve.
Les id sont déterministes, dérivés de la source et de son propre identifiant produit : un produit garde son id d'une réimportation à l'autre. Si un id stocké ne se résout plus, le produit n'est plus dans le catalogue sous cette identité : marquez la ligne comme périmée et résolvez-la à nouveau via l'API de recherche par code-barres ou l'API de recherche alimentaire plutôt que de la supprimer.
Calcul du quota et des limites de débit
Un appel groupé compte pour une requête dans le quota quotidien et un jeton du compteur par seconde, quel que soit le nombre d'id. L'ordre des middlewares est authentification, limite par seconde, contrôle du forfait, puis quota quotidien : un 401, un 429 de limite de débit ou le 403 Starter ne consomment jamais de requête quotidienne. Un 422, si, car la validation a lieu après le décompte du quota ; vérifiez les UUID côté client.
Lisez les en-têtes de chaque 200 : X-RateLimit-Second-Limit, X-RateLimit-Burst-Capacity et X-RateLimit-Second-Remaining pour le compteur par clé, X-RateLimit-Account-Limit et X-RateLimit-Account-Remaining pour l'agrégat par seconde de toutes les clés du compte, et X-RateLimit-Daily-Limit, X-RateLimit-Daily-Remaining et X-RateLimit-Daily-Reset (sur les comptes normaux) pour le budget quotidien partagé et sa réinitialisation à minuit UTC. Le POST ne porte pas d'en-tête Cache-Control, rien n'est donc mis en cache en périphérie pour vous : stockez ce que vous récupérez.
Synchroniser un catalogue chaque nuit
Pour l'assortiment d'un distributeur, envoyez directement les codes-barres, 100 par appel, ou enregistrez l'id renvoyé à côté de votre référence et synchronisez ensuite par id. Dans les deux cas, la tâche nocturne ne cherche jamais : elle lit les codes stockés, les dédoublonne, les découpe en groupes de 100, envoie chaque groupe ici et enregistre un point de reprise après chaque groupe terminé, pour qu'un catalogue plus grand que le budget d'une nuit reprenne là où il s'est arrêté. Comparez updated_at avec votre copie pour savoir ce qui a changé.
Réglez le rythme d'après les en-têtes plutôt qu'avec une pause fixe, et surveillez X-RateLimit-Daily-Remaining pour que la synchronisation n'affame pas le trafic de journée du même compte. Quand une vue a besoin du tableau de 40+ nutriments, appelez l'API de nutrition pour cet id à la demande ; elle prend un id par requête et compte aussi comme une requête.
- Dédoublonnez les id, découpez par 100, point de reprise par groupe.
- Marquez tout ce qui figure dans not_found comme périmé ; revérifiez plus tard.
- Récupérez /nutrients à la demande, produit par produit, pas dans la synchronisation.
Ce que vous pouvez créer
Plans de repas et journaux alimentaires
Résolvez tous les éléments du plan d'une journée en un appel.
Remplissage de panier
Transformez efficacement une liste d'ID d'aliments enregistrés en fiches complètes.
Tâches de synchronisation
Rafraîchissez de nombreux aliments en cache par lots, selon un calendrier.
Limites par forfait
| Free | Non disponible : 403 avec required_plan starter (non décompté des 100 requêtes/jour) |
|---|---|
| Starter | 5 000 requêtes/jour, 5/s en continu, rafale de 25 ; jusqu'à 100 id ou codes-barres par requête |
| Pro | 25 000 requêtes/jour, 20/s en continu, rafale de 100 ; jusqu'à 100 id ou codes-barres par requête |
| Enterprise | 100 000 requêtes/jour, 50/s en continu, rafale de 250 ; jusqu'à 100 id ou codes-barres par requête |
Chaque réponse contient des en-têtes X-RateLimit-* indiquant le budget restant ; chaque 429 contient Retry-After . Comparer les forfaits →
Erreurs et comment les gérer
403 — Compte Free ; le corps contient l'erreur Plan upgrade required, required_plan starter, current_plan free et une upgrade_url
Passez au forfait supérieur via l'upgrade_url, ou utilisez GET /v1/foods/{id} sur Free
422 — Aucun ou les deux champs ids et barcodes ; un tableau vide ou de plus de 100 éléments ; un non-UUID dans ids ou un code-barres vide ; details[] indique la position en échec
Validez et dédoublonnez côté client ; envoyez les codes-barres dans barcodes[], pas dans ids[]
429 — Compteur par clé ou du compte vide, ou X-RateLimit-Daily-Remaining arrivé à 0 (corps : Daily quota exceeded)
Patientez pendant Retry-After secondes ; dans le cas quotidien, c'est le temps restant jusqu'à minuit UTC
401 — En-tête X-API-Key absent, ou clé invalide ou révoquée
Vérifiez le nom de l'en-tête et la clé dans le tableau de bord
503 — Le stockage du quota ou des limites de débit est injoignable ; l'API refuse par sécurité
Réessayez avec un délai croissant ; la requête n'a pas été décomptée
Comparaison avec d'autres API
Par rapport au GET d'une fiche unique, le gain porte sur les allers-retours et le quota : 100 fiches pour une requête au lieu de 100 requêtes. Le GET l'emporte quand de nombreux clients lisent le même produit populaire, car ses réponses peuvent être mises en cache 300 secondes par n'importe quel cache HTTP et il accepte lang ; la consultation groupée n'est pas mise en cache et alimente votre propre stockage. L'API de recherche alimentaire et l'API de recherche par code-barres transforment un texte ou un GTIN en id ; cet endpoint transforme des id que vous détenez déjà en fiches. L'API de nutrition va dans l'autre sens : le tableau complet d'un produit au lieu de six valeurs résumées pour jusqu'à 100.
Voir la comparaison complète des API de données alimentaires →
Questions fréquentes
Puis-je envoyer des codes-barres ou des termes de recherche au lieu d'id ? +
Non. Chaque entrée doit être un UUID, sinon tout le lot est rejeté avec 422. Résolvez les codes-barres via l'API de recherche par code-barres et les noms via l'API de recherche alimentaire, stockez les id, puis utilisez-les ici.
Un appel avec 100 id coûte-t-il 100 requêtes ? +
Non, il en coûte une. Le compteur quotidien et le compteur par seconde avancent chacun d'une unité par requête, quel que soit le nombre d'id qu'elle contient.
Pourquoi n'y a-t-il pas de paramètre lang ? +
La consultation groupée renvoie la fiche brute sans les champs localisés d'appoint. Les tableaux name et ingredients contiennent toutes les langues fournies par les contributeurs : choisissez l'entrée côté client ; si vous avez besoin de category_localized ou d'allergens_localized, utilisez GET /v1/foods/{id}?lang= pour ce produit.
Que voit un compte Free ? +
Un 403 avec l'erreur Plan upgrade required, required_plan starter et une upgrade_url pointant vers la page de facturation. Le contrôle a lieu avant le quota quotidien : ces 403 n'entament donc pas les 100 requêtes par jour, et GET /v1/foods/{id} reste disponible.
Puis-je obtenir le détail nutritionnel complet en lot ? +
Non. Les fiches groupées ne contiennent que nutrition_summary. Le tableau de 40+ nutriments vient de l'API de nutrition, un id par requête ; à partir de Starter, elle n'a pas de plafond quotidien séparé, sur Free elle est limitée à 25 par jour.
Découvrez d'autres endpoints
API de recherche alimentaire
Recherche plein texte dans 6,1 millions de produits alimentaires par nom, marque ou catégorie — classée par pertinence, paginée et rapide. Cherchez dans la langue imprimée sur l'étiquette (cyrillique compris) et passez lang=en|fr|es|de|it|bg pour obtenir les noms, catégories et allergènes localisés. Une seule requête GET renvoie un JSON propre que votre application peut afficher immédiatement.
En savoir plus →API de nutrition
Allez au-delà des macros principales. Obtenez le détail de plus de 40 nutriments par produit — énergie, protéines, glucides, lipides, sucres, fibres, sodium, vitamines et minéraux — tous pour 100 g, pour n'importe quel aliment par ID.
En savoir plus →API de base de données alimentaire
Une source unique pour 6,1 millions d'aliments. Récupérez une fiche produit complète par ID — nom, marque, ingrédients, allergènes, Nutri-Score, groupe NOVA, images, et plus encore.
En savoir plus →Commencez à développer avec l'API de consultation groupée d'aliments
Gratuit pour démarrer. Sans carte bancaire.
Obtenir une clé API Aller au tableau de bord