AI кредити

API за AI анализ на храни

Едно извикване превръща суровите данни за продукта в нещо, което можеш да покажеш на потребителя: резюме от две изречения, добри страни и предупреждения, изчислени от хранителните данни с публикувани прагове, декларираните алергени, съвместимост с диети, която казва откъде идва всеки отговор, и нивото на обработка — на шест езика, стриктно основано на данните от етикета на продукта.

200 OK
POST /v1/analyze/product
curl -X POST -H "X-API-Key: food_•••" \
  -H "Content-Type: application/json" \
  -d '{"barcode":"3017620422003","lang":"en"}' \
  "https://foodbase.dev/v1/analyze/product"

{
  "analysis": {
    "summary": "Nutella is a hazelnut and cocoa
      chocolate spread from Ferrero...",
    "highlights": ["Low salt (0.11 g per 100 g)"],
    "warnings": [
      "High in fat (30.9 g per 100 g)",
      "High in saturated fat (10.6 g per 100 g)",
      "High in sugars (56.3 g per 100 g)",
      "Contains palm oil"
    ],
    "allergens": {
      "contains": ["soy", "milk", "nuts"],
      "text": "Contains: soy, milk, nuts."
    },
    "diets_detail": {
      "vegan": { "value": "no", "basis": "allergen_tag" },
      "gluten_free": { "value": "yes", "basis": "label_claim" }
    },
    "processing_level": "ultra_processed",
    "processing_basis": "nova"
  },
  "cached": false
}

Предпочиташ да кликаш? Пробвай търсачката на продукти или фото площадката.

Какво получаваш

summary

Едно или две прости изречения за това какъв е продуктът и какъв е хранителният му характер.

highlights / warnings

Добри страни (условия за хранителни претенции на ЕС) и предупреждения (високи нива по UK FSA, кофеин, подсладители, алкохол, палмово масло). Една тема никога не е и в двете.

allergens

Алергените от EU-14, които етикетът декларира, разделени на contains и may contain, с локализирано изречение.

diets_detail

vegan / vegetarian / gluten_free / lactose_free с основание: претенция на етикета, деклариран алерген или съставки.

nutrient_levels

Мазнини, наситени мазнини, захари и сол като low, medium или high, на 100 g/ml или на порция.

processing_level

От NOVA групата на продукта; преценява се само по съставките, когато записът няма такава.

Налично във всеки план чрез месечни AI кредити — всяко извикване има фиксирана цена в кредити, а всеки план (включително Free) идва с кредитен лимит. Виж плановете →

Примерен код

Същата заявка на curl, JavaScript и Python. Замени YOUR_API_KEY с ключ от таблото си.


              curl "https://foodbase.dev/v1/analyze/product" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"barcode":"3017620422003","lang":"en"}'
            

Как работи

Адресирай продукта, избери езика

POST /v1/analyze/product приема JSON тяло с точно едно от food_id или barcode (8 до 14 цифри; GTIN варианти с водещи нули се разрешават) плюс незадължителен lang. Изпрати и двете или нито едно и получаваш 422 с текст „Provide exactly one of food_id or barcode“, а кредитът се възстановява. Празните низове се броят за пропуснати.

lang е en по подразбиране и приема още fr, es, de, it и bg. Той задава езика на текста, не присъдите: всяка присъда се изчислява от записа по фиксирани правила и се формулира от речник с фрази на всеки език, а преценките на модела се правят веднъж за продукт и се споделят от всички езици, така че продукт не може да е веган на английски и да не е на немски. Правилата четат хранителните вещества, етикетите, таговете за алергени и следи и NOVA групата на записа — същите данни, които връщат API за база данни с храни и API за хранителни стойности. От снимка API за разпознаване на храни от снимка първо ти дава food_id.

Четене на анализа, поле по поле

Примерът е живият отговор за Nutella (баркод 3017620422003, lang en). highlights са само добри страни: продуктът печели такава, когато отговаря на условието на хранителна претенция по Регламент (ЕО) 1924/2006 на ЕС, като ниско съдържание на сол (най-много 0,3 g на 100 g), източник на протеин (поне 12% от енергията) или високо съдържание на фибри (поне 6 g). warnings са само предупреждения: хранително вещество над прага „high“ за предната страна на опаковката по UK FSA (захари над 22,5 g на 100 g или над 11,25 g на 100 ml за напитки), голяма порция, която преминава границата на FSA на порция, или кофеин, подсладители, алкохол или палмово масло в съставките. Една тема никога не е и двете, а всяко число е собствената стойност на записа.

nutrient_levels дава същите присъди като данни: мазнини, наситени мазнини, захари и сол, всяка low, medium или high, с basis per_100 или per_portion. Кола от 330 ml с 10,6 g захари на 100 ml е medium на 100 ml, но high на кутия, затова предупреждението ѝ гласи „High in sugars (35 g per serving)“. allergens изброява декларираните алергени от EU-14 като contains и may_contain, със status „not_stated“, когато записът няма данни за алергени, което означава „провери опаковката“, а не „няма“.

diets_detail отговаря за vegan, vegetarian, gluten_free и lactose_free със value и basis. Първо решава претенция на етикета (веган, без глутен, без лактоза, сертификационни лога); после деклариран алерген или таг за месо изключва диета; иначе отговорът идва от списъка със съставки. Без глутен и без лактоза са „yes“ само с претенция на етикета: списък със съставки без източник на глутен дава „no_known_source“, защото несертифициран продукт все пак може да е замърсен. diets пази по-старата форма yes/no/unknown, като no_known_source се отчита като unknown.

processing_level е NOVA групата като етикет — unprocessed (1), culinary_ingredient (2: масла, масло, захар), processed (3), ultra_processed (4) — от NOVA групата на записа (processing_basis „nova“); само когато записът няма такава, се преценява по съставките („model“). per_serving се изчислява от размера на порцията в записа или е null, когато няма такъв. disclaimer е фиксиран низ; показвай го, защото текстът е генериран и описва записа в каталога, а не опаковката в ръцете на потребителя.

Кредити, кеширане и възстановявания

Всяко извикване струва 4 AI кредита от месечен лимит, споделен между всички ключове на акаунта (20 Free, 500 Starter, 1 300 Pro, 3 000 Enterprise; нулира се на първо число от месеца по UTC), а после от еднократни кредити за презареждане, когато лимитът не може да покрие извикване. Удържа се преди извода и всеки отговор носи X-Credits-Limit, X-Credits-Remaining (месечни плюс презареждане), X-Credits-Topup-Remaining и X-Credits-Reset.

Анализите се кешират по продукт, език и версия на анализа, свързани с updated_at на записа, така че повторно внесен или поправен продукт се анализира наново. source_updated_at в отговора назовава версията на данните, от която е направен; updated_at на записа за храната ти казва дали още е актуален. Попадение връща cached: true и пак се таксува с 4 кредита: няма възстановявания за попадения в кеша при крайните точки за анализ. Кеширай отговора сам, с ключ food_id и lang, ако показваш често един и същ продукт.

Възстановявания има само когато нищо не е произведено: 404, 422, 502 (съобщението завършва с „You were not charged.“) и 503. 401 или 429 никога не засягат кредитите.

Собствените ти данни за продукт: /analyze/custom

POST /v1/analyze/custom връща същия обект analysis за продукт, който описваш сам: артикул с търговска марка на веригата, нов продукт, етикет, който току-що си извлякъл. Тялото носи name (2 до 150 символа) плюс незадължителни brand, category, quantity, ingredients (до 3000 символа), обект nutrients със стойности на 100 g и lang. Няма полета за свободен въпрос или профил, нито претенции на етикета или тагове за алергени, така че диетите идват от съставките, а без глутен или без лактоза е най-много no_known_source.

Само name е 422: изпрати ingredients, поне една стойност за хранително вещество или и двете, защото моделът не може да измисля хранителни факти. nutrients е стриктен, с деветнайсет ключа, наименувани като колоните на каталога (energy_kcal, sugars_g, sodium_mg, calcium_mg и така нататък); непознат ключ е 422, а стойности извън обхвата се отхвърлят, а не се орязват.

Отговорът има input_hash вместо food_id — SHA-256 на каноничния вход, така че идентични данни и lang са попадение в кеша, таксувано като всяко друго. Незадължителният barcode не се анализира; той само отбелязва продукта като такъв, който искаш в каталога.

Добавяне на език: /translate/product

POST /v1/translate/product приема food_id или barcode и задължителен lang, превежда името и текста на съставките на продукта и записва резултата в каталога като наслагване, което оцелява при повторен внос и е видимо за всеки, който вика, като ново вписване {lang, text} в масивите name и ingredients на записа и чрез name_localized в търсенето. Данни от етикета на този език никога не се презаписват.

cached: true тук означава, че езикът вече е съществувал и 4-те ти кредита се възстановяват. force: true прегенерира превод, който смяташ за лош, но само текст от по-ранно AI изпълнение; ако текстът на езика е от етикета или ръчна поправка, получаваш 422 с възстановени кредити. Нискоуверен или небезопасен изход никога не се записва: извикването връща 502 и не си таксуван.

Поправяне на счупен текст от етикет: /correct/product

Текстът на етикета на собствения език на продукта понякога е счупен в източника: OCR грешки, липсващи интервали след запетаи, списъци с ГЛАВНИ БУКВИ, счупени символи като „crème“ вместо „crème“ или пасаж, повторен два пъти. POST /v1/correct/product го поправя за всички, за 4 кредита. Поправката може да променя само формата: кодът проверява, че нито една съставка, число, процент или E-номер не е добавена или премахната, че запетаите и скобите са останали на местата си и че всеки алерген и подчертаването му са оцелели. Поправка, която не мине проверката, не се записва и не се таксува.

Когато съдържанието е грешно, POST /v1/correct/product/photo приема снимка на етикета и използва прочетения от нея списък със съставки като доказателство, за 4 кредита. Четенето на снимката е скъпата част, така че снимка, която е прочетена, но не може да се използва (не се вижда списък със съставки, баркодът не се чете изцяло, друг продукт или четене, твърде несигурно за доверие), отговаря 422 и се таксува като /vision/label. Всяка поправка пази предишния текст за връщане, прилага се наново след повторен внос само докато изходният източник още доставя текста, който е бил поправен, и кара AI преводите на стария текст да се прегенерират при следващата им заявка. Анализът на продукта също се прегенерира, защото записът се е променил.

Какво можеш да изградиш

Екрани с детайли за продукт

Покажи на купувачите незабавна, четлива присъда до суровите числа.

Диетични филтри, които се обясняват сами

Знаци за веган или без глутен, които казват дали ги подкрепя претенция на етикета, или списъкът със съставки.

Здравни и коуч приложения

Превърни сканиранията в текст, готов за насоки, без да изграждаш собствен LLM конвейер.

Лимити по план

Free 20 AI кредита/месец, споделени между ключовете (5 анализа по 4 кредита); 1 AI заявка/с на ключ
Starter 500 AI кредита/месец; 1 AI заявка/с на ключ
Pro 1 300 AI кредита/месец; 2 AI заявки/с на ключ
Enterprise 3 000 AI кредита/месец; 5 AI заявки/с на ключ

Всеки отговор съдържа хедъри X-RateLimit-* с оставащия бюджет; всеки 429 съдържа Retry-After . Сравни плановете →

Грешки и как да ги обработиш

402 — Месечните AI кредити и кредитите от презареждане са изразходвани; X-Credits-Remaining е 0, съобщението назовава датата на нулиране, а тялото има top_up_url.

Спри AI извикванията до X-Credits-Reset или надстрой. Крайните точки за данни продължават да работят.

404 — Нито един продукт не съвпада с food_id или barcode. Възстановено.

Разреши отново чрез търсене или баркод; id-тата са стабилни, така че 404 не е временна. Извън каталога ползвай /analyze/custom.

422 — И двете или нито едно от food_id и barcode; custom name без съставки или хранителни вещества; грешен ключ или стойност на хранително вещество; force върху текст, който не е генериран от AI. Възстановено, освен /correct/product/photo, чиято снимка е прочетена, но не може да се използва, което се таксува.

Прочети details[].field и details[].message, поправи заявката, не повтаряй непроменена.

429 — Лимитът на AI на ключ (1/с Free и Starter, 2/с Pro, 5/с Enterprise) или таванът на акаунта от три пъти повече. Не се взема кредит.

Изчакай секундата от Retry-After и сериализирай AI извикванията на ключ.

502 — Извикването към модела се провали или превод падна под прага на увереност. Съобщението завършва с „You were not charged.“

Опитай отново след кратка пауза; по-късен успех се кешира нормално.

503 — AI не е включен или хранилището за кредити или лимити е недостъпно. Възстановено.

Опитай отново с backoff и междувременно покажи суровия запис от API за база данни с храни.

В сравнение с други API

Универсално LLM API ще резюмира продукт, ако му поставиш етикета, но тогава притежаваш промпта, правилата за основаване на данните, схемата на изхода, кеширането и съгласуваността между езиците. FoodBase прави това веднъж за продукт: присъдите се изчисляват от записа по публикувани прагове (хранителни претенции на ЕС, светофар на UK FSA), моделът пише само резюмето и преценките по съставките, всичко се валидира по фиксирана схема и се кешира по продукт и език, така че присъда не може да се различава между езиците. Компромисът е, че е толкова добро, колкото е записът: липсващи съставки означават неизвестни диети и нищо не се оценява, за да се запълни празнината — макар че счупен текст от етикет може да се поправи с /correct/product. Ако ти трябват числа, а не проза, API за хранителни стойности е по-евтиното извикване.

Виж пълното сравнение на API за хранителни данни →

Често задавани въпроси

Таксуван ли съм, когато cached е true? +

При /analyze/product и /analyze/custom — да: попадение в кеша струва същите 4 кредита като свеж анализ, без възстановяване. При /translate/product — не: cached: true означава, че езикът вече е съществувал и 4-те ти кредита се възстановяват.

Какво означават „unknown“ и „no_known_source“ в diets? +

unknown: записът няма нито претенция на етикета, нито таг за алерген, нито списък със съставки, който да решава въпроса — твърдение за записа, не мек „не“. no_known_source (само без глутен и без лактоза): списъкът със съставки не назовава източник, но етикетът не прави претенция, така че продуктът не е сертифициран. Хора с цьолиакия или непоносимост към лактоза трябва да смятат за безопасно само „yes“ с basis label_claim.

Мога ли да задам личен въпрос, например дали продуктът е подходящ за диета с ниско съдържание на натрий? +

Не през тези крайни точки: анализът има фиксирана форма, а /analyze/custom приема данни за продукт, не въпроси. Чети sodium_mg или salt_g от API за хранителни стойности и приложи собствен праг, вместо да парсваш текста на warnings.

Откъде идват добрите страни и предупрежденията? +

От фиксирани правила, не от модела: добрите страни ползват условията на хранителните претенции на ЕС (Регламент 1924/2006), предупрежденията — високите прагове на UK FSA за предната страна на опаковката, включително границите на порция за порции над 100 g или 150 ml. Така един и същ продукт получава едни и същи точки всеки път и на всеки език, а nutrient_levels ги връща като данни, по които можеш да филтрираш.

Какво става с кеширания анализ, когато записът на продукта се промени? +

Записът в кеша е свързан с updated_at на записа, така че след повторен внос или поправка следващото извикване генерира нов анализ от новите данни и таксува 4 кредита. Дотогава се сервира кешираният отговор.

Разгледай още endpoint-и

Започни да създаваш с API за AI анализ на храни

Безплатно за начало. Без кредитна карта.

Вземи API ключ Към таблото