Как устроен API КБЖУ
Адреса, параметры, ответ, лимиты и ошибки на одной странице. Что умеет API и сколько стоит, коротко рассказано на странице API для разработчиков
- Адрес
https://perek.us/api/v1/foods - Ключв заголовке
X-Api-Key - ОтветJSON, числа на 100 г, а у напитков на 100 мл
Адреса
-
GET
Поиск По названию, бренду, сети или штрихкоду. Понимает названия блюд целиком, как их пишут люди и нейросети: «Плов с курицей и овощами», «Авокадо (половина)». Название с упаковки длиннее 80 знаков можно прислать целиком, поиск возьмёт его начало./search?q=limitзадаёт число ответов от 1 до 20 (по умолчанию 10), аoffsetлистает дальше -
GET
Подсказки при наборе Для строки поиска, которая подсказывает по буквам: на «моро» предложит мороженое, а не смородину, и назовёт подходящие бренды в/suggest?q=brands. Отдаёт толькоidи названия, поэтому лимит разных продуктов не тратит. Цифры придут в карточке того, что выбрал человек -
GET
Карточка продукта Всё о продукте по/{id}idиз поиска: порции, штрихкоды и источник цифр. С Premium ещё состав и аллергены с упаковки, клетчатка, сахар, соль, витамины и минералы. На бесплатном тарифе полеpremium_onlyназовёт, что из этого у продукта есть -
GET
Несколько карточек сразу До 20?ids=idчерез запятую, например весь дневник за день. Каких нет, придут списком вmissing -
GET
КБЖУ по штрихкоду Коды EAN-13 и EAN-8. Если цифр по коду нет, API ответит 404, а если сам товар нам известен, назовёт его в/barcode/{ean}product -
POST
Разбор еды словами и по фото JSON/parse{"text": "200 г гречки и 2 яйца"}, фото тарелки вimage(base64) или оба сразу. В ответе продукты, их вес и КБЖУ каждого вitemsи сумма вtotal. Обычно ответ приходит сразу. Если разбор идёт дольше 25 секунд, API ответит 202 сid, а готовый результат отдастGET /parse/{id}. Бесплатно 50 разборов в месяц, с Premium 50 в сутки -
POST
КБЖУ с фото этикетки Фото таблицы с упаковки в/labelimage(base64), название товара по желанию вtext. В ответе калории, БЖУ, клетчатка, сахар и соль на 100 г или 100 мл, название, бренд, штрихкод и вес нетто, если они видны. Цифры приходят, только если таблицу подтвердило второе, независимое чтение снимка. Если таблица не читается, придёт ошибкаlabel_unreadable, и фото не спишется. Бесплатно 3 фото в месяц, с Premium 150, с Diamond 1 000
Параметры поиска
marketruилиkzоставит товары одной страныtypefoodоставит обычные продукты,brandedтовары брендов,chainблюда сетей. Можно несколько через запятуюbrandТолько этот бренд или сеть, поbrand.idиз ответа:?q=бургер&brand=burger-kingfullfull=trueвернёт в поиске карточки целиком, и второй запрос за составом не понадобится. На бесплатном тарифе карточка короче, поэтому тамfull=trueсчитается как обычный поиск
Ответ
curl -H "X-Api-Key: ваш_ключ" \ "https://perek.us/api/v1/foods/search?q=гречка&limit=5" # карточка продукта и поиск по штрихкоду curl -H "X-Api-Key: ваш_ключ" "https://perek.us/api/v1/foods/burger-king/vopper" curl -H "X-Api-Key: ваш_ключ" "https://perek.us/api/v1/foods/barcode/4606068171360"
import requests r = requests.get( "https://perek.us/api/v1/foods/search", params={"q": "гречка", "limit": 5}, headers={"X-Api-Key": "ваш_ключ"}, timeout=10, ) for food in r.json()["foods"]: print(food["name"], food["per100"]["kcal"], "ккал")
// Node.js 18 и новее: ключ живёт на сервере const url = new URL("https://perek.us/api/v1/foods/search"); url.searchParams.set("q", "гречка"); url.searchParams.set("limit", "5"); const res = await fetch(url, { headers: { "X-Api-Key": process.env.PEREK_API_KEY }, }); const { foods } = await res.json(); for (const food of foods) { console.log(food.name, food.per100.kcal, "ккал"); }
{
"query": "воппер",
"similar": false,
"offset": 0,
"more": true,
"foods": [{
"id": "burger-king/vopper",
"name": "Воппер",
"type": "chain",
"brand": {"id": "burger-king", "name": "Бургер Кинг", "kind": "chain"},
"per100": {"kcal": 262.77, "protein": 9.85, "fat": 16.06, "carbs": 19.34},
"servings": [{"label": "Порция", "grams": 274.0}],
"unit": "г",
"market": "ru",
"url": "https://perek.us/food/burger-king/vopper",
"license": null
}]
}
idНе меняется, его можно хранить у себя. Даже переименованный продукт найдётся по старомуidper100Калории и БЖУ на 100 г. Если вunitстоит «мл», то на 100 млservingsПорции и их вес в граммах, если они известныsimilarСтоитtrue, когда точного совпадения нет и API нашёл похожее: на «Вареники с капустой» ответит другими вареникамиmoreСтоитtrue, когда ответов больше: следующие отдастoffseturlСтраница продукта на perek.us, на неё ведёт ссылка «Данные: perek.us»licenseЛицензия открытой базы, если цифры взяты оттуда
Карточка целиком
Её отдают /{id}, ?ids=, штрихкод и поиск с full=true. Сверх полей из поиска в ней есть:
aliases- Другие названия продукта
barcodes- Штрихкоды, по которым продукт находится
product- Производитель, страна и срок годности, а с Premium ещё состав и аллергены с упаковки
per100- У части продуктов, кроме КБЖУ, клетчатка, сахар, насыщенные жиры и соль. Это поля Premium
micronutrients- Витамины и минералы, если они известны. Тоже Premium
sources- Откуда взяты цифры: название источника и ссылка
checked,verified- Когда цифры сверили с источником и когда мы проверили их сами
premium_only- На бесплатном тарифе список того, что из скрытого у продукта есть
Лимиты
Бесплатно
Premium
Diamond
Запросов в сутки
500
10 000
80 000
Запросов в минуту
20
180
1 440
Разных продуктов в поиске за сутки
150
5 000
40 000
Карточек и штрихкодов за сутки
50
1 500
12 000
Разборов еды
50 в месяц
50 в сутки
200 в сутки
Фото этикеток в месяц
3
150
1 000
Ключей на аккаунт
31010
- Сутки по UTC
- Счётчики обнуляются в 00:00 UTC, это 03:00 по Москве
- Лимиты на аккаунт
- Общие для всех ключей аккаунта, поэтому лишние ключи лимит не прибавляют
- Повторы не считаются
- Продукт, который уже приходил вам сегодня, не тратит лимит разных продуктов. Приложению, где люди едят одно и то же, его хватит с запасом
- Поиск и карточки отдельно
- Выдача поиска тратит свой лимит. Карточка продукта, штрихкод и поиск с
full=trueтратят лимит карточек, кроме бесплатного тарифа, гдеfull=trueсчитается обычным поиском. Если продукт уже пришёл вам сегодня в поиске, его карточка лимит не тратит - Потолок адреса
- С одного IP можно сделать 2 000 запросов в сутки, а с Premium 20 000. Если запросы похожи на выкачивание справочника, лимиты аккаунта урезаются на сутки
- Когда лимит кончился
- Придёт ответ
429. ЗаголовокRetry-Afterскажет, через сколько секунд повторить, а тело назовёт тариф, где лимит выше, и его цену
Заголовки ответа
X-RateLimit-Remaining- Сколько запросов осталось в эту минуту
X-RateLimit-Remaining-Day- Сколько запросов осталось на сутки
X-Search-Foods-Remaining-Day- Сколько ещё разных продуктов сегодня отдаст поиск
X-Foods-Remaining-Day- Сколько ещё карточек разных продуктов на сутки
X-Api-Plan- Тариф аккаунта:
free,premiumилиdiamond Retry-After- У ответа
429: через сколько секунд повторить
Ошибки
Тело любой ошибки: {"error": {"code": "...", "message": "..."}}. Текст в message по-русски, его можно показать человеку
- 400Неверный запрос
bad_querybad_limitbad_offsetbad_marketbad_typebad_brandbad_idsbad_barcodebad_bodybad_textbad_imageempty- 401Нет ключа
unauthorized: ключ не передан, неверный или отозван- 403Не входит в тариф
label_unavailable: чтение этикеток доступно с Premium- 404Не найдено
not_found: такого продукта нет. Если товар по штрихкоду известен без цифр, его название придёт вproduct- 413Большое фото
image_too_large: снимок больше 8 МБ- 422Не разобрать
label_unreadable,failed: повтор того же фото или текста не поможет, а фото этикетки не спишется- 429Лимит
rate_limited,parse_limit,label_limit. Повторите позже, срок вRetry-After- 503Временно
disabled,parse_busy,label_busy: повторите чуть позже
Условия
- Ссылка на нас
- На бесплатном тарифе рядом с цифрами из API покажите ссылку «Данные: perek.us» на страницу продукта из поля
url. С Premium ссылка по желанию - Коммерческий проект
- Бесплатный тариф для некоммерческих проектов. Если приложение берёт оплату, показывает рекламу или работает на бизнес, подключите Premium. Кто выпустил первый ключ до 21 октября 2026 года, остаётся на прежних условиях
- Ключ только на сервере
- Из мобильного приложения или кода страницы его достанут за минуту, и вашими лимитами начнут пользоваться чужие
- Без выкачивания
- Справочник нельзя собирать целиком, раздавать или продавать как свою базу. Если ключ используют так, мы его отзываем
- Открытые базы
- Если поле
licenseзаполнено, позицию можно распространять на условиях этой лицензии: ODbL у Open Food Facts, CC BY 4.0 у финской Fineli и научных статей, NLOD 2.0 у норвежской Matvaretabellen - Источник у каждой цифры
- Откуда взяты цифры и когда их сверили, показывают поля
sources,checkedиverified. Цифры средние, как на любой упаковке - Вопрос или поправка
- Напишите на ekinin.k@skybots.ru
Для ИИ-агентов
Ключ бесплатный
Выдаётся сразу после входа, как в дневник питания