L’API Foodlex

Une recette entre en JSON, les valeurs calculées en ressortent en JSON : valeurs nutritionnelles, allergènes et liste d’ingrédients terminée. Pensée pour votre ERP, votre boutique ou votre propre outil — partout où les chiffres sont nécessaires sans que personne ait à les ressaisir dans l’application.

Trois points d’entrée

Tous sous https://app.foodlex.app/api/v1/, tous en POST.

Point d’entréeRéponse
/v1/nutrition Valeurs nutritionnelles pour 100 g, par portion et à cru — non arrondies pour poursuivre le calcul, avec en plus les valeurs arrondies de l’étiquette
/v1/allergens Les quatorze groupes d’allergènes de l’annexe II du règlement (UE) n° 1169/2011, avec leur position dans le texte
/v1/ingredient-list La liste des ingrédients, par ordre pondéral décroissant, avec la mise en évidence des allergènes et le QUID

Ce qu’elle ne fait pas

L’API est sans état : elle ne crée aucune recette, n’en lit aucune et ne modifie rien dans vos données. Chaque appel se suffit à lui-même — ce qui entre est calculé, et rien ne subsiste ensuite.

Elle ne recherche pas non plus les aliments. Les valeurs nutritionnelles de chaque ingrédient, c’est vous qui les fournissez. C’est volontaire : un chiffre que nous ajouterions discrètement depuis une base de données finit sur une étiquette dont quelqu’un d’autre répond. Si vous cherchez la base de données, utilisez l’application.

Authentification

Une clé, un en-tête :

Authorization: Bearer flx_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

La clé se compose de flx_live_ suivi de 32 caractères. Elle est affichée une seule fois, à sa création — seul son SHA-256 est conservé et elle ne peut pas être retrouvée dans la base. Perdue, elle se révoque et se remplace.

La clé se place sur un serveur, pas dans une page web. Une clé inscrite dans du JavaScript côté navigateur est une clé offerte à chaque visiteur. Et il n’existe volontairement aucun paramètre d’URL : une clé dans une URL se retrouve dans chaque journal d’accès et dans chaque référent.

Un appel complet

curl -sS https://app.foodlex.app/api/v1/nutrition \ -H "Authorization: Bearer $FOODLEX_KEY" \ -H 'Content-Type: application/json' \ -d '{ "market": "FR", "language": "fr", "preparationLossPercent": 12, "portions": 8, "ingredients": [ { "name": "Farine de blé T55", "amountGrams": 500, "nutrients": { "energyKj": 1443, "energyKcal": 341, "fat": 1.1, "fatSaturated": 0.2, "carbs": 71.8, "sugar": 1.2, "protein": 10.6, "salt": 0.01 } }, { "name": "Beurre", "amountGrams": 250, "nutrients": { "energyKj": 3059, "energyKcal": 741, "fat": 82.0, "fatSaturated": 52.0, "carbs": 0.6, "sugar": 0.6, "protein": 0.7, "salt": 0.02 } } ] }'

La réponse, abrégée :

{ "apiVersion": "1", "market": "FR", "language": "fr", "weights": { "rawGrams": 750, "finalGrams": 660, "portionGrams": 82.5 }, "per100g": { "energyKj": 2251.8939393939395, "energyKcal": 539.0151515151515, … }, "perPortion":{ "energyKj": 1857.8125, … }, "labelPer100g": { "energyKj": "2 252 kJ", "energyKcal": "539 kcal", "fat": "32 g", "fatSaturated": "20 g", "carbs": "55 g", "sugar": "1,1 g", "protein": "8,3 g", "salt": "0,02 g" }, "warnings": [] }
per100g n’est pas arrondi, toutes les décimales y sont. C’est volontaire : qui poursuit le calcul — vers une autre taille de portion, vers son propre tableau — ne doit pas partir d’une valeur intermédiaire arrondie. L’arrondi n’a lieu qu’une fois, à la fin, et c’est ce que contient labelPer100g.
Deux endroits où un programme trébuche. Entre le nombre et l’unité se trouve une espace insécable (U+00A0 ; le séparateur de milliers français est U+202F) — découper "32 g" sur une espace ordinaire ne donne rien. Et labelPer100g n’existe que pour DE, FR et GB, les trois sous droit de l’UE : l’Australie arrondit à trois chiffres significatifs, les États-Unis par paliers sur une portion RACC. Le champ y est absent et labelNote explique pourquoi, dans votre langue — une valeur mal arrondie a l’air juste. Les valeurs de per100g sont exactes pour chaque marché.

Marchés et langues

La requête transmet les deux, et les deux couvrent tout ce que couvre l’application :

market DE · FR · AU · US · GB — détermine le corpus de règles. Valeur par défaut DE
language de · en · fr — agit sur les messages, les dénominations et le format des nombres. Valeur par défaut de

Les identifiants des allergènes restent en anglais, même dans une réponse en français : ce sont des clés, pas un affichage. Le libellé lisible figure à côté, selon le marché et la langue.

Limites et quota

Corps de la requête1 Mo
Ingrédients par requête200
Texte pour /v1/allergens20 000 caractères
Appels par moisFree 0 · Starter 0 · Pro 2 000 · Team 20 000

Le décompte se fait par espace de travail, et non par clé : le quota tient à l’offre, et deux clés d’une même entreprise ne doivent pas se dégager mutuellement de la marge.

Erreurs

Une seule forme, sur tous les points d’entrée, quel que soit le statut :

{ "apiVersion": "1", "error": { "code": "bad_request", "message": "La requête ne correspond pas au schéma : …", "field": "ingredients[2].amountGrams" } }
StatutcodeQuand
400bad_requestLe corps n’est pas du JSON ou ne correspond pas au schéma
401unauthorizedClé absente, inconnue, révoquée ou expirée
403forbiddenL’offre de cet espace de travail exclut l’API
405method_not_allowedTous les points d’entrée sont en POST
413payload_too_largeCorps supérieur à 1 Mo
429quota_exceededQuota mensuel épuisé
500internal_errorImprévu
503unavailableLa vérification de la clé est injoignable

Gestion des versions

La version figure dans le chemin, et non dans un en-tête — elle apparaît ainsi dans chaque message d’erreur, dans chaque journal et dans chaque ligne d’exemple.

GarantiUn champ documenté en v1 ne disparaît pas et ne change pas de sens
GarantiUn champ inconnu dans la requête est ignoré, non rejeté
PossibleDe nouveaux champs dans la réponse — un client doit passer outre les champs qu’il ne connaît pas
Non garantiL’ordre des clés dans le JSON. Ni les chiffres eux-mêmes : si une règle d’arrondi ou un motif d’allergène est corrigé, le résultat change — c’est une correction, pas une rupture de contrat

Si un champ doit changer de sens, /api/v2/… apparaîtra à côté.

Obtenir une clé

L’API est comprise dans l’offre Pro et ne coûte rien de plus. Écrivez-moi ce que vous souhaitez en faire : je crée la clé et vous l’envoie par un canal qui ne la laisse pas traîner dans une boîte aux lettres.

La responsabilité reste la vôtre : Foodlex calcule et met en forme, et indique d’où vient chaque chiffre. La vérification technique et juridique avant impression incombe à celui qui met l’étiquette sur le marché.