Documentation API

Documentation de l'API Nectar

Huit endpoints sur la base nutritionnelle Nectar : recherche d'aliments, scan de code-barres, analyse de repas par IA depuis une photo ou un texte, et calculs nutritionnels.

L'API Nectar donne accès à notre base nutritionnelle et à nos moteurs d'analyse. Huit endpoints, une clé, un seul compteur.

URL de base : https://app.mynectarapp.com/api/public/v1

Aliments10k+, dont 8k+ produits de marque
Nutriments par aliment~100
Portions ménagères24k
Produits scannables7k+
Couverture du score NOVA98 %
Tranches d'apports de référence772

Authentification

Chaque requête porte votre clé dans l'en-tête x-api-key. Les clés commencent par nec_ et vous sont délivrées par votre interlocuteur Nectar. Tous les endpoints sont en POST, avec un corps JSON.

curl -X POST https://app.mynectarapp.com/api/public/v1/food/search \
  -H "x-api-key: nec_votre_cle_ici" \
  -H "Content-Type: application/json" \
  -d '{"search": "pomme"}'

N'exposez jamais votre clé dans du code client — page web, application mobile, dépôt public. Elle appelle l'API en votre nom et consomme votre quota. Passez toujours par votre serveur.

Comprendre les jetons

Un seul compteur pour tout. Chaque appel consomme un nombre de jetons connu à l'avance, rappelé dans la réponse par tokensCharged. Le compteur repart à zéro le 1er de chaque mois.

Le barème

AppelJetonsCe que vous recevez
food/search1Jusqu'à 50 aliments : identité, traductions, calories, macronutriments
portions/convert1Une portion ménagère convertie en grammes
nutrition/reference-intakes1Les apports de référence d'une personne
food/details/{id}1 à 81 de base, +1 par bloc de nutriments, +1 pour les portions
food/barcode2Le produit correspondant au code-barres
nutrition/compute2 +Le bilan d'un repas. +1 par bloc de nutriments.
meal/parse10Un repas décrit en texte, transformé en aliments et quantités
vision/analyze25Une photo de repas, transformée en aliments et quantités

Servir une ligne d'aliment ne nous coûte quasiment rien : les endpoints sur la base et les calculs sont à 1 ou 2 jetons. Une analyse par IA mobilise un modèle à chaque appel : elle coûte 10 ou 25 jetons. C'est la seule raison de l'écart.

Dépassement : deux comportements

Sur la base et les calculs, dépasser votre quota n'interrompt rien. Les requêtes continuent d'aboutir, l'excédent est relevé et fait l'objet d'un échange.

Sur les deux endpoints d'IA, le quota est bloquant. Une fois les jetons épuisés, ils répondent 402 jusqu'à la réinitialisation — et le modèle n'est jamais appelé, donc un appel refusé n'est jamais facturé.

Suivre sa consommation

Chaque réponse porte l'état de votre quota :

X-Token-Quota-Month: 15000
X-Token-Used-Month:  11240
X-Token-Remaining:   3760

Déclenchez votre alerte sur X-Token-Remaining : c'est ce qui vous évite de découvrir un 402 en pleine journée.

Limites de débit

Indépendantes du quota mensuel. 60 requêtes par minute et 1 000 par heure par défaut, ajustables par clé. Au-delà, l'API répond 429 avec les en-têtes X-RateLimit-Limit-Minute et X-RateLimit-Limit-Hour. Prévoyez une reprise avec délai progressif.

Rechercher un aliment

POST /food/search — 1 jeton

Recherche floue et insensible aux accents sur tout le catalogue. Renvoie une liste allégée avec un lien detailsUrl par aliment. Un jeton quel que soit le nombre de résultats.

ParamètreRequisDescription
searchOui2 caractères minimum. La correspondance est floue : tommate trouve Tomate.
typeNonbase (génériques) ou commercial (marques). Les deux par défaut.
limitNonRésultats par page, 50 au maximum et par défaut.
offsetNonRésultats à ignorer. 0 par défaut.

Une recherche renvoie au maximum 50 aliments. Pour atteindre un produit précis, passez par son code-barres ou par le detailsUrl d'un résultat plutôt que par une pagination profonde.

{
  "data": [
    {
      "id": "53bff494-e435-5cfd-b8e4-529668939d5d",
      "type": "base",
      "label": "Pomme, crue",
      "brand": null,
      "trueCalories": 52,
      "rawCalories": 54,
      "translations": { "fr": { "label": "Pomme, crue" }, "en": { "label": "Apple, raw" } },
      "nutrients": [],
      "detailsUrl": "https://.../food/details/53bff494-..."
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0,
  "tokensCharged": 1
}

Scanner un code-barres

POST /food/barcode — 2 jetons

Résolution exacte d'un code-barres vers sa fiche Nectar. 7k+ produits du catalogue en portent un. La réponse a exactement la forme d'un résultat de recherche, ce qui permet de partager le même code de traitement.

curl -X POST https://app.mynectarapp.com/api/public/v1/food/barcode \
  -H "x-api-key: nec_votre_cle_ici" \
  -H "Content-Type: application/json" \
  -d '{"barcode": "3017620422003"}'

La recherche porte uniquement sur les produits de marque. Un code-barres absent du catalogue renvoie 404 et n'est pas facturé.

Fiche détaillée

POST /food/details/{id} — 1 à 8 jetons

La fiche complète d'un aliment. Vous ne payez que ce que vous demandez : un jeton pour la base, puis un jeton par bloc de nutriments et un pour les portions.

BlocContenuCoût
fatty-acidAcides gras et lipides, cholestérol inclus+1
vitaminVitamines+1
mineralMinéraux et oligo-éléments+1
amino-acidAcides aminés essentiels+1
sugarSucres et polyols+1
novaScore de transformation NOVA, de 1 à 4+1
withPortions: trueLes portions ménagères de l'aliment+1
# Vitamines + minéraux + NOVA + portions = 1 + 3 + 1 = 5 jetons
curl -X POST https://app.mynectarapp.com/api/public/v1/food/details/53bff494-... \
  -H "x-api-key: nec_votre_cle_ici" \
  -H "Content-Type: application/json" \
  -d '{"blocks": ["vitamin", "mineral", "nova"], "withPortions": true}'

Une recherche pour trouver, puis un détail uniquement sur l'aliment réellement retenu par l'utilisateur. Demander tous les blocs sur l'ensemble des résultats d'une recherche multiplie la facture sans bénéfice : la plupart ne seront jamais affichés.

Analyser une photo de repas

POST /vision/analyze — 25 jetons · quota bloquant

Une photo entre, les aliments qu'elle montre sortent — matchés dans la base, avec une estimation de poids. C'est le même moteur que celui qu'utilisent les diététiciennes dans Nectar.

ParamètreRequisDescription
photoOuiData URL en base64. JPEG, PNG, GIF ou WebP, jusqu'à 10 Mo décodés.
noteNonCe qu'était le repas, en texte libre, 500 caractères maximum.

La note fait autorité sur la photo. Contre-intuitif mais vérifié : une photo ne distingue pas la semoule du boulgour, le veau du porc, ni un yaourt à 0 % d'un yaourt entier. Quand la note nomme un aliment, elle est suivie. La photo reste seule maîtresse de ce qu'elle seule peut donner : les quantités, les aliments oubliés et le mode de cuisson.

{
  "data": {
    "dish": { "query": "pad thaï", "confidence": 0.92, "grams": 320, "candidates": [] },
    "foods": [
      {
        "query": "filet de saumon",
        "grams": 120,
        "unitCount": 0,
        "confidence": 0.9,
        "needsReview": false,
        "candidates": []
      }
    ],
    "suggestions": [{ "query": "huile d'olive", "reason": "Aspect brillant", "grams": 10 }],
    "cookingMethod": "grill"
  },
  "tokensCharged": 25
}
ChampÀ quoi il sert
dishLe plat entier, quand le modèle reconnaît une recette que nous avons. Permet d'enregistrer un repas en une étape au lieu de confirmer sept ingrédients. null est le cas normal.
foods[].gramsLe poids à enregistrer. Pas toujours l'estimation brute du modèle : un aliment compté à l'unité est pesé par notre portion.
foods[].unitCountUnités entières comptées. 0 pour tout ce qui se mesure en vrac.
needsReviewtrue en dessous de 0,7 de confiance. À faire confirmer.
suggestionsIngrédients que la photo implique sans les montrer : huile, beurre, sel. Proposés avec une raison, jamais ajoutés d'office. Un même aliment peut y figurer deux fois, pour deux raisons différentes.

Faites confirmer avant d'enregistrer. Chaque aliment arrive avec une confiance et jusqu'à trois candidats précisément pour qu'un humain corrige le choix. C'est ainsi que la fonctionnalité est utilisée dans Nectar.

Aucune photo n'est conservée. L'image est analysée puis écartée, jamais écrite sur nos disques. Seul le résultat vous est renvoyé.

Analyser un repas écrit

POST /meal/parse — 10 jetons · quota bloquant

« 2 œufs et 150 g de riz » devient la même liste structurée qu'une photo. À utiliser partout où vos utilisateurs écrivent plutôt qu'ils ne photographient : un champ de saisie rapide, une transcription vocale, un agent conversationnel.

ParamètreRequisDescription
textOuiLe repas en texte libre, 1 000 caractères maximum. Le français donne les meilleurs résultats.

Réponse de forme identique à celle de la photo — un seul analyseur pour les deux endpoints.

Une quantité énoncée fait foi. C'est la seule différence de comportement avec la photo, et elle compte si vous comparez les résultats. 150 g de riz renvoie 150 g, sans réestimation. deux œufs renvoie 2 unités, et les grammes viennent de notre portion. une cuillère à soupe d'huile est convertie. Sans quantité, la portion est standard et la confiance baisse.

curl -X POST https://app.mynectarapp.com/api/public/v1/meal/parse \
  -H "x-api-key: nec_votre_cle_ici" \
  -H "Content-Type: application/json" \
  -d '{"text": "2 œufs brouillés et 150 g de riz complet"}'

Bilan d'un repas

POST /nutrition/compute — 2 jetons + 1 par bloc

Une liste d'aliments et de poids, le bilan nutritionnel complet. Les mêmes blocs que la fiche détaillée s'appliquent, au même tarif.

{
  "items": [
    { "foodId": "53bff494-...", "grams": 150 },
    { "foodId": "a7c21e08-...", "grams": 120 }
  ],
  "blocks": ["vitamin"]
}

La réponse porte trois vues du même calcul :

ChampCe que c'est
totalCe que le repas délivre réellement. La valeur qu'un journal alimentaire enregistre.
per100gLa densité du mélange. Ce qu'une étiquette afficherait, et ce qui permet de comparer deux plats.
items[]La contribution de chaque aliment, pour un détail ou un recalcul de votre côté.
totalGramsLe poids combiné.
unknownFoodIdsLes identifiants que nous ne portons pas. Le reste est calculé quand même.

50 aliments au maximum. Si tous les identifiants sont inconnus, l'appel renvoie 404 et n'est pas facturé.

Convertir une portion

POST /portions/convert — 1 jeton

« 1 bol de riz » devient 200 g. Nectar en détient 24k, aliment par aliment — parce qu'un bol de riz et un bol de soupe ne pèsent pas la même chose, et qu'aucune table générique ne peut le dire.

ParamètreRequisDescription
foodIdOuiL'aliment concerné
labelNonLe nom de la portion. Insensible à la casse et aux accents, et tolérant au fragment. Omettez-le pour lister toutes les portions.
quantityNonCombien de portions. 1 par défaut.

La liste complète des portions revient même sur un libellé introuvable, pour que vous puissiez montrer ce que l'aliment propose. L'appel est facturé dans les deux cas : la recherche a eu lieu.

curl -X POST https://app.mynectarapp.com/api/public/v1/portions/convert \
  -H "x-api-key: nec_votre_cle_ici" \
  -H "Content-Type: application/json" \
  -d '{"foodId": "f14b1be0-...", "label": "filet", "quantity": 2}'

Apports de référence

POST /nutrition/reference-intakes — 1 jeton

Combien de chaque nutriment une personne donnée devrait recevoir. C'est ce qui transforme un chiffre en jugement : afficher « 12 mg de fer » ne dit rien, afficher « 150 % de la référence pour une femme de 30 ans » est la fonctionnalité.

ParamètreRequisValeurs
ageOuiEn années, de 0 à 130
genderOuimale ou female
pregnancyStatusNonnot_pregnant (défaut), pregnant, lactation. Valide uniquement avec female.

Une recommandation est un intervalle, pas une cible. min est l'apport à atteindre, max le plafond à ne pas dépasser, et l'un des deux peut être null : beaucoup de nutriments ont un plancher sans limite haute connue, quelques-uns l'inverse.

Le statut de grossesse change réellement les valeurs : 23 nutriments diffèrent entre une femme enceinte et non enceinte. La caféine passe de 400 à 200 mg, l'iode de 150 à 220 µg. C'est la même résolution que celle utilisée par l'application Nectar, donc vos chiffres correspondent à ce qu'une diététicienne verrait.

L'objet aliment

ChampDescription
idIdentifiant stable, utilisable partout ailleurs
typebase (générique) ou commercial (marque)
labelNom interne de l'aliment
brandMarque, pour les produits commerciaux
trueCaloriesCalories réellement métabolisées pour 100 g, selon la formule Nectar
rawCaloriesCalories brutes pour 100 g, méthode Atwater standard
translationsLibellés français et anglais, indexés par code de langue
nutrientsValeurs pour 100 g, avec identifiant USDA, unité et source
portionsPortions ménagères en grammes, sur la fiche détaillée
novaScoreDegré de transformation de 1 à 4, si le bloc a été demandé

Affichez les traductions, pas le libellé. label est notre nom interne et sa langue varie d'une fiche à l'autre — une même réponse peut mêler « Purée de pomme de terre » et « Salmon, wild ». translations.fr et translations.en sont renseignées pour tous les aliments : ce sont elles que vos utilisateurs doivent voir.

Deux mesures de calories. trueCalories est la valeur propre à Nectar : elle tient compte de ce que l'organisme absorbe réellement, là où rawCalories propose la mesure calorique brute, selon le calcul standard Atwater. L'écart est net sur les fibres et sur les paramètres d'absorption et de métabolisation (CUD et ADS). Affichez celle qui correspond à ce que vous promettez à vos utilisateurs.

Codes d'erreur

CodeSignificationQue faire
400Paramètre manquant ou invalideLe message dit lequel
401Clé absente, mal formée ou inconnueVérifier l'en-tête et le préfixe nec_
402Quota épuisé sur un endpoint d'IAAttendre la réinitialisation ou changer de formule. Non facturé.
403Clé désactivéeContacter votre interlocuteur Nectar
404Ressource introuvableIdentifiant, code-barres ou aliments inconnus. Non facturé.
413Photo trop volumineuseAu-delà de 10 Mo décodés
429Limite de débit atteinteRéessayer avec un délai progressif
500Erreur serveurRéessayer ; nous signaler si cela persiste

Version 1 de l'API. Toute évolution incompatible fera l'objet d'un préavis et d'une nouvelle version ; la v1 restera servie.

Dernière mise à jour : 11 septembre 2026